前言:
最近在开发中需要调用对方的 webservice服务,按照现有的技术,本应该是一件很简单的事情,只需要拿到wsdl文件,生成客户端代码即可,但是,对方的webservice服务是06年用axis1.4生成发布的,wsdl文件只能用zxis1.4生产客户端代码,而axis的jar包和程序部署环境WebSphere8.5冲突,导致程序无法启动。spring的WebServiceTemplate可以在was环境下使用,所以,写一下spring如何手动编写客户端代码,调用axis1.4的服务端。
解决方案:
不管用什么工具生成的webservice客户端,最终都组装为符合soap协议的xml文件发送给服务端,接收服务端返回的xml文件,解析成我们需要的对象。虽然spring无法根据axis1.4的wsdl文件生成客户端javaBean对象,但是我们可以根据spring由自己生产的javaBean对象如何组装soap协议xml文件的规则,反向手动编写这些javaBean,即:根据soap协议的xml文件反向推导出组装此xml文件的javaBean对象。
-
根据wsdl拿到要发送给服务端的xml文件,
这里根据wsdl的语法和soap协议规范,可以自己解析,但是比较费时,所以推荐一个工具:soapUI,可以根据wsdl文件生成要发送给服务端的xml文件以及对应服务端返回的xml文件(只是这个工具的一个小功能),本文用的soapUI版本是5.2.1
请求的xml文件实例:
1 <soapenv:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" > 2 <soapenv:Header/> 3 <soapenv:Body> 4 <sayHello soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"> 5 <message xsi:type="xsd:string">?</message> 6 </sayHello> 7 </soapenv:Body> 8 </soapenv:Envelope>
应答xml文件实例:
1 <soapenv:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"> 2 <soapenv:Header/> 3 <soapenv:Body> 4 <sayHelloResponse soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"> 5 <sayHelloReturn xsi:type="xsd:string">?</sayHelloReturn > 6 </sayHelloResponse> 7 </soapenv:Body> 8 </soapenv:Envelope>
2. 根据xml编写javaBean
对应关系:请求报文中 Body标签内的 标签就是服务端方法的描述,
sayHello --> 服务端的方法名 --> javaBean类 --> @XmlRootElement 中的name的值
sayHello的子标签是方法的参数,后面定义了参数的类型
message --> 方法参数 --> javaBean的字段 --> @XmlElement 中的name的值
请求javaBean实例
1 import javax.xml.bind.annotation.XmlAccessType; 2 import javax.xml.bind.annotation.XmlAccessorType; 3 import javax.xml.bind.annotation.XmlElement; 4 import javax.xml.bind.annotation.XmlRootElement; 5 6 @XmlAccessorType(XmlAccessType.FIELD) 7 @XmlRootElement(name = "sayHello") 8 public class SayHelloRequest { 9 10 @XmlElement(name = "message") 11 private String message; 12 13 public String getMessage() { 14 return message; 15 } 16 17 public void setMessage(String message) { 18 this.message = message; 19 } 20 }
应答javaBean实例
1 import javax.xml.bind.annotation.XmlAccessType; 2 import javax.xml.bind.annotation.XmlAccessorType; 3 import javax.xml.bind.annotation.XmlElement; 4 import javax.xml.bind.annotation.XmlRootElement; 5 6 @XmlAccessorType(XmlAccessType.FIELD) 7 @XmlRootElement(name = "sayHelloResponse") 8 public class SayHelloResponse { 9 10 @XmlElement(name = "sayHelloReturn") 11 private String sayHelloReturn; 12 13 public String getSayHelloReturn() { 14 return sayHelloReturn; 15 } 16 17 public void setSayHelloReturn(String sayHelloReturn) { 18 this.sayHelloReturn = sayHelloReturn; 19 } 20 }
3. spring WebserviceTemplate调用
spring的WebserviceTemplate使用这里不做详解了,需要配置WebserviceTemplate的bean和解析xml文件的 Marshaller bean
1 import javax.annotation.Resource; 2 3 public class WsTest { 4 5 @Resource 6 private WebServiceTemplate webServiceTemplate; 7 8 public SayHelloResponse sayHello (SayHelloRequest request) { 9 10 String url = "http://www.xxxx.com/xxx"; 11 12 return (SayHelloResponse)webServiceTemplate.marshalSendAndReceive (url, request); 13 } 14 15 }