<binding>和<o(jì)peration>元素
Binding欄是完整描述協(xié)議、序列化和編碼的地方,Types, Messages和PortType欄處理抽象的數(shù)據(jù)內(nèi)容,而Binding欄是處理數(shù)據(jù)傳輸?shù)奈锢韺崿F(xiàn)。Binding欄把前三部分的抽象定義具體化。
把相關(guān)的數(shù)據(jù)制定和消息聲明分開,這意味著同一類型服務(wù)的提供者可以把一系列的操作標(biāo)準(zhǔn)化。每個提供者可以提供定制的binding來互相區(qū)分。WSDL也有一個重要的結(jié)構(gòu),使抽象定義可以放在分離的文件中,而不是和Bindings和Services在一起,這樣可在不同的服務(wù)提供者之間提供標(biāo)準(zhǔn)化的抽象定義,這很有幫助。例如,銀行可以用WSDL文檔來標(biāo)準(zhǔn)化一些銀行的操作。每個銀行仍然可以自由的訂制下層的協(xié)議、串行優(yōu)化,及編碼。
下面是重載的WSDL示例 的Binding欄,重復(fù)在此以便討論:
<binding name="fooSampleBinding" type="wsdlns:fooSamplePortType">
<stk:binding preferredEncoding="UTF-8" />
<soap:binding style="rpc"
transport="http://schemas.xmlsoap.org/soap/http"/>
<o(jì)peration 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>
<o(jì)peration 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>元素已經(jīng)取了一個名字(本例中"fooSampleBinding"),這樣就可以被Services欄的<port>元素引用了。它有一個"type"的屬性引用<portType>,本例中就是"wsdlns:fooSamplePortType"。第二行是MSTK2的擴展元素<stk:binding>,它指定了preferredEncoding屬性為"UTF-8"。
<soap:binding>元素指定了所使用的風(fēng)格("rpc")和傳輸方式。Transport屬性應(yīng)用了一個namespace,正是這個namespace指明使用HTTP SOAP協(xié)議。
有兩個同以"foo"命名的<o(jì)peration>元素。唯一不同的是它們各自的<input>名字,分別為"foo1"和"foo2"。兩個<o(jì)peration>元素中的<soap:operation>元素有同樣的"soapAction"屬性,是URI。soapAction屬性是SOAP特定的URI,它只是簡單的使用于SOAP消息。所產(chǎn)生的SOAP消息有一個SOAPAction頭,而URI也僅在<soap:operation>元素里才起作用。soapAction屬性在HTTP的binding中是必需的,但在其他非HTTP binding中卻不要提供。目前它的使用并不清楚,但它似乎有助于本例中的兩個"foo"操作。SOAP 1.1指明soapAction用來確定消息的"意圖"。似乎服務(wù)器可以在不解析整個消息的情況下就能使用這一屬性來發(fā)送消息。實際上,它的使用多種多樣。<soap:operation>元素也可以包含另一屬性,即"style"屬性,在有必要沖突<soap:binding>元素指定的風(fēng)格時可以使用。
<o(jì)peration>屬性可以包含<input>, <o(jì)utput> 和<fault>的元素,它們都對應(yīng)于PortType欄中的相同元素。只有<input>元素在上例中提供。這三個元素中的每一個可有一個可選的"name"屬性,在本例中,我們用這種方法來區(qū)分同名操作。在本例的<input>元素中有一個<soap:body>元素,它指定了哪些信息被寫進(jìn)SOAP消息的信息體中。該元素有以下屬性:
Use
用于制定數(shù)據(jù)是"encoded"還是"literal"。"Literal"指結(jié)果SOAP消息包含以抽象定義(Types, Messages, 和PortTypes)指定格式存在的數(shù)據(jù)。"Encoded"指"encodingStyle"屬性決定了編碼方式。
Namespace
每個SOAP消息體可以有其自己的namespace來防止命名沖突。這一屬性制定的URI在結(jié)果SOAP消息中逐字使用。
EncodingStyle
對SOAP編碼,它應(yīng)該有以下URI值:
"http://schemas.xmlsoap.org/soap/encoding"
文檔風(fēng)格實現(xiàn)
在前幾欄中,<soap:binding>元素有一個類型屬性,設(shè)為"rpc"。此屬性設(shè)為"document"時會改變傳輸時消息的串行化。不同于函數(shù)簽名,現(xiàn)在的消息是文檔傳輸?shù)?。在這類binding中,<message>元素定義文檔格式,而不是函數(shù)簽名。作為例子,考慮以下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的表現(xiàn)。
<service>和<port>元素
service是一套<port>元素。在一一對應(yīng)形式下,每個<port>元素都和一個location關(guān)聯(lián)。如果同一個<binding>有多個<port>元素與之關(guān)聯(lián),可以使用額外的URL地址作為替換。
一個WSDL文檔中可以有多個<service>元素,而且多個<service>元素十分有用,其中之一就是可以根據(jù)目標(biāo)URL來組織端口。這樣,我就可以方便的使用另一個<service>來重定向我的股市查詢申請。我的客戶端程序仍然工作,因為這種根據(jù)協(xié)議歸類的服務(wù)不隨服務(wù)而變化。多個<service>元素的另一個作用是根據(jù)特定的協(xié)議劃分端口。例如,我可以把所有的HTTP端口放在同一個<service>中,所有的SMTP端口放在另一個<service>里。我的客戶可以搜索與它可以處理的協(xié)議相匹配的<service>。
<service name="FOOService">
<port name="fooSamplePort" binding="fooSampleBinding">
<soap:address
location="http://carlos:8080/fooService/foo.asp"/>
</port>
</service>
在一個WSDL文檔中,<service>的name屬性用來區(qū)分不同的service。因為同一個service中可以有多個端口,它們也有"name"屬性。
總結(jié)
本文中我描述了WSDL文檔關(guān)于SOAP方面的最顯著的特點。不過應(yīng)該說明的是WSDL并不僅限于HTTP上的SOAP。WSDL用來描述HTTP-POST、HTTP-GET、SMTP及其他協(xié)議時非常清晰。使用了WSDL,SOAP更加容易處理了,無論是開發(fā)者還是使用者。我相信WSDL和SOAP一起將會開創(chuàng)網(wǎng)絡(luò)應(yīng)用程序世界的新時代。
WSDL的namespace里有一系列的XML元素。下表概述了那些元素、它們的屬性和內(nèi)容。
元素 屬性 內(nèi)容(子元素)
<definitions> name
targetNamespace
xmlns (other namespaces) <types>
<message>
<portType>
<binding>
<service>
<types> (none) <xsd:schema>
<message> Name <part>
<portType> Name <o(jì)peration>
<binding> name
type <o(jì)peration>
<service> name <port>
<part> name
type (empty)
<o(jì)peration> name
parameterOrder <input>
<o(jì)utput>
<fault>
<input> name
message (empty)
<o(jì)utput> name
message (empty)
<fault> name
message (empty)
<port> name
binding <soap:address>
資源:
1.
WSDL 1.12.
SOAP 1.13.
XML Schema Primer4.
MS SOAP Toolkit Download Site5.
A tool for translating IDL to WSDL6.
Free Web Services resources including a WSDL to VB proxy generator7.
PocketSOAP: SOAP related components, tools & source code