前言:
最近在開發中需要調用對方的 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 }