本章主要詳細記錄如何讀懂一個WSDL描述文件。
在上一章裏面我們已經成功部署了一個WebService服務,並且通過瀏覽器能夠順利的看到WSDL文件。那麼該文件
表示什麼含義呢?通過這個文件我們該如何調用他呢?
1、先列出一份簡單的wsdl
<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions targetNamespace="http://www.ztesoft.com/axis/sayHello"
xmlns:apachesoap="http://xml.apache.org/xml-soap"
xmlns:impl="http://www.ztesoft.com/axis/sayHello"
xmlns:intf="http://www.ztesoft.com/axis/sayHello"
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:wsdlsoap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<wsdl:message name="qryUserNameRequest">
<wsdl:part name="name" type="xsd:string" />
</wsdl:message>
<wsdl:message name="qryUserNameResponse">
<wsdl:part name="qryUserNameReturn" type="xsd:string" />
</wsdl:message>
<wsdl:portType name="HelloImpl">
<wsdl:operation name="qryUserName" parameterOrder="name">
<wsdl:input message="impl:qryUserNameRequest" name="qryUserNameRequest" />
<wsdl:output message="impl:qryUserNameResponse" name="qryUserNameResponse" />
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="SayHelloSoapBinding" type="impl:HelloImpl">
<wsdlsoap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http" />
<wsdl:operation name="qryUserName">
<wsdlsoap:operation soapAction="" />
<wsdl:input name="qryUserNameRequest">
<wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
namespace="http://www.ztesoft.com/axis/sayHello" use="encoded" />
</wsdl:input>
<wsdl:output name="qryUserNameResponse">
<wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
namespace="http://www.ztesoft.com/axis/sayHello" use="encoded" />
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="HelloImplService">
<wsdl:port binding="impl:SayHelloSoapBinding" name="SayHello">
<wsdlsoap:address location="http://127.0.0.1:8080/axis/services/SayHello" />
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
2、描述一個wsdl需要從那些方面描述
首先讓我們想一想,如果你想告訴別人你的網絡服務,最起碼你要讓別人知道那些信息,別人才能調用。
1、服務的請求地址,最好多個服務綁定到一個地址上。傳遞參數時指明調用方法名就可以了。
2、服務使用了什麼協議傳輸數據,例如soap協議,或者http協議的get方法,或者http協議的post方式等。
3、在這個地址中,有哪些可以操作的方法。方法入參是什麼,出參是什麼。例如出參是UserInfo複雜對象。
4、針對上面的方法,詳細描述入參或者出參的結構。例如UserInfo裏面有哪些String類型的,那些int類型的等。
3、針對上面提出的要求,我們來看看wsdl文件內的內容。
上面的wsdl文件由4個節點組成。首先根節點是wsdl:definitions表示這個是一個wsdl的定義文件。(文件從下往上看)
3.1、wsdl:definitions:根節點,表示裏面的內容是用來描述webservice的,首先引入schema。這樣就不能亂寫了。
3.2、wsdl:service:提供了一個地址,如果你想訪問這個服務就調用這個地址就行了。
3.3、wsdl:binding:服務的協議,例如使用了soap協議。
3.4、wsdl:portType:具體的服務集合,有哪些方法可以操作。方法入參是什麼,出參是什麼。
3.5、wsdl:message:消息的詳細信息,詳細描述了出參是什麼,入參是什麼。
4、我對wsdl的一些看法
第一次看這個文檔挺難理解的。如果你瞭解下面幾個原因我想看着也許挺容易的。
1、比較複雜的東西應該抽取出來複用。例如上面的wsdl:portType裏面有方法入參和出參。之所以用wsdl:message抽
取出來作爲一個節點描述入參和出參。不就是爲了複用嗎,如果寫在一起有別的方法也用到這種類型入參或者出參。那豈
不是還要寫一次。
2、其實這個和配置servlet有些相似。servlet配置時配置如下
<servlet>
<servlet-name>AxisServlet</servlet-name>
<servlet-class>org.apache.axis.transport.http.AxisServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>AxisServlet</servlet-name>
<url-pattern>/services/*</url-pattern>
</servlet-mapping>
例如上面想把一個url和一個類對應起來,中間加了一個servlet-name節點做爲中間連接點,爲什麼不直接把url和類映
射到一起呢?我想如果這樣做,可能不合理,要是直接映射。那麼多一個對應該類的請求就需要多寫一次類的全名,例如
<servlet-mapping>
<servlet-class>org.apache.axis.transport.http.AxisServlet</servlet-class>
<url-pattern>/services/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-class>org.apache.axis.transport.http.AxisServlet</servlet-class>
<url-pattern>/ws/*</url-pattern>
</servlet-mapping>
如果中間多出來一個步驟,使用別名來對應應該方便很多。以後更改類了,只要改一次就可以了,如果不是的話,那麼豈
不是每一個都需要改。
而這裏呢?wsdl:service可以看成是url-pattern。wsdl:binding則相當於是servlet-name。wsdl:portType相當於servlet-class
這樣看是不是容易了,而且還可以添加很多額外的信息。例如wsdl:binding還可以添加一些描述信息,例如使用什麼協議。
5、上面文件的含義
服務集合wsdl:service裏面有個服務SayHello的訪問地址是http://127.0.0.1:8080/axis/services/SayHello,這個服務的
使用協議(通過什麼方式傳輸數據)是wsdl:binding描述的。並且通過他我們還可以找到具體實現類wsdl:portType,在這
個類中有哪些方法wsdl:operation,以及方法的詳細入參(wsdl:input)出參(wsdl:output)。在wsdl:message中可以看
到參數的詳細組成。
6、通過上面的wsdl文件,我們如何調用
package com.ztesoft.axis.client;
import javax.xml.namespace.QName;
import org.apache.axis.client.Call;
import org.apache.axis.client.Service;
public class Client {
public static void main(String[] args) throws Exception {
// wsdlsoap:address 節點中的地址值。
String url = "http://127.0.0.1:8080/axis/services/SayHello";
Service service = new Service();
Call call = (Call) service.createCall();
call.setTargetEndpointAddress(url);
// wsdl:portType 裏面的操作方法。
call.setOperationName(new QName(url, "qryUserName"));
// 根據描述傳入一個String對象,因爲可能有多個入參,所以使用Objct[]
// 描述的返回參數是String, 強轉String。
String result = (String) call.invoke(new Object[]{"Readiay"});
System.out.println(result);;
}
}
上面就是使用axis提供的客戶端簡單調用一下,最後在控制檯就簡單的打印了處理後的東西。在後面的章節將詳細說明
如何調用客戶端的內容。此處先做一個簡單說明。