前言:
最近在開發中需要調用對方的 webservice服務,按照現有的技術,本應該是一件很簡單的事情,只需要拿到wsdl文件,生成客戶端代碼即可,但是,對方的webservice服務是06年用axis1.4生成發布的,wsdl文件只能用axis1.4生成客戶端代碼,而axis的jar包和程序部署環境WebSphere8.5沖突,導致程序無法啟動。之前的測試中,spring的WebServiceTemplate可以在was環境下使用,所以,寫一下spring如何手動編寫客戶端代碼,調用axis1.4的服務端。
不管用什麼工具生成的webservice客戶端代碼,最終都工具根據生產的代碼組裝為符合soap協議的xml文件發送給服務端,接收服務端返回的xml文件,解析成我們需要的對象。雖然spring無法根據axis1.4的wsdl文件生成客戶端javaBean對象,但是可以先根據wsdl解析到要發送給服務端的 xml文件的格式,由xml文件反向推導出spring組裝此xml文件的javaBean對象,所以重點就是如何根據wsdl解析出服務端需要的xml文件,和 spring javaBean和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: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:encoding> 5 <sayHelloReturn xsi:type="xsd:string">?</sayHelloReturn > 6 </sayHelloResponse> 7 </soapenv:Body> 8 </soapenv:Envelope>
對應關系:請求報文中 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 }
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 }