Web Service描述語言 WSDL 詳解 3
<portType>和<operation>元素
PortType定義了一些抽象的操作。PortType中的operation元素定義了調用PortType中所有方法的語法,每一個operation元素聲明了方法的名稱、參數(使用<message>元素)和各自的類型(<part>元素要在所有<message>中聲明)。
在一篇WSDL文檔中可以有幾個<PortType>元素,每一個都和一些相關操作放在一起,就和COM和一組操作的接口相似。
在<operation>元素中,可能會有至多一個<input>元素,一個<output>元素,以及一個<fault>元素。三個元素各有一個名字和一個消息屬性。
<input>, <output>, <fault>元素屬性的名字有何含義呢?它們可以用來區別兩個同名操作(重載)。例如,看下面兩個C函數:
void
?foo(
int
?arg);
void
?foo(
string
?arg);
這種重載在WSDL中可以這樣表示
<?xml?version="1.0"?encoding="UTF-8"??>
<definitions?name="fooDescription"
targetNamespace="http://tempuri.org/wsdl/"
xmlns:wsdlns="http://tempuri.org/wsdl/"
xmlns:typens="http://tempuri.org/xsd"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:stk="http://schemas.microsoft.com/soap-toolkit/wsdl-
extension"
xmlns="http://schemas.xmlsoap.org/wsdl/">
<types>
<schema?targetNamespace="http://tempuri.org/xsd"
xmlns="http://www.w3.org/2001/XMLSchema"?
xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
elementFormDefault="qualified"?>
</schema>
</types>

<message?name="foo1">
<part?name="arg"?type="xsd:int"/>
</message>

<message?name="foo2">
<part?name="arg"?type="xsd:string"/>
</message>

<portType?name="fooSamplePortType">
<operation?name="foo"?parameterOrder="arg?"?>
<input?name="foo1"?message="wsdlns:foo1"/>
</operation>
<operation?name="foo"?parameterOrder="arg?"?>
<input?name="foo2"?message="wsdlns:foo2"/>
</operation>
</portType>

<binding?name="fooSampleBinding"?type="wsdlns:fooSamplePortType">
<stk:binding?preferredEncoding="UTF-8"?/>
<soap:binding?style="rpc"?
transport="http://schemas.xmlsoap.org/soap/http"/>
<operation?name="foo">
<soap:operation?soapAction="http://tempuri.org/action/foo1"/>
<input?name="foo1">
<soap:body?use="encoded"?namespace="http://tempuri.org/message/"?
encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"?/>
</input>
</operation>
<operation?name="foo">
<soap:operation?soapAction="http://tempuri.org/action/foo2"/>
<input?name="foo2">
<soap:body?use="encoded"?
namespace="http://tempuri.org/message/"?
encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"?
/>
</input>
</operation>
</binding>

<service?name="FOOService">
<port?name="fooSamplePort"?binding="fooSampleBinding">
<soap:address?
location="http://carlos:8080/fooService/foo.asp"/>
</port>
</service>
</definitions>? 到目前為止,還沒有一種SOAP的實現支持重載。這對基于JAVA的客戶端十分重要,因為JAVA服務器使用的接口用到JAVA的重載特性。而對基于COM的客戶端,就不那么重要,因為COM是不支持重載的。
<binding>和<operation>元素
Binding欄是完整描述協議、序列化和編碼的地方,Types, Messages和PortType欄處理抽象的數據內容,而Binding欄是處理數據傳輸的物理實現。Binding欄把前三部分的抽象定義具體化。
把相關的數據制定和消息聲明分開,這意味著同一類型服務的提供者可以把一系列的操作標準化。每個提供者可以提供定制的binding來互相區分。WSDL也有一個重要的結構,使抽象定義可以放在分離的文件中,而不是和Bindings和Services在一起,這樣可在不同的服務提供者之間提供標準化的抽象定義,這很有幫助。例如,銀行可以用WSDL文檔來標準化一些銀行的操作。每個銀行仍然可以自由的訂制下層的協議、串行優化,及編碼。
下面是重載的WSDL示例 的Binding欄,重復在此以便討論:
<binding?name="fooSampleBinding"?type="wsdlns:fooSamplePortType">
<stk:binding?preferredEncoding="UTF-8"?/>
<soap:binding?style="rpc"?
transport="http://schemas.xmlsoap.org/soap/http"/>
<operation?name="foo">
<soap:operation?soapAction="http://tempuri.org/action/foo1"/>
<input?name="foo1">
<soap:body?use="encoded"?namespace="http://tempuri.org/message/"?
encodingStyle=
?"http://schemas.xmlsoap.org/soap/encoding/"?/>
</input>
</operation>
<operation?name="foo">
<soap:operation?soapAction="http://tempuri.org/action/foo2"/>
<input?name="foo2">
<soap:body?use="encoded"?
namespace="http://tempuri.org/message/"?
encodingStyle=
"http://schemas.xmlsoap.org/soap/encoding/"?/>
</input>
</operation>
</binding>? <binding>元素已經取了一個名字(本例中"fooSampleBinding"),這樣就可以被Services欄的<port>元素引用了。它有一個"type"的屬性引用<portType>,本例中就是"wsdlns:fooSamplePortType"。第二行是MSTK2的擴展元素<stk:binding>,它指定了preferredEncoding屬性為"UTF-8"。
<soap:binding>元素指定了所使用的風格("rpc")和傳輸方式。Transport屬性應用了一個namespace,正是這個namespace指明使用HTTP SOAP協議。
有兩個同以"foo"命名的<operation>元素。唯一不同的是它們各自的<input>名字,分別為"foo1"和"foo2"。兩個<operation>元素中的<soap:operation>元素有同樣的"soapAction"屬性,是URI。soapAction屬性是SOAP特定的URI,它只是簡單的使用于SOAP消息。所產生的SOAP消息有一個SOAPAction頭,而URI也僅在<soap:operation>元素里才起作用。soapAction屬性在HTTP的binding中是必需的,但在其他非HTTP binding中卻不要提供。目前它的使用并不清楚,但它似乎有助于本例中的兩個"foo"操作。SOAP 1.1指明soapAction用來確定消息的"意圖"。似乎服務器可以在不解析整個消息的情況下就能使用這一屬性來發送消息。實際上,它的使用多種多樣。<soap:operation>元素也可以包含另一屬性,即"style"屬性,在有必要沖突<soap:binding>元素指定的風格時可以使用。
<operation>屬性可以包含<input>, <output> 和<fault>的元素,它們都對應于PortType欄中的相同元素。只有<input>元素在上例中提供。這三個元素中的每一個可有一個可選的"name"屬性,在本例中,我們用這種方法來區分同名操作。在本例的<input>元素中有一個<soap:body>元素,它指定了哪些信息被寫進SOAP消息的信息體中。該元素有以下屬性:
Use
用于制定數據是"encoded"還是"literal"。"Literal"指結果SOAP消息包含以抽象定義(Types, Messages, 和PortTypes)指定格式存在的數據。"Encoded"指"encodingStyle"屬性決定了編碼方式。
Namespace
每個SOAP消息體可以有其自己的namespace來防止命名沖突。這一屬性制定的URI在結果SOAP消息中逐字使用。
EncodingStyle
對SOAP編碼,它應該有以下URI值:
"http://schemas.xmlsoap.org/soap/encoding"?文檔風格實現
在前幾欄中,<soap:binding>元素有一個類型屬性,設為"rpc"。此屬性設為"document"時會改變傳輸時消息的串行化。不同于函數簽名,現在的消息是文檔傳輸的。在這類binding中,<message>元素定義文檔格式,而不是函數簽名。作為例子,考慮以下WSDL片段:
<definitions
xmlns:stns="(SchemaTNS)"
xmlns:wtns="(WsdlTNS)"
targetNamespace="(WsdlTNS)">

<schema?targetNamespace="(SchemaTNS)"
elementFormDefault="qualified">
<element?name="SimpleElement"?type="xsd:int"/>
<element?name="CompositElement"?type="stns:CompositeType"/>
<complexType?name="CompositeType">
<all>
<element?name='a'?type="xsd:int"/>
<element?name='b'?type="xsd:string"/>
</all>
</complexType>
</schema>

<message
>
<part?name='p1'?type="stns:CompositeType"/>
<part?name='p2'?type="xsd:int"/>
<part?name='p3'?element="stns:SimpleElement"/>
<part?name='p4'?element="stns:CompositeElement"/>
</message>
…
</definitions>? schema有兩個元素:SimpleElement和CompositeElement,還有一個類型聲明(CompositeType)。唯一聲明的<message>元素有四個部分:p1:Composite型;p2:int型;p3:SimpleElement型;p4:CompositeElement型。以下有一個表,對四種類型的use/type決定的binding作一比較:rpc/literal, document/literal, rpc/encoded, 以及document/encoded。表指明了每種binding的表現。
<service>和<port>元素
service是一套<port>元素。在一一對應形式下,每個<port>元素都和一個location關聯。如果同一個<binding>有多個<port>元素與之關聯,可以使用額外的URL地址作為替換。
一個WSDL文檔中可以有多個<service>元素,而且多個<service>元素十分有用,其中之一就是可以根據目標URL來組織端口。這樣,我就可以方便的使用另一個<service>來重定向我的股市查詢申請。我的客戶端程序仍然工作,因為這種根據協議歸類的服務不隨服務而變化。多個<service>元素的另一個作用是根據特定的協議劃分端口。例如,我可以把所有的HTTP端口放在同一個<service>中,所有的SMTP端口放在另一個<service>里。我的客戶可以搜索與它可以處理的協議相匹配的<service>。
<service?name="FOOService">
<port?name="fooSamplePort"?binding="fooSampleBinding">
<soap:address?
location="http://carlos:8080/fooService/foo.asp"/>
</port>
</service>? 在一個WSDL文檔中,<service>的name屬性用來區分不同的service。因為同一個service中可以有多個端口,它們也有"name"屬性。
總結
本文中我描述了WSDL文檔關于SOAP方面的最顯著的特點。不過應該說明的是WSDL并不僅限于HTTP上的SOAP。WSDL用來描述HTTP-POST、HTTP-GET、SMTP及其他協議時非常清晰。使用了WSDL,SOAP更加容易處理了,無論是開發者還是使用者。我相信WSDL和SOAP一起將會開創網絡應用程序世界的新時代。
WSDL的namespace里有一系列的XML元素。下表概述了那些元素、它們的屬性和內容。
元素 | 屬性 | 內容(子元素) |
<definitions> | name targetNamespace xmlns (other namespaces) | <types> <message> <portType> <binding> <service> |
<types> | (none) | <xsd:schema> |
<message> | Name | <part> |
<portType> | Name | <operation> |
<binding> | name type | <operation> |
<service> | name | <port> |
<part> | name type | (empty) |
<operation> | name parameterOrder | <input> <output> <fault> |
<input> | name message | (empty) |
<output> | name message | (empty) |
<fault> | name message | (empty) |
<port> | name binding | <soap:address> |
資源:
1. WSDL 1.1
2. SOAP 1.1
3. XML Schema Primer
4. MS SOAP Toolkit Download Site
5. A tool for translating IDL to WSDL
6. Free Web Services resources including a WSDL to VB proxy generator
7. PocketSOAP: SOAP related components, tools & source code
?
posted on 2007-01-22 12:59
Java初心 閱讀(2747)
評論(0) 編輯 收藏 所屬分類:
Web Service