当SOAP请求太长时,我们使用WildFly 11中的JAX-WS(引擎盖下的Apache CXF)作为响应获得'401: Unauthorized'
。
我们使用NTLM协议从WildFly调用SOAP Web服务。
如果请求大小很短,它可以正常工作,但如果请求是“大”(例如,带有1MB的SOAP消息),它将失败并显示错误HTTP 401.我们正在使用此Web服务发送图像,但编码为base64二进制的。
我们尝试使用SOAP UI调用该服务并且它有效,因此它似乎是应用程序服务器中的问题。可能会发生什么,以及我们可以使用哪些变通方法?
更新: Jira问题CXF-5890似乎与此类似。
我们的客户端代码非常简单,我们发送一个BASE64字节数组(s:base64Binary):
@Stateless
public class Client {
@WebServiceRef(wsdlLocation = "/wsdl/service.wsdl")
private ServiceRepository service;
public void send() {
Repository repository = service.getRepositorySoap();
Map<String, Object> requestContext = ((BindingProvider) repository).getRequestContext();
requestContext.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, "http://customerendpoint/service.asmx");
// sets standard Java authentication for NTLM
authtWsSharepoint();
// This method loads an image in BASE64. We found the problem around 45,000 characters, but it is not exact
String image = getImage();
repository.submitFile(image.getBytes());
}
}
我们正在使用标准的Java身份验证器:
private void authtWsSharepoint() throws Exception {
Authenticator sAuthService = new Authenticator() {
@Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication("domain\\user", "password".toCharArray());
}
};
Authenticator.setDefault(sAuthService);
}
以下是例外:
Caused by: org.apache.cxf.transport.http.HTTPException: HTTP response '401: Unauthorized' when communicating with http://customerendpoint/service.asmx
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponseInternal(HTTPConduit.java:1581)
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponse(HTTPConduit.java:1533)
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.close(HTTPConduit.java:1336)
at org.apache.cxf.io.CacheAndWriteOutputStream.postClose(CacheAndWriteOutputStream.java:56)
at org.apache.cxf.io.CachedOutputStream.close(CachedOutputStream.java:215)
at org.apache.cxf.transport.AbstractConduit.close(AbstractConduit.java:56)
at org.apache.cxf.transport.http.HTTPConduit.close(HTTPConduit.java:652)
at org.apache.cxf.interceptor.MessageSenderInterceptor$MessageSenderEndingInterceptor.handleMessage(MessageSenderInterceptor.java:62)
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:307)
at org.apache.cxf.endpoint.ClientImpl.doInvoke(ClientImpl.java:516)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:425)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:326)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:279)
at org.apache.cxf.frontend.ClientProxy.invokeSync(ClientProxy.java:96)
at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:138)
... 110 more
答案 0 :(得分:1)
魔术发生在httpClientPolicy.setAllowChunking(false)
。将此设置为false可解决问题。
代码示例
Client client = ClientProxy.getClient(servicePort);
HTTPConduit http = (HTTPConduit) client.getConduit();
HTTPClientPolicy httpClientPolicy = new HTTPClientPolicy();
//This is the magic line. Setting this to false solved the problem
httpClientPolicy.setAllowChunking(false);
http.setClient(httpClientPolicy);
<强>依赖关系强>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-simple</artifactId>
<version>3.0.5</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http</artifactId>
<version>3.0.5</version>
<scope>provided</scope>
</dependency>
<强>的JBoss部署-structure.xml 强>
<?xml version="1.0" encoding="UTF-8"?>
<jboss-deployment-structure>
<deployment>
<dependencies>
<module name="org.apache.cxf.impl">
<imports>
<include path="META-INF"/>
<include path="META-INF/cxf"/>
</imports>
</module>
</dependencies>
</deployment>
</jboss-deployment-structure>