I am writing SOAP client using WSDL. I have similar code in PHP, which works fine. However, I have some problems in Java. Here is my code snippet:
Where should I define the path to my local WSDL file?
Any idea is welcome.
try
{
SOAPConnectionFactory soapConnectionFactory = SOAPConnectionFactory.newInstance();
SOAPConnection soapConnection = soapConnectionFactory.createConnection();
SOAPMessage soapResponse = soapConnection.call(mySampleQuery(),
"https://www.webpagename.com");
// Process the SOAP Response
printSOAPResponse(soapResponse);
soapConnection.close();
}
catch (Exception e)
{
System.err.println("Error occurred while sending SOAP Request to Server");
e.printStackTrace();
}
private static SOAPMessage queryFlightsByAerodrome() throws Exception
{
MessageFactory messageFactory = MessageFactory.newInstance(SOAPConstants.SOAP_1_2_PROTOCOL);
SOAPMessage soapMessage = messageFactory.createMessage();
SOAPPart soapPart = soapMessage.getSOAPPart();
String serverURI = "localfolder/wsdlfilename.wsdl";
// SOAP Envelope
SOAPEnvelope envelope = soapPart.getEnvelope();
envelope.addNamespaceDeclaration("mydata", serverURI);
// SOAP Body
SOAPBody soapBody = envelope.getBody();
SOAPElement soapBodyElem = soapBody.addChildElement("mySampleRequest", "mydata");
SOAPElement soapBodyElem1 = soapBodyElem.addChildElement("userId");
soapBodyElem1.addTextNode("testuser");
//...here I create soapBodyElem1
MimeHeaders headers = soapMessage.getMimeHeaders();
headers.addHeader("SOAPAction", serverURI + "queryTestData");
System.out.println("Content description: "+soapMessage.getContentDescription());
soapMessage.saveChanges();
/* Print the request message */
System.out.print("Request SOAP Message:");
soapMessage.writeTo(System.out);
System.out.println();
return soapMessage;
}
After running this code I get the following error at line SOAPMessage soapResponse = soapConnection.call(mySampleQuery(),"https://www.webpagename.com"):
Nov 03, 2014 4:18:27 PM
com.sun.xml.internal.messaging.saaj.soap.MessageImpl
identifyContentType SEVERE: SAAJ0537: Invalid Content-Type. Could be
an error message instead of a SOAP message Error occurred while
sending SOAP Request to Server
com.sun.xml.internal.messaging.saaj.SOAPExceptionImpl:
com.sun.xml.internal.messaging.saaj.SOAPExceptionImpl: Invalid
Content-Type:text/html. Is this an error message instead of a SOAP
response? at
com.sun.xml.internal.messaging.saaj.client.p2p.HttpSOAPConnection.call(Unknown
Source) at com.aslogic.isagent.MyAgent.main(MyAgent.java:46)
Caused by: com.sun.xml.internal.messaging.saaj.SOAPExceptionImpl:
Invalid Content-Type:text/html. Is this an error message instead of a
SOAP response? at
com.sun.xml.internal.messaging.saaj.soap.MessageImpl.identifyContentType(Unknown
Source) at
com.sun.xml.internal.messaging.saaj.soap.MessageFactoryImpl.createMessage(Unknown
Source) at
com.sun.xml.internal.messaging.saaj.client.p2p.HttpSOAPConnection.post(Unknown
Source)
Invalid Content-Type. Could be an error message instead of a SOAP message
That's your first clue right there.
Invalid Content-Type:text/html. Is this an error message instead of a SOAP response
That's another clue. Putting it all together:
Your client is connecting to the service
The service is returning a non-SOAP response payload (it's returning HTML instead), hence the reason why SAAJ is choking on it.
Typically, a webservice will return HTML when it's responding with a standard JavaEE container-generated error page, as against the expected SOAP response. The question now is: What is the error response that's being returned? Talk to your service provider for feedback on what you're doing wrong. Also, look into logging everything that hits your client somehow
Related
Tracing XML request/responses with JAX-WS when error occurs
Related
I'm currently working on a custom SOAP call to a specific domain beyond my control. I know the SOAP call fails but I cannot seem to grab the returned (wrong)value.
Right now I'm using the code below:
Document document = convertStringToDocument(this.MeldingString);
// System.out.println(document);
SOAPConnectionFactory myFct = SOAPConnectionFactory.newInstance();
MessageFactory myMsgFct = MessageFactory.newInstance(SOAPConstants.SOAP_1_2_PROTOCOL);
SOAPMessage message = myMsgFct.createMessage();
SOAPConnection myCon = myFct.createConnection();
// Adding parts
SOAPPart mySPart = message.getSOAPPart();
SOAPEnvelope myEnvp = mySPart.getEnvelope();
// Escape the password for usage in header
String escpwd = StringEscapeUtils.escapeJava(this.Password);
// Header
MimeHeaders headers = message.getMimeHeaders();
headers.setHeader("Content-Type", "application/soap+xml;charset=UTF-8");
headers.setHeader("Authorization", this.Username + ":" + escpwd);
// Body
SOAPBody body = myEnvp.getBody();
body.addDocument(document);
// Sending
Core.getLogger("GetResultSOAPmsg").trace("Started");
URL endPt = new URL(
"URL-TO-MY-SERVICE");
System.setProperty("java.net.useSystemProxies", "true");
try {
SOAPMessage reply = myCon.call(message, endPt); "UTF-8");
}
catch(Exception e)
{
e.printStackTrace();
}
This yields the following error which is very common al throughout SO:
SEVERE: SAAJ0537: Invalid Content-Type. Could be an error message instead of a SOAP message
com.sun.xml.internal.messaging.saaj.SOAPExceptionImpl: com.sun.xml.internal.messaging.saaj.SOAPExceptionImpl: Invalid Content-Type:text/html. Is this an error message instead of a SOAP response?
Now I have read most of these topics already and they explain how this problem is usually solved (namespaces, escaping URL, etc.) but I cannot seem to figure out what is wrong in my case. This is a private service and the other side is unfortunately unable to assist me in this case. The error could be anything from wrong certificates to misspelling the URL.
Therefore I would like to actually SEE onscreen what the actual reply is that was received when making the call. This is going to help me (assuming it's something like a 503, 404 or other page). Regardless of what I do and where I set my breakpoints, there is no information on Reply. It makes somewhat sense since it was unable to create said object but the entire message seems to be discarded.
In what way will I be able to see what the actual reply was to my call before it is discarded?
I think there's a problem with your header
headers.setHeader("Content-Type", "application/soap+xml;charset=UTF-8");
try something like
headers.setHeader("Content-Type", "application/xml;charset=UTF-8");
or
headers.setHeader("Content-Type", "application/json;charset=UTF-8");
depending on the content type that the content type accepted by the service
I am having one function where we generate SOAP request.The request I am able to run in SOAP UI tool and its fetching.
I am creating SOAPMessage like this
MessageFactory messageFactory = MessageFactory.newInstance();
SOAPMessage soapMessage = messageFactory.createMessage();
MimeHeaders headers = soapMessage.getMimeHeaders();
headers.removeAllHeaders();
headers.addHeader("Content-Type", "text/xml");
SOAPPart soapPart = soapMessage.getSOAPPart();
When I call
SOAPMessage soapResponse = soapConnection.call(soapMessage, url);
get this error:
SEVERE: SAAJ0537: Invalid Content-Type. Could be an error message instead of a SOAP message
com.sun.xml.internal.messaging.saaj.SOAPExceptionImpl: com.sun.xml.internal.messaging.saaj.SOAPExceptionImpl: Invalid Content-Type:text/html. Is this an error message instead of a SOAP response?
could you help to sort it out?
whether that means connection unable to establish??
Most probably expected HTTP Content-Type header for SOAP messages is application/soap+xml (see XML SOAP).
The exception you get originates from SOAP service container saying that the value of Content-Type header is text/html. I think that SOAP UI set the correct request header value for you.
The header value sent by your code seem to be a default one. You should check what the expected Content-Type value is for you server and ho to set it with your framework/library.
I am trying to access SAOP API using SAAJ.
I have followed the same code that were present in other answers on creating a SOAP request body and
calling the SOAP API.
This particular service does not need any authentication (as mentioned in API doc) nor does it take any input parameters.
From WSDL: (copied only relevant content)
<xs:complexType name="getCustomerNames">
<xs:sequence/>
</xs:complexType>
...
<wsdl:operation name="getCustomerNames">
<wsdl:input message="tns:getCustomerNames" name="getCustomerNames"/>
<wsdl:output message="tns:getCustomerNamesResponse" name="getCustomerNamesResponse"/>
<wsdl:fault message="tns:SOAPException" name="SOAPException"/>
</wsdl:operation>
Below is the Java code that creates the soap body and calls the API
SOAPConnectionFactory scf = SOAPConnectionFactory.newInstance();
SOAPConnection connection = scf.createConnection();
SOAPFactory sf = SOAPFactory.newInstance();
String serverURI = "com.webservices.services.authentication";
MessageFactory mf = MessageFactory.newInstance(SOAPConstants.SOAP_1_2_PROTOCOL); // I tried without parameters as well
SOAPMessage message = mf.createMessage();
message.getSOAPHeader().detachNode();
SOAPPart soapPart = message.getSOAPPart();
SOAPEnvelope envelope = soapPart.getEnvelope();
envelope.addNamespaceDeclaration("auth", serverURI);
Name bodyName = sf.createName("getCustomerNames", "auth", serverURI);
SOAPBodyElement bodyElement = body.addBodyElement(bodyName);
URL endpoint = new URL(urlendpoint); // urlendpoint is the one that I took from WSDL file service endpoint.
SOAPMessage response = connection.call(message, endpoint);
connection.close();
I get the below error message whenever I execute this. I could not understand why.. The same url is returning the
proper response when I execute curl command from Unix and post the same request xml that was created by above java code.
Feb 14, 2017 3:21:54 PM com.sun.xml.internal.messaging.saaj.soap.MessageImpl identifyContentType
SEVERE: SAAJ0537: Invalid Content-Type. Could be an error message instead of a SOAP message
com.sun.xml.internal.messaging.saaj.SOAPExceptionImpl: Invalid Content-Type:text/html. Is this an error message instead of a SOAP response?
That error means that the server responds with an HTML page instead of a SOAP response. To debug this, you need to intercept the response and look at the content of the HTML page; it will probably contain more information about the problem.
I'm using CXf's fault out interceptor to intercept the exception from the web services method. That works fine within the handleMessage method..
Now I have two questions,
How do I had extra information to the Fault object apart from setting the faultcode?
Say if there is any error in the handleMessage method, the control goes to handleFault method but in the handle fault method it simply unwinds and logs something like - GetMth has thrown exception, unwinding now: java.lang.Exception. But the fault message(in xml format) is not being sent to the client as Output mesasage,
2. How do I make sure that the fault message is sent as SOAPfault to the clinet? (in the hanldeMessage below, i have place `f=null` to introduce the fault) Please Suggest!!!
I managed to write the xml content to the writer class with the below code, but am unable to pass this message to the client. I mean even after writing the message to the xmlwriter class and content being written fine to the console log, its not been sent to the client. i.e, I dont see the outbound message being sent nor printed when i turn on the monitors and the interceptor outbound logs. Could anyone please help me with this?
MessageFactory factory = getFactory(message);
SOAPMessage soapMessage = factory.createMessage();
SOAPPart soapPart = soapMessage.getSOAPPart();
SOAPBody soapBody = soapPart.getEnvelope().getBody();
SOAPFault soapFault = soapBody.addFault();
soapFault.setFaultString("Strange");
W3CDOMStreamWriter writer1 = new SAAJStreamWriter(soapPart);
message.setContent(XMLStreamWriter.class, writer1);
message.setContent(SOAPMessage.class, soapMessage);
message.setContent(Node.class, soapMessage.getSOAPPart());
message.getInterceptorChain().add(SAAJOutEndingInterceptor.INSTANCE);
LOGS:
saaj the factory com.sun.xml.messaging.saaj.soap.ver1_2.SOAPMessageFactory1_2Impl#146ee9c
saaj the soapMessage com.sun.xml.messaging.saaj.soap.ver1_2.Message1_2Impl#1db52c8
saaj the soapPart com.sun.xml.messaging.saaj.soap.ver1_2.SOAPPart1_2Impl#17d6c1
saaj the soapsoapBodyPart [env:Body: null]
saaj the soapFault [env:Fault: null]
saaj the setFaultString Strange
saaj the messg {org.apache.cxf.message.Message.RESPONSE_CODE=200, HTTP.RESPONSE=org.apache.catalina.connector.ResponseFacade#2982bf, org.apache.cxf.headers.Header.list=[], wrote.envelope.start=true, org.apache.cxf.message.Message.ENCODING=UTF-8, org.apache.cxf.message.FaultMode=CHECKED_APPLICATION_FAULT, org.apache.cxf.binding.soap.SoapVersion=org.apache.cxf.binding.soap.Soap12#b16f5f, Content-Type=application/soap+xml, org.apache.cxf.binding.soap.saaj.SAAJOutInterceptor.original.xml.writer=[StreamWriter: class com.ctc.wstx.sw.SimpleNsStreamWriter, underlying outputter: com.ctc.wstx.sw.BufferingXmlWriter#1144823], org.apache.cxf.interceptor.LoggingOutInterceptor.log-setup=true, org.apache.cxf.service.model.BindingFaultInfo=org.apache.cxf.service.model.BindingFaultInfo#106def2}
saaj the writer1 :
><pre><env:Header/><env:Body><env:Fault><env:Code><env:Value>env:Receiver</env:Value></env:Code><env:Reason><env:Text xml:lang="en-US">Strange</env:Text></env:Reason></env:Fault></env:Body> </pre>
Please advise.
Using JAX-WS and a custom WSDL, is there a way to get the message that would be sent to a web-service without actually making a call to the service? I need to generate a soap message conforming to a WSDL, but that soap message is actually embedded into another message. I was thinking I could create a local web-service that just echos back the message but it seems like there should be a way without doing this or using a handlerchain when it doens't really matter that the message is sent.
Maybe the easiest thing to do is just to generate the soap manually?
I hope this helps:
http://www.java-tips.org/java-ee-tips/java-api-for-xml-web-services/writing-a-handler-in-jax-ws.html
You can intercept message before being sent, get the body, get the header, sign it with SAML or whatever you want, and then send it to server.
maybe this example helps (from Understanding Web Services, Part 1: SOAP, IBM Developer Works, page 21):
MessageFactory messageFactory = MessageFactory.newInstance();
SOAPMessage message = messageFactory.createMessage();
SOAPPart SOAPPart = message.getSOAPPart();
SOAPEnvelope envelope = SOAPPart.getEnvelope();
SOAPBody body = envelope.getBody();
SOAPElement bodyElement = body.addChildElement(envelope.createName("echo", "req", "http://localhost:8080/axis2/services/MyService/"));
bodyElement.addChildElement("category").addTextNode("classifieds");
message.saveChanges();
SOAPPart SOAPpartbefore = message.getSOAPPart();
SOAPEnvelope reqenv = SOAPpartbefore.getEnvelope();
System.out.println(reqenv.toString());