1

Collegues, i call webservice and receive the exception:

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?

I read this and this.

Wireshark shows than i receive response:

HTTP/1.1 200 OK
Content-Type: text/html
Transfer-Encoding: chunked
Server: Jetty(8.1.13.v20130916)

<?xml version="1.0" encoding="UTF-8"?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ws="http://mayacomp/Generic/Ws">
<soapenv:Body>
<ws:response>
<out>
<requestID>6b140165-af79-47a2-9e9f-5b7bba265050</requestID>
<requestTimestamp>2015-12-01T13:04:44.044</requestTimestamp>
</out>
</ws:response>
</soapenv:Body>
</soapenv:Envelope>

My beans looks like:

@Bean
    public Jaxb2Marshaller marshaller() {
        Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
        marshaller.setContextPath("com.mayacomp.entities");
        HashMap<String,Object> properties = new HashMap<String,Object>();
        properties.put(javax.xml.bind.Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
        marshaller.setMarshallerProperties(properties);
        return marshaller;
    }


@Bean
public myClient myClient(Jaxb2Marshaller marshaller) {
    myClient client = new myClient();
    client.setDefaultUri("URL");
    client.setMarshaller(marshaller);
    client.setUnmarshaller(marshaller);
    //client.setMessageSender(messageSender);
    return client;
}

Class which calls WS looks like:

public class myClient extends WebServiceGatewaySupport {

    public Response createApplication(In in) {

        Request request = (Request) new Request();
        request.setIn(in);

        Response response = (Response) getWebServiceTemplate().marshalSendAndReceive(
                "URL",
                request,
                new WebServiceMessageCallback()
                { public void doWithMessage(WebServiceMessage message) {

                        SaajSoapMessage saajSoapMessage = (SaajSoapMessage)message;

                        SOAPMessage soapMessage = SOAP.createSOAPMessage(in);

                        saajSoapMessage.setSaajMessage(soapMessage);

                }

                } 
                );
        return null;
    }

Could you help me to read web service response?

UPDATE

--- maven-dependency-plugin:2.8:tree (default-cli) @ adapter ---
com.comp:adapter:jar:0.0.1-SNAPSHOT
+- junit:junit:jar:4.12:compile
|  \- org.hamcrest:hamcrest-core:jar:1.3:compile
+- org.springframework:spring-context:jar:4.2.3.RELEASE:compile
|  +- org.springframework:spring-aop:jar:4.2.3.RELEASE:compile
|  |  \- aopalliance:aopalliance:jar:1.0:compile
|  +- org.springframework:spring-beans:jar:4.2.3.RELEASE:compile
|  \- org.springframework:spring-expression:jar:4.2.3.RELEASE:compile
+- org.springframework:spring-core:jar:4.2.3.RELEASE:compile
|  \- commons-logging:commons-logging:jar:1.2:compile
+- io.codearte.jfairy:jfairy:jar:0.5.1:compile
|  +- com.google.guava:guava:jar:19.0-rc2:compile (version selected from constraint [15.0,))
|  +- org.yaml:snakeyaml:jar:1.16:compile (version selected from constraint [1.9,2.0))
|  +- org.iban4j:iban4j:jar:2.1.1:compile
|  +- com.google.inject:guice:jar:4.0:compile
|  |  \- javax.inject:javax.inject:jar:1:compile
|  +- joda-time:joda-time:jar:2.3:compile
|  +- com.google.inject.extensions:guice-assistedinject:jar:4.0:compile
|  +- org.reflections:reflections:jar:0.9.9:compile
|  |  +- org.javassist:javassist:jar:3.18.2-GA:compile
|  |  \- com.google.code.findbugs:annotations:jar:2.0.1:compile
|  +- org.apache.commons:commons-lang3:jar:3.3.2:compile
|  \- org.slf4j:slf4j-api:jar:1.7.7:compile
+- org.fluttercode.datafactory:datafactory:jar:0.8:compile
+- org.springframework.ws:spring-ws-core:jar:2.2.3.RELEASE:compile
|  +- org.springframework.ws:spring-xml:jar:2.2.3.RELEASE:compile
|  +- org.springframework:spring-oxm:jar:4.0.9.RELEASE:compile
|  +- org.springframework:spring-web:jar:4.0.9.RELEASE:compile
|  \- org.springframework:spring-webmvc:jar:4.0.9.RELEASE:compile
+- log4j:log4j:jar:1.2.17:compile
\- org.apache.httpcomponents:httpclient:jar:4.5.1:compile
   +- org.apache.httpcomponents:httpcore:jar:4.4.3:compile
   \- commons-codec:commons-codec:jar:1.9:compile
Community
  • 1
  • 1
May12
  • 2,420
  • 12
  • 63
  • 99

3 Answers3

2

I am facing the same problem with one of our vendor services which returns Content-Type as text/html and spring web service template does not like that. As there is no easy way to change the response headers in spring web-service. I solved it by using custom Http client and then providing client interceptor which removes "Content-Type" headers.

HttpClient httpClient = HttpClients.custom()
            .addInterceptorFirst(new HttpComponentsMessageSender.RemoveSoapHeadersInterceptor())
            .addInterceptorFirst(new HttpResponseInterceptor() {
                @Override
                public void process(HttpResponse httpResponse, HttpContext httpContext) throws HttpException, IOException {
                    boolean htmlResponse = Arrays.stream(httpResponse.getAllHeaders()).anyMatch(header -> header.getName().equalsIgnoreCase("Content-Type") && header.getValue().contains("text/html"));
                    if (htmlResponse) {
                        httpResponse.removeHeaders("Content-Type");
                    }
                }
            })
            .setDefaultRequestConfig(requestConfig)
            .build();

I just removed and did not add "Content-Type" header because SOAPMessageFactory for SOAP 1.1 and 1.2 adds a appropriate header before processing the message.

Ajinkya
  • 544
  • 4
  • 9
  • This worked for me.Our WireMock-based SOAP service was returning application/xml. I modified the above code to remove the header when it found that content type. In addition I used TRACE logging for 'org.springframework.ws.server.MessageTracing' which meant I could see the exact response from the WireMock server and determine that the error message I was seeing was for the correct reason. – mekondelta Jul 26 '19 at 08:41
1

Take a look in your stack trace where org.springframework.ws.soap.SoapMessageCreationException is being thrown. Depending on where the error happens you might be able to configure org.springframework.ws.client.core.WebServiceTemplate to accept Content-Type:text/html.

I have a feeling that that aspect of the implementation is not pluggable and that you wouldn't be able to replace it. See SOAPExceptionImpl: Invalid Content-Type:text/html. Is this an error message instead of a SOAP response?. The base exception is occuring in some jdk code.

If it were me, I'd be tempted to use a regular http client, make an http call, and manually parse the response. There are some complete examples for using the apache client to do this here: Sending HTTP Post request with SOAP action using org.apache.http

Community
  • 1
  • 1
Robert Moskal
  • 21,737
  • 8
  • 62
  • 86
  • Robert, thank you. Do you advice to use regular http client instead of spring-ws WebServiceTemplate? Because WebServiceTemplare works correctly only with text/xml content type in response (not with text/html). – May12 Dec 01 '15 at 16:53
  • Yes, spring will only accept text/xml and a handful of other content-types. – Robert Moskal Dec 01 '15 at 16:54
  • Robert, which http client library do you recommend to use to call ws? Also my web service accept xml (soap message) in request, but return text/html. – May12 Dec 02 '15 at 05:18
  • The apache client is nice. There are some complete examples for doing this here: http://stackoverflow.com/questions/10671494/sending-http-post-request-with-soap-action-using-org-apache-http – Robert Moskal Dec 02 '15 at 15:08
0

I had the same problem as you with this Content-Type:text/html So all my focus was on trying to change the CT to text/xml but that didn't work. The problem is your "MyClient" you need to have a correct "MessageSender" and dependancy that I have added in my pom.

 @Bean
public HttpComponentsMessageSender defaultMessageSender() {
    HttpComponentsMessageSender messageSender = createMessageSenderBasicAuth();

    HttpClientBuilder httpClientBuilder = HttpClients.custom()
            .useSystemProperties()
            .addInterceptorFirst(new HttpComponentsMessageSender.RemoveSoapHeadersInterceptor())
            .setDefaultCredentialsProvider(basicAuthCredentials())
            .setDefaultRequestConfig(requestConfigWithDefaultTimeout());

    messageSender.setHttpClient(httpClientBuilder.build());

    return messageSender;
}
private HttpComponentsMessageSender createMessageSenderBasicAuth() {
    return new HttpComponentsMessageSender() {
        @Override
        protected HttpContext createContext(URI uri) {
            HttpHost target = new HttpHost(uri.getHost(), uri.getPort(), uri.getScheme());
            AuthCache authCache = new BasicAuthCache();
            BasicScheme basicAuth = new BasicScheme();
            authCache.put(target, basicAuth);
            HttpClientContext localContext = HttpClientContext.create();
            localContext.setAuthCache(authCache);

            return localContext;
        }
    };
}

private RequestConfig requestConfigWithDefaultTimeout() {
    return RequestConfig.custom()
            .setConnectionRequestTimeout(10000)
            .setConnectTimeout(10000) // 10 sec
            .setSocketTimeout(10000)
            .build();
}

In the pom file I have added

pom.xml

    <dependency>
        <groupId>org.springframework.ws</groupId>
        <artifactId>spring-ws-core</artifactId>
        <version>2.4.7.RELEASE</version>
    </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.12.2</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-annotations</artifactId>
            <version>2.12.1</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.10.2</version>
        </dependency>

Your "MyClient" Should look like this

@Bean
public myClient myClient(@Qualifier("marshaller") Jaxb2Marshaller marshaller) {
    myClient client = new myClient();
    client.setDefaultUri("URL");
    client.setMarshaller(marshaller);
    client.setUnmarshaller(marshaller);
    client.setMessageSender(defaultMessageSender());
    return client;
}

And its a good idea to call

WebServiceTemplate webServiceTemplate = getWebServiceTemplate(); webServiceTemplate.afterPropertiesSet(); inside your "public class myClient extends WebServiceGatewaySupport" class