WSDL實例解析
關鍵字: web serviceWSDL的主要文檔元素
WSDL文檔可以分為兩部分。頂部分由抽象定義組成,而底部分則由具體描述組成。抽象部分以獨立于平臺和語言的方式定義SOAP消息,它們并不包含任何隨 機器或語言而變的元素。這就定義了一系列服務,截然不同的應用都可以實現。具體部分,如數據的序列化則歸入底部分,因為它包含具體的定義。在上述的文檔元 素中,<types>、<message>、<portType>屬于抽象定義 層,<binding>、<service>屬于具體定義層。所有的抽象可以是單獨存在于別的文件中,也可以從主文檔中導入。
WSDL文檔的結構實例解析
下面我們將通過一個實際的WSDL文檔例子來詳細說明各標簽的作用及關系。
- <?xml version="1.0" encoding="UTF-8"?>
- <definitions
- xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
- xmlns:tns="http://www.jsoso.com/wstest"
- xmlns:xsd="http://www.w3.org/2001/XMLSchema"
- xmlns="http://schemas.xmlsoap.org/wsdl/"
- targetNamespace="http://www.jsoso.com/wstest"
- name="Example">
- <types>
- <xsd:schema>
- <xsd:import
- namespace="http://www.jsoso.com/wstest"
- schemaLocation="http://localhost:8080/hello?xsd=1"></xsd:import>
- </xsd:schema>
- </types>
- <message name="toSayHello">
- <part name="userName" type="xsd:string"></part>
- </message>
- <message name="toSayHelloResponse">
- <part name="returnWord" type="xsd:string"></part>
- </message>
- <message name="sayHello">
- <part name="person" type="tns:person"></part>
- <part name="arg1" type="xsd:string"></part>
- </message>
- <message name="sayHelloResponse">
- <part name="personList" type="tns:personArray"></part>
- </message>
- <message name="HelloException">
- <part name="fault" element="tns:HelloException"></part>
- </message>
- <portType name="Example">
- <operation name="toSayHello" parameterOrder="userName">
- <input message="tns:toSayHello"></input>
- <output message="tns:toSayHelloResponse"></output>
- </operation>
- <operation name="sayHello" parameterOrder="person arg1">
- <input message="tns:sayHello"></input>
- <output message="tns:sayHelloResponse"></output>
- <fault message="tns:HelloException" name="HelloException"></fault>
- </operation>
- </portType>
- <binding name="ExamplePortBinding" type="tns:Example">
- <soap:binding
- transport="http://schemas.xmlsoap.org/soap/http"
- style="rpc"></soap:binding>
- <operation name="toSayHello">
- <soap:operation soapAction="sayHello"></soap:operation>
- <input>
- <soap:body use="literal"
- namespace="http://www.jsoso.com/wstest"></soap:body>
- </input>
- <output>
- <soap:body use="literal"
- namespace="http://www.jsoso.com/wstest"></soap:body>
- </output>
- </operation>
- <operation name="sayHello">
- <soap:operation soapAction="sayHello"></soap:operation>
- <input>
- <soap:body use="literal"
- namespace="http://www.jsoso.com/wstest"></soap:body>
- </input>
- <output>
- <soap:body use="literal"
- namespace="http://www.jsoso.com/wstest"></soap:body>
- </output>
- <fault name="HelloException">
- <soap:fault name="HelloException" use="literal"></soap:fault>
- </fault>
- </operation>
- </binding>
- <service name="Example">
- <port name="ExamplePort" binding="tns:ExamplePortBinding">
- <soap:address location="http://localhost:8080/hello"></soap:address>
- </port>
- </service>
- </definitions>
由于上面的事例XML較長,我們將其逐段分解講解
WSDL文檔的根元素:<definitions>
- <definitions
- xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
- xmlns:tns="http://www.jsoso.com/wstest"
- xmlns:xsd="http://www.w3.org/2001/XMLSchema"
- xmlns="http://schemas.xmlsoap.org/wsdl/"
- targetNamespace="http://www.jsoso.com/wstest"
- name="Example">
- ……
- ……
- </definitions>
<definitions>定義了文檔中用到的各個xml元素的namespace縮寫,也界定了本文檔自己的 targetNamespace="http://www.jsoso.com/wstest",這意味著其它的XML要引用當前XML中的元素時,要聲 明這個namespace。注意xmlns:tns="http://www.jsoso.com/wstest"這個聲明,它標示了使用tns這個前綴 指向自身的命名空間。
WSDL文檔數據類型定義元素:<types>
- <types>
- <xsd:schema>
- <xsd:import
- namespace="http://www.jsoso.com/wstest"
- schemaLocation="http://localhost:8080/hello?xsd=1"></xsd:import>
- </xsd:schema>
- </types>
<types>標簽定義了當前的WSDL文檔用到的數據類型。要說明的是,為了最大程度的平臺中立性,WSDL 使用 XML Schema 語法來定義數據類型。這些數據類型用來定義web service方法的參數和返回指。對于通用的原生數據類型如:integer , boolean , char , float等,在W3C的標準文檔http://www.w3.org/2001/XMLSchema中已經做了定義。這里我們要引入的schema定義 schemaLocation="http://localhost:8080/hello?xsd=1"是我們自定義的Java對象類型。
WSDL文檔消息體定義元素:< message >
- <message name="toSayHello">
- <part name="userName" type="xsd:string"></part>
- </message>
- <message name="toSayHelloResponse">
- <part name="returnWord" type="xsd:string"></part>
- </message>
- <message name="sayHello">
- <part name="person" type="tns:person"></part>
- <part name="arg1" type="xsd:string"></part>
- </message>
- <message name="sayHelloResponse">
- <part name="personList" type="tns:personArray"></part>
- </message>
- <message name="HelloException">
- <part name="fault" element="tns:HelloException"></part>
- </message>
<message>元素定義了web service函數的參數。<message>元素中的每個<part>子元素都和某個參數相符。輸入參數在<message>元素中定義,與輸出參數相 隔離,輸出參數有自己的<message>元素。兼作輸入、輸出的參數在輸入輸出的<message>元素中有它們相應的<part>元素。輸出 <message>元素以"Response"結尾,對Java而言方法得返回值就對應一個輸出的<message>。每個<part>元素都有名字和類 型屬性,就像函數的參數有參數名和參數類型。
在上面的文檔中有兩個輸入參數、兩個輸出參數和一個錯誤參數(對應Java中的Exception)。
? 輸入參數<message>的name屬性分別命名為toSayHello,sayHello。
toSayHello對應輸入參數userName,參數類型為xsd:string,在Java語言中就是String;
sayHello對應兩個輸入參數person和arg1,類型為tns:person和xsd:string。這里tns:person類型就是引用了< types >標簽中的類型定義。
? 輸出參數<message>的name屬性分別命名為toSayHelloResponse和sayHelloResponse。
這個名稱和輸入參數的<message>標簽name屬性對應,在其后面加上Response尾綴。
toSayHelloResponse對應的返回值是returnWord,參數類型為xsd:string;
sayHelloResponse對應的返回值是personList,參數類型為tns:personArray(自定義類型);
? 錯誤參數<message>的name屬性為HelloException。
它的<part>子標簽element而不是type來定義類型。
以上的message標簽的name屬性通常使用web service函數方法名作為參照,錯誤參數標簽則使用異常類名為參照。標簽中的參數名稱,即part子元素的name屬性是可自定義的(下一章節(jié)詳細說 明)。message標簽的參數類型將引用types標簽的定義。
WSDL文檔函數體定義元素:< portType >
- <portType name="Example">
- <operation name="toSayHello" parameterOrder="userName">
- <input message="tns:toSayHello"></input>
- <output message="tns:toSayHelloResponse"></output>
- </operation>
- <operation name="sayHello" parameterOrder="person arg1">
- <input message="tns:sayHello"></input>
- <output message="tns:sayHelloResponse"></output>
- <fault message="tns:HelloException" name="HelloException"></fault>
- </operation>
- </portType>
在<operation>元素中,name屬性表示服務方法名,parameterOrder屬性表示方法的參數順序,使用空格符分割多個參 數,如:“parameterOrder="person arg1”。<operation>元素的子標簽<input>表示輸入參數說明,它引用<message>標簽中的輸入參 數。<output>表示輸出參數說明,它引用<message>標簽中的輸出參數。<fault>標簽在Java方法中的特別 用來表示異常(其它語言有對應的錯誤處理機制),它引用<message>標簽中的錯誤參數。
WSDL綁定實現定義元素:< binding >
- <binding name="ExamplePortBinding" type="tns:Example">
- <soap:binding
- transport="http://schemas.xmlsoap.org/soap/http"
- style="rpc"></soap:binding>
- <operation name="toSayHello">
- <soap:operation soapAction="sayHello"></soap:operation>
- <input>
- <soap:body use="literal"
- namespace="http://www.jsoso.com/wstest"></soap:body>
- </input>
- <output>
- <soap:body use="literal"
- namespace="http://www.jsoso.com/wstest"></soap:body>
- </output>
- </operation>
- <operation name="sayHello">
- <soap:operation soapAction="sayHello"></soap:operation>
- <input>
- <soap:body use="literal"
- namespace="http://www.jsoso.com/wstest"></soap:body>
- </input>
- <output>
- <soap:body use="literal"
- namespace="http://www.jsoso.com/wstest"></soap:body>
- </output>
- <fault name="HelloException">
- <soap:fault name="HelloException" use="literal"></soap:fault>
- </fault>
- </operation>
- </binding>
<binding>標簽是完整描述協(xié)議、序列化和編碼的地方,<types>,<message>和<portType>標簽處理抽象的數據內容,而<binding>標簽是處理數據傳輸的物理實現。
<binding>標簽把前三部分的抽象定義具體化。
首先<binding>標簽使用<soap:binding>的transport和style屬性定義了Web Service的通訊協(xié)議HTTP和SOAP的請求風格RPC。其次<operation>子標簽將portType中定義的 operation同SOAP的請求綁定,定義了操作名稱soapAction,輸出輸入參數和異常的編碼方式及命名空間。
WSDL服務地址綁定元素:< service >
- <service name="Example">
- <port name="ExamplePort" binding="tns:ExamplePortBinding">
- <soap:address location="http://localhost:8080/hello"></soap:address>
- </port>
- </service>
service是一套<port>元素。在一一對應形式下,每個<port>元素都和一個location關聯(lián)。如果同一個<binding>有多個<port>元素與之關聯(lián),可以使用額外的URL地址作為替換。
一個WSDL文檔中可以有多個<service>元素,而且多個<service>元素十分有用,其中之一就是可以根據目標URL來組織端口。在一個 WSDL文檔中,<service>的name屬性用來區(qū)分不同的service。在同一個service中,不同端口,使用端口的"name"屬性區(qū) 分。
簡單的描述了WSDL對SOAP協(xié)議的支持,以及在Web Service中的作用。