Web services 如何使用SpringWS客户端从具有无效内容类型的web服务读取响应?

Web services 如何使用SpringWS客户端从具有无效内容类型的web服务读取响应?,web-services,soap,spring-ws,Web Services,Soap,Spring Ws,同事们,我调用webservice并收到异常: org.springframework.ws.soap.SoapMessageCreationException:无法 从InputStream创建消息:无效内容类型:text/html。是 这是一条错误消息,而不是SOAP响应?;嵌套异常是 com.sun.xml.internal.messaging.saaj.SOAPExceptionImpl:无效 内容类型:text/html。这是一条错误消息而不是SOAP吗 回应 我阅读和阅读 Wires

同事们,我调用webservice并收到异常:

org.springframework.ws.soap.SoapMessageCreationException:无法 从InputStream创建消息:无效内容类型:text/html。是 这是一条错误消息,而不是SOAP响应?;嵌套异常是 com.sun.xml.internal.messaging.saaj.SOAPExceptionImpl:无效 内容类型:text/html。这是一条错误消息而不是SOAP吗 回应

我阅读和阅读

Wireshark显示,我收到了以下响应:

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>
您能帮我阅读web服务响应吗

更新

--- 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

查看您的堆栈跟踪,其中抛出了org.springframework.ws.soap.SoapMessageCreationException。根据错误发生的位置,您可能能够配置org.springframework.ws.client.core.WebServiceTemplate以接受内容类型:text/html

我有一种感觉,实现的那个方面是不可插拔的,您将无法替换它。看见基本异常发生在某些jdk代码中


如果是我,我会尝试使用常规http客户端,进行http调用,并手动解析响应。这里有一些使用apache客户端完成此操作的完整示例:

我们的一个供应商服务也面临同样的问题,它返回的内容类型为text/html,而SpringWeb服务模板不喜欢这样。 因为在SpringWeb服务中没有简单的方法来更改响应头。我通过使用自定义Http客户机解决了这个问题,然后提供客户机拦截器来删除“内容类型”头


我刚刚删除了并且没有添加“内容类型”标题,因为SOAPMessageFactory for SOAP 1.1和1.2在处理消息之前添加了一个适当的标题。

我与您在该内容类型上遇到了相同的问题:text/html 因此,我的全部注意力都集中在尝试将CT更改为text/xml,但这并没有奏效。问题是你的“我的客户”,你需要有一个正确的“MessageSender”和依赖性,我已经在我的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();
}
在pom文件中,我添加了

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>
打电话是个好主意

WebServiceTemplate WebServiceTemplate=getWebServiceTemplate(); webServiceTemplate.AfterPropertieSet();
在您的“公共类myClient扩展WebServiceGatewaySupport”类中

Robert,谢谢。您是否建议使用常规http客户端而不是spring ws-WebServiceTemplate?因为WebServiceTemplare只能在响应中使用text/xml内容类型(而不是text/html)时正常工作。是的,spring只接受text/xml和少量其他内容类型。Robert,您建议使用哪个http客户端库来调用ws?此外,我的web服务在请求中接受xml(soap消息),但返回text/html。apache客户端很好。这里有一些完整的例子来说明这一点:这对我来说很有效。我们基于WireMock的SOAP服务返回application/xml。我修改了上面的代码,以便在发现该内容类型时删除标题。此外,我还对“org.springframework.ws.server.MessageTracing”使用了跟踪日志记录,这意味着我可以看到WireMock服务器的确切响应,并确定我看到的错误消息是出于正确的原因。
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();
 @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();
}
    <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>
@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;
}