使用CXF解析wsdl文件生成webservice的客户端后,在调用时可能会爆出这个问题,这是因为客户端调用接口发送的soap协议和服务端接口接受的soap协议不一致所致,在Eclipse或者MyEclipse中,可以使用TCP/IP Monitor 进行监控,查看客户端方和服务端方的soap协议版本。
在我的实际应用中,生成java代码后,调用接口发生了A SOAP 1.2 message is not valid when sent to a SOAP 1.1 only endpoint.错误,监控通信内容如下:
这是我发送出去的,使用的是soap1.1的协议;
这是服务器端返回的信息,由图可知服务端使用的是soap1.2的协议。
我尝试了更改wsdl的头文件声明,再生成的java类还是一样的错误。后来查看cxf源码得知soap的默认版本是soap1.1,需要在生成接口实例前修改soap版本为1.2。
代码如下:
private static JaxWsProxyFactoryBean jobFactory; // WS的代理连接
private static xxWebService xxWebService;
public static xxWebService getxxWebService() {
try {
String url = "http://127.0.0.1:8088";
log.info("getxxWebService Ready");
if (jobFactory != null) {
String str = jobFactory.getAddress();
if ((str != null) && (str.equals(url))) {
return xxWebService;
}
}
jobFactory = new JaxWsProxyFactoryBean();
jobFactory.setServiceClass(xxWebService.class);
jobFactory.setAddress(url);
jobFactory.getOutInterceptors().add(new LoggingOutInterceptor());
//默认为soap1.1,这里改为soap1.2协议发送
SoapBindingConfiguration config = new SoapBindingConfiguration();
<strong><em><u> </u>Soap12 sv = Soap12.getInstance();
config.setVersion(sv);
jobFactory.setBindingId(SoapBindingConstants.SOAP12_BINDING_ID);
jobFactory.setBindingConfig(config);</em></strong>
xxWebService = (xxWebService)jobFactory.create();
Client client = ClientProxy.getClient(xxWebService);
HTTPConduit conduit = (HTTPConduit)client.getConduit();
HTTPClientPolicy httpClientPolicy = new HTTPClientPolicy();
httpClientPolicy.setConnectionTimeout(10000);
httpClientPolicy.setReceiveTimeout(30000);
// 解决Marshalling Error: Error writing request body to server
httpClientPolicy.setAllowChunking(false);// 取消块编码
conduit.setClient(httpClientPolicy);
return xxWebService;
}
catch (Exception e) {
e.printStackTrace();
}
return null;
}
这样就可以以soap1.2协议调用接口了。