HTTP headers are ignored [SWS-968]
Sergey Zaytsev Aleksandrovich opened SWS-968 and commented
HTTP headers set in HttpUrlConnectionMessageSender implementation are ignored. In particular issue refers to Content-type property.
Since I have the following exception trying to call a SOAP Action : Caused by: org.springframework.ws.soap.SoapMessageCreationException: Could not create message from InputStream: Invalid Content-Type:text/html. Is this an error message instead of a SOAP response?; nested exception is com.sun.xml.internal.messaging.saaj.SOAPExceptionImpl: Invalid Content-Type:text/html. Is this an error message instead of a SOAP response? at org.springframework.ws.soap.saaj.SaajSoapMessageFactory.createWebServiceMessage(SaajSoapMessageFactory.java:216) ~[spring-ws-core-2.3.0.RELEASE.jar:2.3.0.RELEASE] at org.springframework.ws.soap.saaj.SaajSoapMessageFactory.createWebServiceMessage(SaajSoapMessageFactory.java:60) ~[spring-ws-core-2.3.0.RELEASE.jar:2.3.0.RELEASE] at org.springframework.ws.transport.AbstractWebServiceConnection.receive(AbstractWebServiceConnection.java:92) ~[spring-ws-core-2.3.0.RELEASE.jar:2.3.0.RELEASE] at org.springframework.ws.client.core.WebServiceTemplate.doSendAndReceive(WebServiceTemplate.java:611) ~[spring-ws-core-2.3.0.RELEASE.jar:2.3.0.RELEASE] at org.springframework.ws.client.core.WebServiceTemplate.sendAndReceive(WebServiceTemplate.java:555) ~[spring-ws-core-2.3.0.RELEASE.jar:2.3.0.RELEASE] at org.springframework.ws.client.core.WebServiceTemplate.marshalSendAndReceive(WebServiceTemplate.java:390) ~[spring-ws-core-2.3.0.RELEASE.jar:2.3.0.RELEASE] at com.redsys.integration.main.TririgaBaseClient.getModules(TririgaBaseClient.java:55) ~[classes/:na] at com.redsys.integration.main.Application.lambda$lookup$0(Application.java:20) [classes/:na] at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:798) [spring-boot-1.4.0.RELEASE.jar:1.4.0.RELEASE] ... 6 common frames omitted 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(MessageImpl.java:655) ~[na:1.8.0_101] at com.sun.xml.internal.messaging.saaj.soap.MessageImpl.<init>(MessageImpl.java:301) ~[na:1.8.0_101] at com.sun.xml.internal.messaging.saaj.soap.ver1_1.Message1_1Impl.<init>(Message1_1Impl.java:65) ~[na:1.8.0_101] at com.sun.xml.internal.messaging.saaj.soap.ver1_1.SOAPMessageFactory1_1Impl.createMessage(SOAPMessageFactory1_1Impl.java:63) ~[na:1.8.0_101] at org.springframework.ws.soap.saaj.SaajSoapMessageFactory.createWebServiceMessage(SaajSoapMessageFactory.java:188) ~[spring-ws-core-2.3.0.RELEASE.jar:2.3.0.RELEASE] ... 14 common frames omitted
I decided to use custom sender with the following code:
@Override
protected void prepareConnection(HttpURLConnection connection) throws IOException {
connection.setRequestProperty("Content-Type", "application/soap+xml;charset=UTF-8");
super.prepareConnection(connection);
}
Exception tells us about wrong Content-Type: text/html though it has been changed.
Before calling to marshalSendAndReceive I do call webServiceTemplate.afterPropertiesSet().
Affects: 2.3.0
Attachments:
- Application.java (582 bytes)
- MainConfiguration.java (679 bytes)
- SOAPUI.pcapng (16.69 kB)
- SOAPUI-request-raw.dump (572 bytes)
- SOAPUI-response-raw.dump (9.76 kB)
- SpringWS.pcapng (5.36 kB)
- TririgaBaseClient.java (2.36 kB)
- TririgaCallerWithAuth.java (781 bytes)
- WebServiceTemplate-logging.dump (351 bytes)
jaminh commented
That content type, application/soap+xml is use for SOAP version 1.2. You likely just need to define a messageFactory configured to use SOAP version 1.2 as described here http://docs.spring.io/spring-ws/site/reference/html/common.html#soap_11_or_12.
Sergey Zaytsev Aleksandrovich commented
Unfortunately that didn't help.
I setted up SOAP version in the following way: final MessageFactory msgFactory = MessageFactory.newInstance(SOAPConstants.SOAP_1_2_PROTOCOL); final SaajSoapMessageFactory newSoapMessageFactory = new SaajSoapMessageFactory(msgFactory);
WebServiceTemplate webServiceTemplate = getWebServiceTemplate();
webServiceTemplate.setMessageFactory(newSoapMessageFactory);
webServiceTemplate.setMessageSender(new TririgaCallerWithAuth());
Now it complains about: Caused by: org.springframework.ws.soap.SoapMessageCreationException: Could not create message from InputStream: Invalid Content-Type:text/html. Is this an error message instead of a SOAP response?; nested exception is com.sun.xml.internal.messaging.saaj.SOAPExceptionImpl: Invalid Content-Type:text/html. Is this an error message instead of a SOAP response?
URL I pass into marshalSendAndReceive method works 100% ( tested it in SOAP UI manually ).
jaminh commented
Sorry, if you look closely at the exception it is actually saying you are getting a content-type of "text/html" in the response. When you get the successful response back with SOAP UI what is the Content-Type header for the response? If it is "text/html" then the service you are calling is not implementing SOAP correctly. Would it be possible for you to include the request and response you are getting from SOAP UI and the WebServiceTemplate?
Sergey Zaytsev Aleksandrovich commented
I've attached three files - two of them relate to SOAPUI ( request and response ) while the last one results from TRACE logging webServiceTemplate request. I did manage to see only SOAP envelop, with no HTTP headers mentioned ( do not know how to dig deeper in webServiceTemplate ). But my code contains explicit Content-Type setting in my TririgaCallerWithAuth.java file. So, there is no reponse file related to webServiceTemplate, since it seems that endpoint couldn't serve my webServiceTemplate's request.
jaminh commented
It appears from the SOAP UI response the service is using MTOM so you will need to enable that on your Marshaller. But based on the stack trace I think there is a different issue causing the service to send back an error page or something instead of an actual response. You could potentially get the whole HTTP conversation using tcpdump or wireshark to see the HTTP headers you are sending and the response you are getting back from the service. Otherwise you might be able to try one of the suggestions from here http://stackoverflow.com/questions/1445919/how-to-enable-wire-logging-for-a-java-httpurlconnection-traffic.
Sergey Zaytsev Aleksandrovich commented
I've tried inspection using Wireshark and saw SOAP envelope in both cases - SOAP UI and spring-ws code ( as in the attachments ). They a bit different - latter introduces 4 namespaces. But, I can manually type spring-ws' envelope in SOAP UI editor and it works! But I still can't make it work with spring-ws code.
Using Wireshark it is clear the there is no any mention of "Content-Type:text/html" - both soapui and sringws uses same "application/soap+xml" content type.
I've attached them as well... *.pcap fles
If you have any idea, I really appreciate that.
P.S.: I did set SOAP version 1.2 - didn't help. It remains 1.2 in my experiments.
Sergey Zaytsev Aleksandrovich commented
Seems like SOAPUI can parse response from web service while my code is not... Still looking at how to set allowable response's content-type
Sergey Zaytsev Aleksandrovich commented
There is one place where text/html has mentioned - in Accept. Is there a way to disable automatic value for Action header and set it explicitly ? Looks like this is a reason.
jaminh commented
Seems like you are sending your message to the wrong endpoint and you are getting a service listing or something like that in the response. You need to send the message to http://10.0.5.168/tririga/ws/TririgaWS
Sergey Zaytsev Aleksandrovich commented
Yes, the whole point of the service is to give a list of so called modules. Response from SOAP UI contains it. So, I've tried different variations with URLs but result always remains the case - complain about "text/html" content type.
Could you please provide very short snippet of calling marshallSendAndReceive(...) method with URL you mentioned ?
jaminh commented
Try replacing
Object response = webServiceTemplate.marshalSendAndReceive("http://10.0.5.168/tririga/ws",
getModules, new SoapActionCallback("http://10.0.5.168/tririga/ws/TririgaWS/getModules"));
with
Object response = webServiceTemplate.marshalSendAndReceive("http://10.0.5.168/tririga/ws/TririgaWS",
getModules);
in TririgaBaseClient. You shouldn't need the SoapActionCallback since when you are sending the request with SoapUI it is not including a SoapAction. I think the important thing you are missing is the "/TririgaWS" at the end of the URL.
jaminh commented
Also in the MainConfiguration you will want to change
@Bean
public Jaxb2Marshaller marshaller() {
return new Jaxb2Marshaller() ` setContextPath("com.redsys.wsdl.model"); ` ;
}
to
@Bean
public Jaxb2Marshaller marshaller() {
return new Jaxb2Marshaller() ` setContextPath("com.redsys.wsdl.model"); setMtomEnabled(true) ` ;
}