I have a wsdl from ERP cloud. To consume it in Java, I compiled it using wsimport and extracted all the java files.
Now I'm trying to use these java files in order to communicate to the server data through wsdl. The wsdl requires authentication.
Problem
Whenever I try to run my custom code to connect to wsdl, for authentication it works with simple setting of username and password in Binding context.
private void attachAuthentication(Object className) {
BindingProvider prov = (BindingProvider) className;
prov.getRequestContext().put(BindingProvider.USERNAME_PROPERTY, "xxx");
prov.getRequestContext().put(BindingProvider.PASSWORD_PROPERTY, "xxx");
}
But whenever I deploy my code on a weblogic GPI instance, it gives me following error.
com.sun.xml.ws.fault.ServerSOAPFaultException: Client received SOAP Fault from server: The request was invalid or malformed Please see the server log to find more detail regarding exact cause of the failure.
at com.sun.xml.ws.fault.SOAP12Fault.getProtocolException(SOAP12Fault.java:229)
at com.sun.xml.ws.fault.SOAPFaultBuilder.createException(SOAPFaultBuilder.java:139)
at com.sun.xml.ws.client.sei.StubHandler.readResponse(StubHandler.java:253)
at com.sun.xml.ws.db.DatabindingImpl.deserializeResponse(DatabindingImpl.java:203)
at com.sun.xml.ws.db.DatabindingImpl.deserializeResponse(DatabindingImpl.java:290)
at com.sun.xml.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:119)
I tried attaching a Soap handler to my SEI. Here's what I've done.
InitializeErp.java
HeaderHandlerResolver handlerResolver = new HeaderHandlerResolver();
InvoiceInterfaceService_Service interfaceInvoice = new InvoiceInterfaceService_Service();
interfaceInvoice.setHandlerResolver(handlerResolver);
invoiceInterfaceServiceSoapHttpPort = interfaceInvoice.getInvoiceInterfaceServiceSoapHttpPort();
HeaderHandlerResolver.java
public class HeaderHandlerResolver implements HandlerResolver {
#Override
public List<Handler> getHandlerChain(PortInfo portInfo) {
List<Handler> handlerChain = new ArrayList<Handler>();
HandlerHeader hh = new HandlerHeader();
handlerChain.add(hh);
return handlerChain;
}
}
HeaderHandler.java
public class HandlerHeader implements SOAPHandler<SOAPMessageContext> {
#Override
public Set<QName> getHeaders() {
return Collections.emptySet();
}
#Override
public boolean handleMessage(SOAPMessageContext context) {
final Boolean outInd = (Boolean) context.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
if (outInd) {
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.mmm'Z'");
Date creationDate = new Date();
Date expirationDate = new Date(creationDate.getTime() + TimeUnit.HOURS.toMillis(1));
try {
SOAPMessage message = context.getMessage();
SOAPEnvelope env = message.getSOAPPart().getEnvelope();
env.addNamespaceDeclaration("sch", "http://xmlns.oracle.com/scheduler");
env.addNamespaceDeclaration("typ", "http://xmlns.oracle.com/scheduler/types");
SOAPHeader header = env.getHeader();
SOAPBody body = env.getBody();
env.removeNamespaceDeclaration("SOAP-ENV");
env.setPrefix("soapenv");
header.setPrefix("soapenv");
body.setPrefix("soapenv");
QName security = new QName("http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd", "Security", "wsse");
// Constructing Header
SOAPElement securityElement = header.addChildElement(security);
securityElement.addNamespaceDeclaration("wsu", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd");
securityElement.setAttribute("soapenv:mustUnderstand", "1");
QName usernameToken = new QName("UsernameToken", "wsse");
SOAPElement usernameTokenElement = securityElement.addChildElement("UsernameToken", "wsse");
usernameTokenElement.setAttribute("wsu:Id", "UsernameToken-97B1FF404874F4997215144527824364");
QName username = new QName("Username", "wsse");
SOAPElement usernameElement = usernameTokenElement.addChildElement("Username", "wsse");
usernameElement.addTextNode("xxx");
QName passwrod = new QName("Password", "wsse");
SOAPElement passwordElement = usernameTokenElement.addChildElement("Password", "wsse");
passwordElement.setAttribute("Type", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText");
passwordElement.addTextNode("xxx");
QName nonce = new QName("Nonce", "wsse");
SOAPElement nonceElement = usernameTokenElement.addChildElement("Nonce", "wsse");
nonceElement.setAttribute("EncodingType", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary");
nonceElement.addTextNode("Ox0BI3sh1pPSe2S7NsUzeg==");
QName created = new QName("Created", "wsu");
SOAPElement createdElement = usernameTokenElement.addChildElement("Created", "wsu");
createdElement.addTextNode(format.format(creationDate));
QName timestamp = new QName("Timestamp", "wsu");
SOAPElement timestampElement = securityElement.addChildElement("Timestamp", "wsu");
timestampElement.setAttribute("wsu:Id", "TS-4");
QName createdTimestamp = new QName("Created", "wsu");
SOAPElement createdTimestampElement = timestampElement.addChildElement("Created", "wsu");
createdTimestampElement.addTextNode(format.format(creationDate));
QName expiresTimestamp = new QName("Expires", "wsu");
SOAPElement expiresTimestampElement = timestampElement.addChildElement("Expires", "wsu");
expiresTimestampElement.addTextNode(format.format(expirationDate));
// Print out the outbound SOAP message to System.out
System.out.println("setting attributes...");
message.writeTo(System.out);
System.out.println("");
System.out.println("message printed..");
} catch (Exception e) {
e.printStackTrace();
}
}
return true;
}
#Override
public boolean handleFault(SOAPMessageContext context) {
try {
SOAPMessage message = context.getMessage();
ByteArrayOutputStream out = new ByteArrayOutputStream();
message.writeTo(out);
String strMsg = new String(out.toByteArray());
RequestFilter.getSession().setAttribute("soap fault", "Soap ->" + strMsg);
} catch (SOAPException | IOException ex) {
RequestFilter.getSession().setAttribute("mailContent", ex.toString());
}
return true;
}
#Override
public void close(MessageContext context) {
}
}
This is what my Soap HEader looks like.
On running it on server. This is what I get in my SoapFault
Soap -> ns1:Senderns2:InvalidRequestThe request was invalid or malformedweblogic.wsee.security.wst.faults.InvalidRequestException: Server Authentication Required at weblogic.wsee.security.wst.framework.TrustSoapClient.invoke(TrustSoapClient.java:157) at weblogic.wsee.security.wst.framework.TrustSoapClient.requestTrustToken(TrustSoapClient.java:110) at weblogic.wsee.security.saml.SAMLTrustCredentialProvider.createCredential(SAMLTrustCredentialProvider.java:432) at
I've many ways to modify the Soap header, Removed security, just passed username password, Added both handler as well as credentials in BindingContext, But nothing seems to work on server.
With the header attached, I get the following error on local
I'm out of ways now. Can anyone please suggest me any approach or point out what am I missing. What should I try now. Any help is appreciated. All suggestions are welcome.
Related
I'm trying to access/read headers from WebServiceContext on the web service method after execution by the SOAP handler, but I get an exception:
java.lang.RuntimeException: DOMStreamReader: getElementText() not implemented
at com.sun.xml.ws.streaming.DOMStreamReader.getElementText(DOMStreamReader.java:401) ~[jaxws-rt.jar:2.3.2]
If I don't execute the SOAP handler, I can read header values during web service execution.
Web Services Class
#WebService(targetNamespace = "http://example.com/LOGIN", serviceName = "UserLogin")
#HandlerChain(file = "../handlers.xml")
public class LoginImpl {
#Resource
WebServiceContext context;
(...)
#WebMethod(operationName = "Suspend", action = "http://example.com/LOGIN/Suspend")
#WebResult(name = "SuspendResult", targetNamespace = "http://example.com/LOGIN")
#RequestWrapper(targetNamespace = "http://example.com/LOGIN")
#ResponseWrapper(targetNamespace = "http://example.com/LOGIN")
public WSResult suspend(
#WebParam(name = "user", targetNamespace = "http://example.com/LOGIN") String userid) {
HeaderList hl = (HeaderList) context.getMessageContext().get(JAXWSProperties.INBOUND_HEADER_LIST_PROPERTY);
if (hl != null) {
Header cred = hl.get(new QName("http://example.com/definitions","Credentials"), true);
if (cred != null) {
try {
WSCredentials result = new WSCredentials();
result.roles = new HashSet<String>();
XMLStreamReader reader = cred.readHeader();
int eventType = reader.getEventType();
do {
if (eventType == XMLStreamConstants.START_ELEMENT) {
if ("Username".equals(reader.getLocalName())) {
String text = reader.getElementText(); // -> java.lang.RuntimeException: DOMStreamReader
result.username = text;
}
(...)
}
(...)
SOAP Handler
public class ValidateAuthorization implements SOAPHandler<SOAPMessageContext> {
public ValidateAuthorization() {
}
#Override
public boolean handleMessage(SOAPMessageContext context) {
if (Boolean.FALSE.equals(context.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY))) {
String username = null;
try {
SOAPMessage soapMessage = context.getMessage();
SOAPPart soapPart = soapMessage.getSOAPPart();
SOAPEnvelope soapEnvelope = soapPart.getEnvelope();
SOAPHeader header = soapEnvelope.getHeader();
WSCredentials result = new WSCredentials();
result.roles = new HashSet<String>();
Iterator<?> headerElements = header.examineAllHeaderElements();
while (headerElements.hasNext()) {
SOAPHeaderElement headerElement = (SOAPHeaderElement) headerElements.next();
if (headerElement.getElementName().getLocalName().equals("Credentials")) {
SOAPHeaderElement securityElement = headerElement;
Iterator<?> it2 = securityElement.getChildElements();
while (it2.hasNext()) {
Node soapNode = (Node) it2.next();
if (soapNode instanceof SOAPElement) {
SOAPElement element = (SOAPElement) soapNode;
QName elementQname = element.getElementQName();
if(elementQname.getLocalPart().equals("Username")) {
username = element.getValue();
result.username = element.getValue();
}
}
}
}
}
soapMessage.writeTo(System.out);
log.debug("USERNAME " + username); // OK!
} catch (Exception e) {
log.error("Error reading SOAP message context: " + e, e);
e.printStackTrace();
}
}
return true;
}
(...)
}
I would like to read SOAPEnv headers on SOAP handlers and on web service execution. I suspect that the first iteration over the list of headers changes the pointer to the XLM of the web service, which does not allow the correct reading in the second iteration.
To observe this behavior, just access the headers in the SOAP Handler, even without iterating over them. That is, it suffices that the SOAPHeader object be created in the
public class ValidateAuthorization implements SOAPHandler<SOAPMessageContext> method, so that I cannot read the headers when executing the web service.
SOAPMessage soapMessage = context.getMessage();
SOAPPart soapPart = soapMessage.getSOAPPart();
SOAPEnvelope soapEnvelope = soapPart.getEnvelope();
SOAPHeader header = soapEnvelope.getHeader();
If I don't access the SOAP Headers in the SOAP Handler, I can list the headers in the web service.
Could you help me, please? Many thanks.
I have create Java Classes from the DHL WSDL
https://cig.dhl.de/cig-wsdls/com/dpdhl/wsdl/geschaeftskundenversand-api/2.2/geschaeftskundenversand-api-2.2.wsdl.
Now i have all Classes, but no Authentifaction Class.
I try this
GKVAPIServicePortTypeProxy port2 = new GKVAPIServicePortTypeProxy();
port2.setEndpoint("https://cig.dhl.de/services/sandbox/soap");
CreateShipmentOrderRequest sh = new CreateShipmentOrderRequest();
//Setting up shipment;
.. and so on
CreateShipmentOrderResponse chr = port2.createShipmentOrder(sh);
But only what i get is, "(401)Authorization Required"
How can i set my Authentifiaction ?
Hi I h had fixed the 401 problem with adding of the ssl certificate from DHL to my application truststore.
But I have the problem that I missing to add the Authentification block to the request.
<soapenv:Header>
<cis:Authentification>
<cis:user>user</cis:user>
<cis:signature>password</cis:signature>
</cis:Authentification>
</soapenv:Header>
My try to adding this block resulting in a 'org.quartz.jobexecutionexception: de.vps.icms.exceptions.icmsscriptingexception: java.lang.noclassdeffounderror: org/apache/axis2/saaj/soapenvelopeimpl'exception.
Some idea what I did wrong?
Here the Code:
public class WSClient {
public WSClient() {
try {
GKVAPIServicePortType port = prepareService();
String b = BWIConstants.SYSPARAM_DHL_WS_URL;
CreateShipmentOrderRequest createShipmentOrderRequest = new CreateShipmentOrderRequest();
CreateShipmentOrderResponse createShipmentOrderResponse =
port.createShipmentOrder(createShipmentOrderRequest);
createShipmentOrderResponse.getStatus();
} catch (Exception e) {
e.printStackTrace();
}
}
private GKVAPIServicePortType prepareService() throws MalformedURLException {
// get Service stub
String pathToClassFolder = getClass().getResource("/").toString();
String fullwsdlFilePath = pathToClassFolder + "/" + "geschaeftskundenversand-api-2.2.wsdl";
URL wsdlLocation = new URL(fullwsdlFilePath);
GVAPI20De service = new GVAPI20De(wsdlLocation);
// get Service Port
GKVAPIServicePortType port = service.getPort(GKVAPIServicePortType.class);
// overwrite Endpoint
Map<String, Object> requestContext = ((BindingProvider) port).getRequestContext();
requestContext.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, "https://cig.dhl.de/services/sandbox/soap");
// overwrite BasicAuth Username and Password
// requestContext.put(BindingProvider.USERNAME_PROPERTY, cigUser);
// requestContext.put(BindingProvider.PASSWORD_PROPERTY, cigPass);
// Add authentication Handler
Binding binding = ((BindingProvider) port).getBinding();
List<Handler> handlerChain = binding.getHandlerChain();
handlerChain.add(
new AuthenticationHandler(BWIConstants.SYSPARAM_DHL_WS_USER, BWIConstants.SYSPARAM_DHL_WS_SIGNATURE));
binding.setHandlerChain(handlerChain);
return port;
}
}
public class AuthenticationHandler implements SOAPHandler<SOAPMessageContext> {
private String USER = "";
private String PASSWORD = "";
public AuthenticationHandler(final String user, final String password) {
USER = user;
PASSWORD = password;
}
/**
* {#inheritDoc}
*/
public void close(final MessageContext context) {
// nothing to do
}
/**
* {#inheritDoc}
*/
public Set<QName> getHeaders() {
// nothing to do
return null;
}
/**
* {#inheritDoc}
*/
public boolean handleFault(final SOAPMessageContext context) {
// nothing to do
return true;
}
/**
* {#inheritDoc}
*/
public boolean handleMessage(final SOAPMessageContext context) {
if (isOutboundMessage(context)) {
try {
// get/create the map of HTTP headers
Map<Object, Object> headers = (Map<Object, Object>) context.get(MessageContext.HTTP_REQUEST_HEADERS);
if (headers == null) {
headers = new HashMap<Object, Object>();
context.put(MessageContext.HTTP_REQUEST_HEADERS, headers);
}
// add custom HTTP header (deactivate HTTP keepAlive)
String headerName = "Connection";
List<String> headerValues = new ArrayList<String>();
headerValues.add("Close");
headers.put(headerName, headerValues);
SOAPMessage message = context.getMessage();
SOAPEnvelope envelope = message.getSOAPPart().getEnvelope();
SOAPHeader header;
if (envelope.getHeader() == null) {
header = envelope.addHeader();
} else {
header = envelope.getHeader();
}
// add the Authentification element
SOAPElement auth = header.addHeaderElement(
envelope.createName("Authentification", "cis", "http://dhl.de/webservice/cisbase"));
SOAPElement user =
auth.addChildElement(envelope.createName("user", "cis", "http://dhl.de/webservice/cisbase"));
user.setValue(USER);
SOAPElement signature =
auth.addChildElement(envelope.createName("signature", "cis", "http://dhl.de/webservice/cisbase"));
signature.setValue(PASSWORD);
SOAPElement type =
auth.addChildElement(envelope.createName("type", "cis", "http://dhl.de/webservice/cisbase"));
type.setValue("0");
// save changes
message.saveChanges();
} catch (SOAPException ex) {
throw new RuntimeException("Failed to add SOAP headers for authentication.", ex);
}
}
return true;
}
private boolean isOutboundMessage(final MessageContext context) {
Boolean outboundProperty = (Boolean) context.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
return outboundProperty.booleanValue();
}
}
Using basic authentication, you would first Base64 encode your username:password - there's online sites that will do it but beware as likely not a good idea to do it if it refers to DHL in anyway, e.g. they could swipe your credentials.
You then get the Request Context of the port, create a map of the headers and add an Authorization header. Finally you add that back to the request context.
Example:
Note, I purposely generated bad base64 encoding so you would likely not be able to decode it and see it properly formatted with the "username:password"
GVAPI20De service1 = new GVAPI20De();
GKVAPIServicePortType port2 = service1.getGKVAPISOAP11Port0();
CreateShipmentOrderRequest sh = new CreateShipmentOrderRequest();
//Setting up shipment;
Map<String, Object> req_ctx = ((BindingProvider)port2).getRequestContext();
//you may not need this and can try commenting it out
req_ctx.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, "https://cig.dhl.de/cig-wsdls/com/dpdhl/wsdl/geschaeftskundenversand-api/2.2/geschaeftskundenversand-api-2.2.wsdl");
//optional timeout
req_ctx.put("javax.xml.ws.client.connectionTimeout", "60000");
Map<String, List<String>> headers = new HashMap<String, List<String>>();
headers.put("Authorization", Collections.singletonList("Basic c3gh567sd4689k11lg=="));
req_ctx.put(MessageContext.HTTP_REQUEST_HEADERS, headers);
CreateShipmentOrderResponse chr = port2.createShipmentOrder(sh)
I am trying to create a Soap client in java, where I have to Sign the Soap message using my private key.
I am getting response using SoapUI, with WS-Security configured.
I have imported the WSDL and generated classes using wsimport.
I created a SOAPHandler to sign the message like below. I am not sure If this is the correct way to sign the message.
#Override
private void handleMessage(SOAPMessageContext context) throws SOAPException, WSSecurityException {
try {
SOAPMessage soapMessage = context.getMessage();
SOAPPart soapPart = soapMessage.getSOAPPart();
soapMessage.getSOAPHeader();
WSSecHeader wsSecHeader = new WSSecHeader();
wsSecHeader.setMustUnderstand(true);
wsSecHeader.insertSecurityHeader(soapPart);
WSSecTimestamp wsSecTimeStamp = new WSSecTimestamp();
wsSecTimeStamp.prepare(soapPart);
wsSecTimeStamp.prependToHeader(wsSecHeader);
WSSConfig wssConfig = new WSSConfig();
WSSecSignature sign = new WSSecSignature(wssConfig);
sign.setKeyIdentifierType(WSConstants.BST_DIRECT_REFERENCE);
Properties cxfProps = new Properties();
cxfProps.setProperty("org.apache.ws.security.crypto.provider", "org.apache.ws.security.components.crypto.Merlin");
cxfProps.setProperty("org.apache.ws.security.crypto.merlin.keystore.type", "jks");
cxfProps.setProperty("org.apache.ws.security.crypto.merlin.keystore.alias", "example.com");
cxfProps.setProperty("org.apache.ws.security.crypto.merlin.keystore.password", "password");
cxfProps.setProperty("org.apache.ws.security.crypto.merlin.keystore.file", "keystore.jks");
Crypto crypto1 = CryptoFactory.getInstance(cxfProps);
sign.prepare(soapPart, crypto1, wsSecHeader);
String bstId = sign.getBSTTokenId();
sign.appendBSTElementToHeader(wsSecHeader);
sign.setDigestAlgo("http://www.w3.org/2001/04/xmlenc#sha256");
sign.setSignatureAlgorithm("http://www.w3.org/2001/04/xmldsig-more#rsa-sha256");
Vector<WSEncryptionPart> signParts = new Vector<WSEncryptionPart>();
signParts.add(new WSEncryptionPart(wsSecTimeStamp.getId()));
signParts.add(new WSEncryptionPart(WSConstants.ELEM_BODY,
WSConstants.URI_SOAP12_ENV, ""));
signParts.add(new WSEncryptionPart(bstId));
sign.addReferencesToSign(signParts, wsSecHeader);
List<Reference> referenceList = sign.addReferencesToSign(signParts,
wsSecHeader);
sign.computeSignature(referenceList, false, null);
} catch (Exception ex) {
Logger.getLogger(SecurityHandler.class.getName()).log(Level.SEVERE, null, ex);
}
}
I am getting a NullPointerException.
java.lang.NullPointerException
at sun.security.provider.JavaKeyStore$JKS.convertAlias(JavaKeyStore.java:57)
at sun.security.provider.JavaKeyStore.engineGetCertificateChain(JavaKeyStore.java:153)
at sun.security.provider.JavaKeyStore$JKS.engineGetCertificateChain(JavaKeyStore.java:55)
at java.security.KeyStore.getCertificateChain(KeyStore.java:1036)
at org.apache.ws.security.components.crypto.Merlin.getX509Certificates(Merlin.java:1277)
at org.apache.ws.security.components.crypto.Merlin.getX509Certificates(Merlin.java:600)
at org.apache.ws.security.message.WSSecSignature.getSigningCerts(WSSecSignature.java:793)
at org.apache.ws.security.message.WSSecSignature.prepare(WSSecSignature.java:169)
at app.SecurityHandler.handleOutboundMessage(SecurityHandler.java:187)
In order to select target private key from your keystore you have to add
sign.setUserInfo("key-alias", "key-password");
in your code.
I am new to SOAP , I want to call web service .
I have seen a tutorial for making soap request .
This is the Code
MessageFactory mf = null;
SOAPMessage sm = null;
SOAPEnvelope envelope = null;
MimeHeaders headers = null;
SOAPBody body = null;
SOAPElement requestData = null;
SOAPElement requestDoc = null;
CDATASection cdata = null;
SOAPConnectionFactory sfc = null;
SOAPConnection connection = null;
URL requestUrl = null;
SOAPMessage response = null;
OutputStream os = null;
String host = null;
int port = 80;
String path = null;
String api_key = null;
int socket_timeout = 0;
String service_type = null;
String baseXml = null;
try {
xmlChannelRequest = createChannelRequest(cmId, function, guId, password, estabId);
mf = MessageFactory.newInstance();
sm = mf.createMessage();
envelope = sm.getSOAPPart().getEnvelope();
envelope.addNamespaceDeclaration("soap", "http://schemas.xmlsoap.org/soap/envelope/");
envelope.setPrefix("soapenv");
envelope.setAttribute("xmlns:tem", "http://tempuri.org/");
headers = sm.getMimeHeaders();
headers.addHeader("SOAPAction", "http://tempuri.org/IPublicChannelManagerService/RequestData");
body = envelope.getBody();
body.setPrefix("soapenv");
requestData = body.addChildElement("RequestData");
requestData.setPrefix("tem");
requestDoc = requestData.addChildElement("requestDocument", "tem", "http://tempuri.org/");
cdata = requestDoc.getOwnerDocument().createCDATASection("<Request>\n"
+ " <Authentication CMId=\"6438\" Function=\"31\" Guid=\"5594FB83-F4D4-431F-B3C5-EA6D7ASDSBA795\" Password=\"y656g321TR\"/>\n"
+ " <Establishment Id=\"297867\"/>\n"
+ " </Request>");
requestDoc.appendChild(cdata);
System.out.println("---------------- SOAP Request ----------------------------");
sm.writeTo(System.out);
sfc = SOAPConnectionFactory.newInstance();
connection = sfc.createConnection();
requestUrl = new URL("http://pp.xxx.yyyy.co.uk/zzzz.svc?wsdl");
response = connection.call(sm, requestUrl);
This is working fine. My question is , is there any easy way , just like passing object to method and it creates , SOAP request .
ex : Just like JaxB , i will send a Bean , it will generate xml.
outputStream = new ByteArrayOutputStream();
marshaller = jaxbContext.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(beanObject, outputStream);
You should have the WSDL file before you make the request. Then just generate your specific classes using e.g. wsimport tool and then just call the JAX-WS webservice. You do not have to build the request by yourself in this way.
Have a look over this tutorial.
I have a simple SOAP webservice server like this:
public class receiver extends JAXMServlet implements ReqRespListener {
public SOAPMessage onMessage(SOAPMessage soapm) {
return soapm;
}
}
In the client I send a message to this server:
public class sender {
/** This is a sample web service operation */
SOAPConnectionFactory scfac = null;
SOAPConnection con =null;
MessageFactory fac = null;
SOAPMessage message = null;
SOAPMessage response = null;
#WebMethod(operationName = "sender")
public String sender(#WebParam(name = "a") String a)
{
try{
//Creat Connection
scfac = SOAPConnectionFactory.newInstance();
con = scfac.createConnection();
fac = MessageFactory.newInstance();
message = fac.createMessage();
SOAPPart soapPart = message.getSOAPPart();
SOAPEnvelope envelope = soapPart.getEnvelope();
SOAPHeader header = envelope.getHeader();
header.detachNode();
SOAPBody body = envelope.getBody();
body.addTextNode(a);
URL endpoint = new URL("http://localhost:8080/Target/receiver");
//log("Bat dau gui");
response = con.call(message, endpoint);
//log("Da nhan ve");
SOAPPart sp = response.getSOAPPart();
SOAPEnvelope ev = sp.getEnvelope();
SOAPBody bd = ev.getBody();
String result = bd.getValue();
return result;
}
catch (Exception e)
{
String fail = "Fail to send";
return fail;
}
}
}
I called the sender function in a jsp file and passed a String to it.
I had built it with Netbeans and Tomcat server but it just responds with a null message.
How can I fix the problem?
I had fixed the problem by 2 steps:
The SOAP server: In the web.xml file fix the servlet class from com.sun.xml.ws.transport.http.servlet.WSServlet to your own Java class (in my case it is receive.receiver)
Add saaj-impl-1.3.1 library to NetBeans (the library with method com.sun.xml.messaging)