當(dāng)前位置:工程項(xiàng)目OA系統(tǒng) > 泛普各地 > 上海OA系統(tǒng) > 上海OA信息化
Web服務(wù)說(shuō)明語(yǔ)言 (WSDL) 淺釋
申請(qǐng)免費(fèi)試用、咨詢電話:400-8352-114
AMTeam.orgWeb服務(wù)說(shuō)明語(yǔ)言 (WSDL) 淺釋
Carlos C. Tapang
Infotects
2001年7月
摘要:使用 WSDL,用戶能夠以真正獨(dú)立于語(yǔ)言和平臺(tái)的方式,自動(dòng)生成 Web 服務(wù)代理。
為什么采用 WSDL?
Internet
協(xié)議這樣的標(biāo)準(zhǔn),是由某個(gè)機(jī)構(gòu)強(qiáng)加給人們的嗎?還是因?yàn)槿藗冋J(rèn)識(shí)到,遵循這些標(biāo)準(zhǔn)帶來(lái)的好處遠(yuǎn)遠(yuǎn)超過(guò)付出的代價(jià)而主動(dòng)接受?有很多標(biāo)準(zhǔn)提出之后最終都沒(méi)有獲得成功。有時(shí)候,即使通過(guò)法律或政府規(guī)定來(lái)強(qiáng)制執(zhí)行,這些標(biāo)準(zhǔn)也沒(méi)有得到推廣,Ada
編程語(yǔ)言就是一個(gè)例子。
我認(rèn)為,一項(xiàng)標(biāo)準(zhǔn)被廣泛接受一定是因?yàn)樽裱軒?lái)好處。以鐵路服務(wù)為例,不同公司修建的鐵軌要能夠相互銜接,或者來(lái)自不同公司的產(chǎn)品要能夠配合使用才行得通。有一些廠商已經(jīng)聯(lián)合起來(lái),要將 SOAP 變成一種標(biāo)準(zhǔn)。Web 服務(wù)說(shuō)明語(yǔ)言 (WSDL) 為 Web 服務(wù)提供商和用戶提供了一種方便的協(xié)作方式,使 SOAP 的好處更加明顯。使各個(gè)公司修建的鐵軌能夠銜接很簡(jiǎn)單:這些公司只需約定兩根鐵軌之間的距離即可。而對(duì)于 Web 服務(wù)則要復(fù)雜得多。首先,我們必須約定用于指定接口的標(biāo)準(zhǔn)格式。
有反對(duì)意見(jiàn)認(rèn)為,SOAP 并不真正需要接口說(shuō)明語(yǔ)言。如果 SOAP 是僅為傳輸內(nèi)容而制定的標(biāo)準(zhǔn),那么它需要一種語(yǔ)言來(lái)說(shuō)明這些內(nèi)容。SOAP 消息確實(shí)攜帶類型信息,所以 SOAP 允許動(dòng)態(tài)決定類型。但是,除非知道函數(shù)的名稱以及參數(shù)的數(shù)量和類型,否則我們并不能正確地調(diào)用函數(shù)。沒(méi)有 WSDL,您可以根據(jù)文檔(這必須有才行)或者通過(guò)檢查線路消息來(lái)判斷調(diào)用語(yǔ)法。這兩種方式都涉及人工操作,因此這個(gè)過(guò)程就有可能出錯(cuò)。而使用 WSDL,我能夠以真正獨(dú)立于語(yǔ)言和平臺(tái)的方式,為 Web 服務(wù)自動(dòng)生成代理。就像 IDL 文件對(duì)于 COM 和 CORBA 一樣,WSDL 文件是客戶端和服務(wù)器之間的合約。
請(qǐng)注意,盡管 WSDL 被設(shè)計(jì)成可以表達(dá)與非 SOAP 協(xié)議的綁定,我們這里主要考慮的是其與 HTTP 上的 SOAP 相關(guān)的情況。另外,雖然 SOAP 現(xiàn)在主要用于進(jìn)行遠(yuǎn)程過(guò)程或函數(shù)調(diào)用,但是 WSDL 還允許以 SOAP 傳輸文檔規(guī)范。WSDL 1.1 已經(jīng)作為草案提交到 W3C。請(qǐng)參閱 http://www.w3.org/TR/wsdl.html(英文)。
WSDL 文檔結(jié)構(gòu)
使用模塊圖有助于理解 XML 文檔。下圖通過(guò)顯示組成
WSDL 文檔(是 XML 文檔)的五個(gè)小節(jié)之間的關(guān)系,展示了 WSDL 的結(jié)構(gòu)。
WSDL 文檔的節(jié)可分成兩組。上層的組包含抽象定義,而下層的組包含具體說(shuō)明。抽象各節(jié)以獨(dú)立于語(yǔ)言和平臺(tái)的方式定義 SOAP 消息,不包含特定計(jì)算機(jī)或語(yǔ)言專用的元素。這有助于定義一套各種網(wǎng)站都能實(shí)現(xiàn)的服務(wù)。與具體站點(diǎn)相關(guān)的問(wèn)題(例如序列化)被放到下層各節(jié),這些節(jié)包含具體的說(shuō)明。
抽象定義
類型
獨(dú)立于計(jì)算機(jī)和語(yǔ)言的類型定義。
消息
包含函數(shù)參數(shù)(輸入與輸出分開(kāi))或文檔說(shuō)明。
端口類型
引用消息節(jié)中的消息定義來(lái)說(shuō)明函數(shù)簽名(操作名稱、輸出參數(shù)和輸出參數(shù)等)。
具體說(shuō)明
綁定
指定端口類型節(jié)中每個(gè)操作的綁定。
服務(wù)
指定每個(gè)綁定的端口地址。
在下圖中,箭頭連接符表示文檔各節(jié)之間的關(guān)系。圓點(diǎn)和箭頭連接符表示“引用”或“使用”關(guān)系。雙箭頭連接符表示“修飾”關(guān)系。三維箭頭連接符表示“包含”關(guān)系??梢钥闯?,消息節(jié)使用類型節(jié)中的定義,端口類型節(jié)使用消息節(jié)中的定義,綁定節(jié)引用端口類型節(jié),而服務(wù)節(jié)引用綁定節(jié)。端口類型和綁定節(jié)包含操作元素,而服務(wù)節(jié)包含端口元素。端口節(jié)中的操作元素由綁定節(jié)中的操作元素修飾或說(shuō)明。
在本文中,我將使用標(biāo)準(zhǔn)的 XML 術(shù)語(yǔ)來(lái)說(shuō)明 WSDL 文檔。“元素”指一個(gè) XML 元素,而“屬性”指元素的屬性。形式如下:
<元素 屬性="屬性值">內(nèi)容</元素>
“內(nèi)容”可以由一個(gè)或多個(gè)元素以遞歸方式組成。根元素是最上層的元素,文檔中所有其他元素都從屬于它。子元素始終從屬于另一個(gè)元素(稱為“父元素”)。
請(qǐng)注意,可以只有一個(gè)或根本就沒(méi)有類型節(jié)。所有其他各節(jié)可以有零個(gè)、一個(gè)或多個(gè)父元素。例如,消息節(jié)可以有零個(gè)或多個(gè) <message> 元素。WSDL 架構(gòu)要求所有各節(jié)以規(guī)定的順序出現(xiàn):輸出、類型、消息、端口類型、綁定和服務(wù)。每個(gè)抽象節(jié)都可以放在獨(dú)立的文件中,并被導(dǎo)入到主文檔中。
圖 1:抽象定義和具體定義
WSDL 文件示例
讓我們來(lái)觀察一個(gè) WSDL
文件示例,了解其結(jié)構(gòu)和原理。請(qǐng)注意,這是一個(gè)非常簡(jiǎn)單的 WSDL
文檔實(shí)例。這里我們的目的僅僅是用它來(lái)說(shuō)明最重要的特性。后面各節(jié)將有更詳細(xì)的討論。
<?xml version="1.0" encoding="UTF-8" ?>
<definitions
name="FooSample"
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="Simple.foo">
<part name="arg"
type="xsd:int"/>
</message>
<message name="Simple.fooResponse">
<part
name="result" type="xsd:int"/>
</message>
<portType name="SimplePortType">
<operation
name="foo" parameterOrder="arg" >
<input
message="wsdlns:Simple.foo"/>
<output
message="wsdlns:Simple.fooResponse"/>
</operation>
</portType>
<binding name="SimpleBinding"
type="wsdlns:SimplePortType">
<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/Simple.foo"/>
<input>
<soap:body use="encoded" namespace="http://tempuri.org/message/"
encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
/>
</input>
<output>
<soap:body use="encoded"
namespace="http://tempuri.org/message/"
encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
/>
</output>
</operation>
</binding>
<service name="FOOSAMPLEService">
<port
name="SimplePort" binding="wsdlns:SimpleBinding">
<soap:address
location="http://carlos:8080/FooSample/FooSample.asp"/>
</port>
</service>
</definitions>
下面是示例文檔的要點(diǎn)。稍后我會(huì)詳細(xì)討論每一節(jié)。
第一行聲明該文檔是 XML。雖然這不是必需的,但它可以幫助 XML 語(yǔ)法分析程序判斷是要分析整個(gè) WSDL 文件還是產(chǎn)生一個(gè)錯(cuò)誤信號(hào)。第二行是 WSDL 文檔的根元素:<definitions>。根元素附加了一些名稱空間屬性(名稱空間聲明),<types> 元素的 <schema> 子元素也附加了一些名稱空間屬性。
<types> 元素包含類型節(jié)。如果不需要聲明數(shù)據(jù)類型,可以省略這一節(jié)。在示例 WSDL 中,沒(méi)有聲明應(yīng)用程序?qū)S玫念愋?,但我還是使用了類型節(jié),這只是為了聲明文檔中使用的架構(gòu)名稱空間。
<message> 元素包含消息節(jié)。如果我們把操作看作函數(shù),那么 <message> 元素就定義了該函數(shù)的參數(shù)。<message> 元素中的每個(gè) <part> 子元素都對(duì)應(yīng)一個(gè)參數(shù)。輸入的參數(shù)在一個(gè)單獨(dú)的 <message> 元素中定義,與輸出元素分開(kāi),輸出元素在自己的 <message> 元素中定義。輸入和輸出參數(shù)在輸入和輸出 <message> 元素中都有各自對(duì)應(yīng)的 <part> 元素。輸出 <message> 元素的名稱按約定以“Response”結(jié)尾,例如“fooResponse”。每個(gè) <part> 元素都有 name 和 type 屬性,就象每個(gè)函數(shù)參數(shù)都有名稱和類型一樣。
當(dāng)用于文檔交換時(shí),WSDL 允許使用 <message> 元素來(lái)說(shuō)明要交換的文檔。
<part> 元素的類型可以是 XSD 基本類型、SOAP 定義類型 (soapenc)、WSDL 定義類型 (wsdl) 或類型節(jié)定義類型。
端口類型節(jié)中可以有零個(gè)、一個(gè)或多個(gè) <portType> 元素。因?yàn)槌橄蟮亩丝陬愋投x可以放在獨(dú)立的文件中,所以 WSDL 文件中可能有零個(gè) <portType> 元素。上例只顯示了一個(gè) <portType> 元素。正如您所看到的,<portType> 元素用 <operation> 子元素來(lái)定義一個(gè)或多個(gè)操作。示例只顯示了一個(gè) <operation> 元素,名為“foo”。這個(gè)名稱相當(dāng)于函數(shù)名。<operation> 元素可以有一個(gè)、兩個(gè)或三個(gè)子元素:<input>、<output> 和 <fault> 元素。每個(gè) <input> 和 <output> 元素中的 message 屬性引用消息節(jié)中相關(guān)的 <message> 元素。這樣,示例中的整個(gè) <portType> 元素相當(dāng)于下面的 C 函數(shù)聲明:
int foo(int arg);
這個(gè)示例表明,與 C 相比,XML 是多么冗長(zhǎng)。(包括 <message> 元素在內(nèi),示例用了 12 行 XML 來(lái)表達(dá)這個(gè)在 C 中僅一行的函數(shù)聲明。)
綁定節(jié)可以有零個(gè)、一個(gè)或多個(gè) <binding> 元素。其目的是指定如何通過(guò)線路發(fā)送每個(gè) <operation> 的調(diào)用和響應(yīng)。服務(wù)節(jié)也可以有零個(gè)、一個(gè)或多個(gè) <service> 元素。它包含 <port> 元素。每個(gè) <port> 元素都引用綁定節(jié)中的一個(gè) <binding> 元素。綁定和服務(wù)節(jié)都包含對(duì) WSDL 文檔的具體說(shuō)明。
名稱空間
在根元素 <definitions> 和子元素
<schema> 中都有名稱空間屬性:
<definitions name="FooSample"
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>
每個(gè)名稱空間屬性為文檔中使用的每個(gè)名稱空間都聲明了一個(gè)簡(jiǎn)寫。在實(shí)例“xmlns:xsd”中,為名稱空間 http://www.w3.org/2001/XMLSchema(英文)定義了一個(gè)簡(jiǎn)寫 (xsd)。這樣,在文檔的后面部分只需要給名稱加上前綴(或“限定”)“xsd:”,就可以引用這個(gè)名稱空間,例如限定的類型名稱“xsd:int”。標(biāo)準(zhǔn)的作用域規(guī)則適用于這個(gè)簡(jiǎn)寫前綴。即,在某個(gè)元素中定義的前綴只在該元素中有效。
名稱空間的作用是什么?名稱空間是為避免命名沖突而設(shè)立的。假設(shè)我建立了一個(gè) Web 服務(wù),其 WSDL 文件包含一個(gè)名為“foo”的元素,而您要將我的 Web 服務(wù)與另一個(gè)補(bǔ)充的服務(wù)結(jié)合使用。如果沒(méi)有名稱空間,那么其他 Web 服務(wù)就不能在它們的 WSDL 文件中使用名稱“foo”。僅當(dāng)在兩個(gè)實(shí)例中它們都是指同一個(gè)對(duì)象,兩個(gè)服務(wù)才能使用相同的名稱。而在兩個(gè)不同的名稱空間中,我的 Web 服務(wù)“foo”與其他 Web 服務(wù)“foo”指的是不同的對(duì)象。在您的客戶端中,可以通過(guò)限定來(lái)引用我的“foo”。例如,如果我將 carlos 聲明為 http://www.infotects.com/fooService 的簡(jiǎn)寫,則完全限定名 http://www.infotects.com/fooService#foo 等價(jià)于“carlos:foo”。請(qǐng)注意,名稱空間中使用 URI 來(lái)保證其唯一性并允許在文檔中使用定位符。由 URI 指向的位置不一定對(duì)應(yīng)真實(shí)的 Web 位置。GUID 也可以用來(lái)代替或補(bǔ)充 URI。例如,GUID“335DB901-D44A-11D4-A96E-0080AD76435D”是一個(gè)有效的名稱空間指示符。
targetNamespace 屬性聲明了一個(gè)名稱空間,在該元素中聲明的所有名稱都從屬于該名稱空間。在 WSDL 文件示例中,<definitions> 的 targetNamespace 是 http://tempuri.org/wsdl。這意味著在此 WSDL 文檔中聲明的所有名稱都從屬于此名稱空間。<schema> 有自己的 targetNamespace 屬性,其值為 http://tempuri.org/xsd。因此,在此 <schema> 元素中定義的所有名稱都從屬于此名稱空間,而不是主目標(biāo)名稱空間。
<schema> 元素中的下一行聲明了一個(gè)默認(rèn)的名稱空間。架構(gòu)中所有未限定的名稱都屬于此名稱空間。
xmlns="http://www.w3.org/2001/XMLSchema"
SOAP 消息
看待 WSDL
文件的方式之一是:對(duì)于使用該文件的客戶端和服務(wù)器而言,它決定在線路上傳輸什么內(nèi)容。雖然 SOAP 使用了底層協(xié)議(例如 IP 和
HTTP),但是應(yīng)用程序決定了它在特定的客戶端和服務(wù)器之間使用的高層協(xié)議。換句話說(shuō),給定一個(gè)操作(例如僅簡(jiǎn)單地讀取并返回一個(gè)輸入的整數(shù)的“echoInt”),那么參數(shù)的數(shù)量、每個(gè)參數(shù)的類型以及這些參數(shù)通過(guò)線路(序列化)傳輸?shù)姆绞骄蜆?gòu)成了應(yīng)用程序?qū)S玫膮f(xié)議。這種協(xié)議可以按各種方式來(lái)指定,我相信最好的方式就是使用
WSDL。這樣看來(lái),WSDL 不僅是一個(gè)“接口合約”,而且還是一個(gè)協(xié)議規(guī)范語(yǔ)言。如果我們需要從 IP 和 HTTP
等“固定”的協(xié)議發(fā)展到應(yīng)用程序?qū)S玫膮f(xié)議,這正是我們所需要的。
WSDL 可以指定 SOAP 消息是遵循 rpc 還是遵循文檔樣式。rpc 樣式的消息(如示例中所用的)類似于有零個(gè)或更多參數(shù)的函數(shù)調(diào)用。文檔樣式的消息較平整,并且它需要的嵌套層次更少。下面的 XML 消息作為使用 MS SOAP Toolkit 2.0 (MSTK2) 中的 SoapClient 對(duì)象分析 WSDL 文件示例的結(jié)果被發(fā)送和接收。
從客戶端發(fā)送時(shí)使用函數(shù)調(diào)用“foo(5131953)”:
<?xml version="1.0" encoding="UTF-8"
standalone="no"?>
<SOAP-ENV:Envelope
SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Body>
<m:foo xmlns:m="http://tempuri.org/message/">
<arg>5131953</arg>
</m:foo>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
從服務(wù)器接收(響應(yīng)):
<?xml version="1.0" encoding="UTF-8"
standalone="no"?>
<SOAP-ENV:Envelope
SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Body>
<SOAPSDK1:fooResponse
xmlns:SOAPSDK1="http://tempuri.org/message/">
<result>5131953</result>
</SOAPSDK1:fooResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
函數(shù)調(diào)用消息及其響應(yīng)都是有效的 XML。SOAP 消息包含 <Envelope> 元素,而 <Envelope> 元素包含可選的 <Header> 元素和至少一個(gè) <Body> 元素。發(fā)送和接收的消息在主 <Envelope> 元素中都有一個(gè) <Body> 元素。rpc 函數(shù)調(diào)用消息正文有一個(gè)以操作名稱“foo”命名的元素,而響應(yīng)正文有一個(gè)“fooResponse”元素。foo 元素有一個(gè) <arg> 部分。<arg> 是一個(gè)參數(shù),如示例 WSDL 所說(shuō)明。fooResponse 同樣有一個(gè) <result> 部分。請(qǐng)注意 encodingStyle、envelope 和 message 名稱空間在 WSDL 的綁定節(jié)中的規(guī)定方式。如下所示。
<binding name="SimpleBinding"
type="wsdlns:SimplePortType">
<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/Simple.foo"/>
<input>
<soap:body use="encoded"
namespace="http://tempuri.org/message/"
encodingStyle=
"http://schemas.xmlsoap.org/soap/encoding/"
/>
</input>
<output>
<soap:body use="encoded"
namespace="http://tempuri.org/message/"
encodingStyle=
"http://schemas.xmlsoap.org/soap/encoding/"
/>
</output>
</operation>
</binding>
WSDL 類型和消息節(jié)中的 XML 架構(gòu)
WSDL 數(shù)據(jù)類型基于 W3C
推薦的“XML 架構(gòu):數(shù)據(jù)類型”(XSD)。此文檔有三個(gè)不同的版本(1999、2000/10 和 2001),應(yīng)該在 <definitions>
元素中的名稱空間之一中聲明,指定在 WSDL 文件中使用哪個(gè)版本:
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
本文中我們只考慮 2001 版。WSDL 標(biāo)準(zhǔn)的支持者強(qiáng)烈建議使用 2001 版。
在本節(jié)和后面各節(jié)中,使用了以下前綴或名稱空間簡(jiǎn)寫:
前綴 等價(jià)的名稱空間 說(shuō)明
soapenc http://schemas.xmlsoap.org/soap/encoding SOAP 1.1
編碼
wsdl http://schemas.xmlsoap.org/wsdl/soap WSDL 1.1
xsd http://www.w3.org/2001/XMLSchema XML 架構(gòu)
XSD 基本類型
下表摘自 MSTK2 文檔,列舉了 MSTK2 支持的全部
XSD 基本類型。它說(shuō)明了客戶端和服務(wù)器端的 WSDL 閱讀器如何將 XSD 類型映射到 variant 類型以及 VB、C++ 和 IDL
中對(duì)應(yīng)的類型。
XSD 定義了兩組內(nèi)置的數(shù)據(jù)類型:原始型和導(dǎo)出型。在 http://www.w3.org/TR/2001/PR-xmlschema-2-20010330(英文)中查看內(nèi)置數(shù)據(jù)類型的層次結(jié)構(gòu)會(huì)有所幫助。
復(fù)雜類型
XML 架構(gòu)允許定義復(fù)雜類型。在 C
中,復(fù)雜類型為結(jié)構(gòu)。例如,要定義與以下 C 結(jié)構(gòu)等價(jià)的數(shù)據(jù)類型:
typedef struct {
string
firstName;
string lastName;
long ageInYears;
float
weightInLbs;
float heightInInches;
}
PERSON;
我們可以在 XML 架構(gòu)中寫入:
<xsd:complexType name="PERSON">
<xsd:sequence>
<xsd:element
name="firstName" type="xsd:string"/>
<xsd:element name="lastName"
type="xsd:string"/>
<xsd:element
name="ageInYears" type="xsd:int"/>
<xsd:element name="weightInLbs"
type="xsd:float"/>
<xsd:element
name="heightInInches" type="xsd:float"/>
</xsd:sequence>
</xsd:complexType>
但是,<complexType> 能表達(dá)的不僅是結(jié)構(gòu)的等價(jià)類型。它可以有除 <sequence> 以外的其他子元素。我可以使用 <all> 而不是 <sequence>:
<xsd:complexType name="PERSON">
<xsd:all>
<xsd:element
name="firstName" type="xsd:string"/>
<xsd:element name="lastName"
type="xsd:string"/>
<xsd:element
name="ageInYears" type="xsd:int"/>
<xsd:element name="weightInLbs"
type="xsd:float"/>
<xsd:element
name="heightInInches" type="xsd:float"/>
</xsd:all>
</xsd:complexType>
這意味著成員變量 <element> 可以以任何順序出現(xiàn),并且每一個(gè)都是可選的。這與 C 結(jié)構(gòu)不完全一樣。
請(qǐng)注意,示例中使用了內(nèi)置數(shù)據(jù)類型 string、int、float。C 中的 string 與 XML 中的 string 相同,float 也相同。但是 C 中的 long 是 XML 中的 int(如上表所示)。
在 WSDL 文件中,復(fù)雜類型(如上面所示的類型)在類型節(jié)中聲明。例如,我可以按以下方式聲明 PERSON 類型,并在消息節(jié)中使用:
<?xml version="1.0" encoding="UTF-8" ?>
<definitions
?>
<types>
<schema
targetNamespace="someNamespace"
xmlns:typens="someNamespace" >
<xsd:complexType
name="PERSON">
<xsd:sequence>
<xsd:element name="firstName"
type="xsd:string"/>
<xsd:element name="lastName"
type="xsd:string"/>
<xsd:element name="ageInYears"
type="xsd:int"/>
<xsd:element name="weightInLbs"
type="xsd:float"/>
<xsd:element name="heightInInches"
type="xsd:float"/>
</xsd:sequence>
</xsd:complexType>
</schema>
</types>
<message name="addPerson">
<part name="person" type="typens:PERSON"/>
</message>
<message
name="addPersonResponse">
<part name="result"
type="xsd:int"/>
</message>
</definitions>
在上例中,第一個(gè)消息名為“addPerson”,它有一個(gè)類型為“PERSON”的 <part>。PERSON 類型在類型節(jié)中聲明為復(fù)雜類型。
如果初始化 MSTK2 SoapClient 時(shí),我們?cè)谕暾?WSDL 文件中使用上述片段,將能夠成功分析該文件。但是,不能發(fā)送對(duì) <addPerson> 的函數(shù)調(diào)用。因?yàn)?SoapClient 本身不知道如何處理復(fù)雜類型,所以需要使用自定義類型映射程序來(lái)處理復(fù)雜類型。MSTK2 文檔有一個(gè)示例應(yīng)用程序,其中包含了自定義類型映射程序。
還有另外一種方式,可以將 <part> 元素與類型聲明相關(guān)聯(lián)。這種方式使用 element 屬性,而不是 type 屬性。在下面的另一個(gè)示例中,我在類型節(jié)中聲明了兩個(gè)元素(“Person”和“Gender”),然后用 element 屬性在“addPerson”<message> 中引用它們。
<?xml version="1.0" encoding="UTF-8" ?>
<definitions
?>
<types>
<schema
targetNamespace="someNamespace"
xmlns:typens="someNamespace" >
<element
name="Person">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="firstName"
type="xsd:string"/>
<xsd:element name="lastName"
type="xsd:string"/>
<xsd:element name="ageInYears"
type="xsd:int"/>
<xsd:element name="weightInLbs"
type="xsd:float"/>
<xsd:element name="heightInInches"
type="xsd:float"/>
</xsd:sequence>
</xsd:complexType>
</element>
<element
name="Gender">
<xsd:simpleType>
<xsd:restriction
base="xsd:string">
<xsd:enumeration value="Male"
/>
<xsd:enumeration value="Female"
/>
</xsd:restriction>
</xsd:simpleType>
</element>
</schema>
</types>
<message name="addPerson">
<part name="who" element="typens:Person"/>
<part name="sex" element="typens:Gender"/>
</message>
<message
name="addPersonResponse">
<part name="result"
type="xsd:int"/>
</message>
</definitions>
類型節(jié)的 Gender <element> 中嵌入了一個(gè)匿名枚舉類型,這種類型可能的取值有“Male”和“Female”。我在“addPerson”<message> 中使用 element 屬性而不是 type 屬性來(lái)引用該元素。
在將特定的類型與 <part> 相關(guān)聯(lián)時(shí),“element”和“type”之間有什么區(qū)別呢?使用“type”屬性,我們可以說(shuō)明一個(gè)能夠使用多種類型的部分(類似 variant);而在使用“element”屬性時(shí)我們不能這樣做。下面的示例說(shuō)明了這一點(diǎn)。
<?xml version="1.0" encoding="UTF-8" ?>
<definitions
?>
<types>
<schema
targetNamespace="someNamespace"
xmlns:typens="someNamespace">
<xsd:complexType
name="PERSON">
<xsd:sequence>
<xsd:element name="firstName"
type="xsd:string"/>
<xsd:element name="lastName"
type="xsd:string"/>
<xsd:element name="ageInYears"
type="xsd:int"/>
<xsd:element name="weightInLbs"
type="xsd:float"/>
<xsd:element name="heightInInches"
type="xsd:float"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType
name="femalePerson">
<xsd:complexContent>
<xsd:extension base="typens:PERSON"
>
<xsd:element name="favoriteLipstick" type="xsd:string"
/>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
<xsd:complexType
name="malePerson">
<xsd:complexContent>
<xsd:extension base="typens:PERSON"
>
<xsd:element name="favoriteShavingLotion" type="xsd:string"
/>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
<xsd:complexType
name="maleOrFemalePerson">
<xsd:choice>
<xsd:element name="fArg" type="typens:femalePerson"
>
<xsd:element name="mArg" type="typens:malePerson"
/>
</xsd:choice>
</xsd:complexType>
</schema>
</types>
<message name="addPerson">
<part name="person"
type="typens:maleOrFemalePerson"/>
</message>
<message
name="addPersonResponse">
<part name="result"
type="xsd:int"/>
</message>
</definitions>
上例還說(shuō)明了擴(kuò)展導(dǎo)出的方式?!癴emalePerson”和“malePerson”都是從“PERSON”導(dǎo)出的。每個(gè)都有一個(gè)額外的元素:“femalePerson”有“favoriteLipstick”,“malePerson”有“favoriteShavingLotion”。使用 <choice> 構(gòu)造將兩個(gè)導(dǎo)出的類型合并到一個(gè)復(fù)雜類型“maleOrFemalePerson”中。最后,在“addPerson”<message> 中,由“person”<part> 引用合并的類型。然后,這個(gè) <part> 或參數(shù)就可以是“femalePerson”或“malePerson”。
數(shù)組
XSD 提供了 <list>
構(gòu)造來(lái)聲明一個(gè)項(xiàng)目用空格分隔的數(shù)組。但是,SOAP 不使用 XSD
列表來(lái)編碼數(shù)組。而是為數(shù)組定義了自己的類型“SOAP-ENC:Array”。下例顯示了如何從這個(gè)類型導(dǎo)出,為一維的整數(shù)數(shù)組聲明一個(gè)類型:
<xsd:complexType name="ArrayOfInt">
<xsd:complexContent>
<xsd:restriction
base="soapenc:Array">
<attribute ref="soapenc:arrayType"
wsdl:arrayType="xsd:int[]"/>
</xsd:restriction>
</xsd:complexContent>
</xsd:complexType>
通過(guò)使用限制導(dǎo)出的方式從 soapenc:Array 導(dǎo)出,來(lái)聲明一個(gè)新的復(fù)雜類型。然后,為該復(fù)雜類型聲明一個(gè)屬性 arrayType。對(duì)“soapenc:arrayType”的引用實(shí)際上通過(guò)以下方式聲明了 arrayType 屬性:
<xsd:attribute name="arrayType" type="xsd:string"/>
然后,wsdl:arrayType 屬性值決定了數(shù)組中每個(gè)成員的類型。數(shù)組項(xiàng)目也可以是復(fù)雜類型。
<xsd:complexType name="ArrayOfPERSON">
<xsd:complexContent>
<xsd:restriction
base="soapenc:Array">
<attribute ref="soapenc:arrayType"
wsdl:arrayType="typens:PERSON[]"/>
</xsd:restriction>
</xsd:complexContent>
</xsd:complexType>
WSDL 要求數(shù)組的類型名稱必須是“ArrayOf”加上數(shù)組中項(xiàng)目的類型。這樣,僅從名稱就可以知道“ArrayOfPERSON”是 PERSON 結(jié)構(gòu)的數(shù)組。下面,我使用 ArrayOfPERSON 來(lái)聲明一個(gè) <message>,以添加多個(gè) PERSON 而不僅僅是一個(gè) PERSON。
<?xml version="1.0" encoding="UTF-8" ?>
<definitions
?>
<types>
<schema
targetNamespace="someNamespace"
xmlns:typens="someNamespace" >
<xsd:complexType
name="PERSON">
<xsd:sequence>
<xsd:element name="firstName"
type="xsd:string"/>
<xsd:element name="lastName"
type="xsd:string"/>
<xsd:element name="ageInYears"
type="xsd:int"/>
<xsd:element name="weightInLbs"
type="xsd:float"/>
<xsd:element name="heightInInches"
type="xsd:float"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType
name="ArrayOfPERSON">
<xsd:complexContent>
<xsd:restriction
base="soapenc:Array">
<attribute ref="soapenc:arrayType"
wsdl:arrayType="typens:PERSON[]"/>
</xsd:restriction>
</xsd:complexContent>
</xsd:complexType>
</schema>
</types>
<message name="addPersons">
<part name="person"
type="typens:ArrayOfPERSON"/>
</message>
<message
name="addPersonResponse">
<part name="result"
type="xsd:int"/>
</message>
</definitions>
<portType> 和 <operation>
元素
portType 抽象定義了一系列操作。portType 中的 operation 元素定義了調(diào)用 portType
中所有方法的語(yǔ)法。每個(gè) operation 元素都聲明了方法的名稱、參數(shù)(使用 <message> 元素)以及每個(gè)參數(shù)的類型(每個(gè)
<message> 中聲明的 <part> 元素)。
一個(gè) WSDL 文檔中可以有多個(gè) <portType> 元素。每個(gè) <portType> 元素組合了一系列相關(guān)的操作,這與 COM 接口組合方法類似。
在一個(gè) <operation> 元素中,最多可以有一個(gè) <output> 元素、一個(gè) <output> 元素和一個(gè) <fault> 元素。這三個(gè)元素中的每一個(gè)都有 name 和 message 屬性。
<output>、<output> 和 <fault> 元素中的 name 屬性的作用是什么呢?它可以用來(lái)區(qū)分兩個(gè)名稱相同的操作(重載)。例如,考慮以下兩個(gè)名稱相同而參數(shù)不同的 C 函數(shù):
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>
直到我撰寫這篇文章時(shí),還沒(méi)有哪種 SOAP 實(shí)現(xiàn)能夠重載操作名稱。對(duì)基于 Java 的客戶端,這很重要。因?yàn)榛?Java 的服務(wù)器使用的接口利用了 Java 的重載特性。而對(duì)基于 COM 的客戶端,這并不重要,因?yàn)?COM 不支持重載。
<binding> 和 <operation>
元素
在綁定節(jié)中完全指定協(xié)議、序列化和編碼。類型、消息和端口類型節(jié)處理抽象的數(shù)據(jù)內(nèi)容,而綁定節(jié)處理數(shù)據(jù)傳輸?shù)奈锢砑?xì)節(jié)。綁定節(jié)將前三節(jié)中的抽象內(nèi)容具體化。
綁定規(guī)范與數(shù)據(jù)和消息聲明的分離意味著參與同種業(yè)務(wù)的服務(wù)提供商可以將一組操作標(biāo)準(zhǔn)化 (portType)。然后,每個(gè)提供商可以通過(guò)提供不同的自定義綁定來(lái)彼此區(qū)分。WSDL 同樣有一個(gè)導(dǎo)入構(gòu)造,這樣抽象定義就能夠放到自己的文件中,而與綁定和服務(wù)節(jié)分開(kāi)。這些文件可以在服務(wù)提供商之間分發(fā),并把抽象定義用作標(biāo)準(zhǔn)。例如,多家銀行可以將一組銀行業(yè)務(wù)操作標(biāo)準(zhǔn)化,在抽象 WSDL 文檔中進(jìn)行準(zhǔn)確說(shuō)明。然后,每個(gè)銀行就可以自由地“自定義”底層協(xié)議、序列化優(yōu)化和編碼。
下面是重載示例 WSDL 的綁定節(jié),在此重復(fù)是為了進(jìn)行更詳細(xì)的討論:
<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> 元素被給定一個(gè)名稱(在本例中是“fooSampleBinding”),使服務(wù)節(jié)中的 <port> 元素能夠引用它。它有一個(gè)“type”屬性引用 <portType>,在本例中是“wsdlns:fooSamplePortType”。第二行是 MSTK2 擴(kuò)展元素 <stk:binding>,它指定了 preferredEncoding“UTF-8”。
<soap:binding> 元素指定了所使用的樣式 (rpc) 和傳送方式。attribute 屬性引用了指定使用 HTTP SOAP 協(xié)議的名稱空間。
有兩個(gè) <operation> 元素具有相同的名稱“foo”。區(qū)分這兩個(gè)操作的是兩個(gè)不同的 <input> 名稱:“foo1”和“foo2”。兩個(gè) <operation> 元素中的 <soap:operation> 元素有相同的“soapAction”屬性(是 URI)。soapAction 屬性是在 SOAP 消息中逐字使用的 SOAP 專用 URI。產(chǎn)生的 SOAP 消息具有 SOAPAction 標(biāo)題,<soap:operation> 元素中的 URI 成為其值。soapAction 屬性是 HTTP 綁定所必需的,但不應(yīng)該出現(xiàn)在非 HTTP 綁定中。其用法在本文中不作詳細(xì)說(shuō)明。在本例中,它可以用來(lái)幫助區(qū)分兩個(gè)“foo”操作。SOAP 1.1 說(shuō)明 soapAction 用于確定消息的“意圖”。它建議服務(wù)器使用此屬性來(lái)路由消息,而不必解析整個(gè)消息。在實(shí)際應(yīng)用中,其用法很多。<soap:operation> 元素還可以包含另外一個(gè)屬性“style”。如果對(duì)于某個(gè)操作,有必要修改在 <soap:binding> 中指定的格式,就可以使用“style”屬性。
<operation> 元素可以包含 <input>、<output> 和 <fault> 元素,它們與端口類型節(jié)中相同的元素對(duì)應(yīng)。上例中僅使用了 <input> 元素。這三個(gè)元素都有可選的“name”屬性,用于區(qū)分同名的操作(如本例所示)。在示例的 <input> 元素中包含了 <soap:body> 元素,它指定產(chǎn)生的 SOAP 消息的 <body> 中包括的內(nèi)容。此元素有以下屬性:
Use
用于指定數(shù)據(jù)是“encoded”還是“l(fā)iteral”?!發(fā)iteral”指產(chǎn)生的
SOAP
消息包含的數(shù)據(jù)按照抽象定義(類型、消息和端口類型節(jié))所指定的方式進(jìn)行格式化。“encoded”指由“encodingStyle”屬性(請(qǐng)參閱下面的說(shuō)明)決定編碼。
Namespace
每個(gè) SOAP
消息正文都可以有自己的名稱空間,以防止名稱沖突。在此屬性中指定的 URI 在產(chǎn)生的 SOAP 消息中被逐字使用。
EncodingStyle
對(duì)于 SOAP 編碼,這應(yīng)該具有 URI
值“http://schemas.xmlsoap.org/soap/encoding”。
文檔樣式綁定
在上一節(jié)中,<soap:binding> 元素有一個(gè)值為“rpc”的
type 屬性。此屬性設(shè)置為“document”時(shí),會(huì)改變線路上消息的序列化。現(xiàn)在消息是文檔傳輸,而不是函數(shù)簽名。在這種綁定中,<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>
該架構(gòu)有兩個(gè)元素(SimpleElement 和 CompositeElement)和一個(gè)聲明的類型 (CompositeType)。唯一聲明的 <message> 元素有四個(gè)部分:p1,是 CompositeType 類型;p2,是 int 類型;p3,是 SimpleElement;p4,是 CompositeElement。下表比較了由以下使用/類型決定的四種綁定:rpc/literal、document/literal、rpc/encoded 和 document/encoded。表格顯示了對(duì)于每一種綁定會(huì)在線路上出現(xiàn)什么。
<operation name="method1" style="rpc"
...>
<input>
<soap:body parts="p1 p2 p3 p4"
use="literal"
namespace="(MessageNS)"/>
</input>
</operation>
在線路上:<soapenv:body...
xmlns:mns="(MessageNS)"
xmlns:stns="(SchemaTNS)">
<mns:method1>
<mns:p1>
<stns:a>123</stns:a>
<stns:b>hello</stns:b>
</mns:p1>
<mns:p2>123</mns:p2>
<mns:p3>
<stns:SimpleElement>
123
</stns:SimpleElement>
</mns:p3>
<mns:p4>
<stns:CompositeElement>
<stns:a>123</stns:a>
<stns:b>hello</stns:b>
</stns:CompositeElement>
</mns:p4>
</mns:method1>
</soapenv:body>
<operation name="method1"
style="document"
...>
<input>
<soap:body parts="p1"
use="literal">
</input>
</operation>
在線路上:
<soapenv:body...
xmlns:stns="(SchemaTNS)">
<stns:a>123</stns:a>
<stns:b>hello</stns:b>
</soapenv:body>
<operation name="method1" style="rpc"
...>
<input>
<soap:body parts="p1 p2" use="encoded"
encoding=
"http://schemas.xmlsoap.org/soap/encoding/"
namespace="(MessageNS)"/>
</input>
</operation>
在線路上:<soapenv:body...
xmlns:mns="(MessageNS)">
<mns:method1>
<p1
TARGET="_self"
HREF="#1"/>
<p2>123</p2>
</mns:method1>
<mns:CompositeType
id="#1">
<a>123</a>
<b>hello</b>
</mns:CompositeType>
</soapenv:body>
<operation name="method1"
style="document"
...>
<input>
<soap:body parts="p3 p4"
use="literal">
</input>
</operation>
在線路上:
<soapenv:body...
xmlns:stns="(SchemaTNS)">
<stns:SimpleElement>
123
</stns:SimpleElement>
<stns:CompositeElement>
<stns:a>123</stns:a>
<stns:b>hello</stns:b>
</stns:CompositeElement>
</soapenv:body>
<operation name="method1"
style="document"
...>
<input>
<soap:body parts="p1 p2" use="encoded"
encoding=
"http://schemas.xmlsoap.org/soap/encoding/"
namespace="(MessageNS)"/>
</input>
</operation>
在線路上:<soapenv:body...
xmlns:mns="(MessageNS)">
<mns:CompositeType>
<a>123</a>
<b>hello</b>
</mns:CompositeType>
<soapenc:int>123</soapenc:int>
</soapenv:body>
<service> 和 <port> 元素
服務(wù)是一組
<port> 元素。每個(gè) <port> 元素以一對(duì)一的方式將位置與 <binding> 相關(guān)聯(lián)。如果有多個(gè)
<port> 元素與同一個(gè) <binding> 相關(guān)聯(lián),那么其他 URL 位置將用作備用項(xiàng)。
一個(gè) WSDL 文檔中可以有多個(gè) <service> 元素。允許多重 <service> 元素有很多用途。其中之一就是按照 URL 目標(biāo)將端口組合在一起。這樣,我就可以用另一個(gè) <service> 重定向我的所有股票報(bào)價(jià)請(qǐng)求,而同時(shí)客戶端程序還能繼續(xù)工作。因?yàn)樵谶@種服務(wù)組合中,與不同服務(wù)關(guān)聯(lián)的協(xié)議都是相同的。多重 <service> 元素的另一種用途是根據(jù)底層協(xié)議對(duì)端口進(jìn)行分類。例如,我可以將所有的 HTTP 端口放在一個(gè) <service> 中,將所有 SMTP 端口放在另一個(gè) <service> 中。然后,我的客戶端就可以搜索與它能處理的協(xié)議匹配的 <service>。
<service name="FOOService">
<port name="fooSamplePort"
binding="fooSampleBinding">
<soap:address
location="http://carlos:8080/fooService/foo.asp"/>
</port>
</service>
在同一個(gè) WSDL 文檔中,<service> 的“name”屬性區(qū)分了各個(gè)服務(wù)。因?yàn)橐粋€(gè)服務(wù)中可能有多個(gè)端口,端口也可以有一個(gè)“name”屬性。
總結(jié)
在本文中,我介紹了 WSDL 文檔中與 SOAP
相關(guān)的最重要的特性。需要指出的是:WSDL 不僅僅能說(shuō)明 HTTP 上的 SOAP。WSDL 完全能夠說(shuō)明使用 HTTP-POST、HTTP-GET、SMTP
等協(xié)議的 SOAP。有了 WSDL,開(kāi)發(fā)者和用戶都更容易使用 SOAP。我相信 WSDL 和 SOAP 結(jié)合將引入一種通過(guò)網(wǎng)絡(luò)利用 Web
服務(wù)的新型應(yīng)用。
WSDL 在其名稱空間中涉及很多 XML 元素。下面的表格總結(jié)了這些元素以及它們的屬性和內(nèi)容:
targetNamespace
xmlns(其他名稱空間)
<message>
<portType>
<binding>
<service>
type
type
parameterOrder
<output>
<fault>
message
message
message
binding
資源:
- WSDL
1.1(英文)
- SOAP 1.1(英文)
- XML 架構(gòu)入門(英文)
- MS SOAP Toolkit 下載網(wǎng)站(英文)
- 用于把 IDL 轉(zhuǎn)換為 WSDL 的工具(英文)
- 免費(fèi)的 Web
服務(wù)資源,包括 WSDL 到 VB 的代理生成器(英文)
- PocketSOAP:SOAP 相關(guān)的組件、工具和源代碼(英文)
- 1重慶OA信息化
- 2成都OA信息化
- 3貴陽(yáng)OA信息化
- 4西安OA信息化
- 5武漢OA信息化
- 6北京OA信息化
- 7廣州OA信息化
- 8石家莊OA信息化
- 9天津OA信息化
- 10沈陽(yáng)OA信息化
- 11長(zhǎng)春OA信息化
- 12福州OA信息化
- 1有生命力的上海OA信息化
- 2企業(yè)上海OA信息化架構(gòu)
- 3軟件服務(wù)時(shí)代的來(lái)臨
- 4推行上海OA信息化,從哪幾個(gè)方面考慮?
- 5微軟基于Web計(jì)算的框架結(jié)構(gòu)分析
- 6上海OA信息化的幾種學(xué)科體系
- 7軟件企業(yè),你真正服務(wù)好你的客戶了嗎?
- 8上海OA信息化落差于金融業(yè)風(fēng)險(xiǎn)管理專家系統(tǒng)
- 9[原創(chuàng)]企業(yè)如何規(guī)劃和實(shí)施上海OA信息化系統(tǒng)
- 10對(duì)高校行政管理辦公自動(dòng)化(OA)問(wèn)題的幾點(diǎn)思考
- 11實(shí)施上海OA信息化的要素分析
- 12上海OA信息化訪問(wèn)單
- 13隱性知識(shí)轉(zhuǎn)化是知識(shí)創(chuàng)新的基礎(chǔ)
- 14導(dǎo)師制與上海OA信息化
- 15使用Microsoft SOAP Toolkit 2.0建立安全Web服務(wù)
- 16上海OA信息化原理的評(píng)論
- 17上海寶康嬰童用品有限公司OA辦公平臺(tái)
- 18上海市兒童醫(yī)院OA辦公自動(dòng)化系統(tǒng)
- 19OA+ERP”整合優(yōu)化銷售訂單管理
- 20借力上海OA信息化 提升客戶服務(wù)
- 21上海保集(集團(tuán))有限公司OA辦公軟件系統(tǒng)平臺(tái) V3.50SP1
- 22個(gè)人上海OA信息化與組織上海OA信息化
- 23上海OA信息化不神秘
- 24OA辦公軟件的作用如何讓企業(yè)認(rèn)可呢
- 25不同業(yè)務(wù)模式下的上海OA信息化策略
- 26上海吉祥航空股份有限公司辦公自動(dòng)化OA系統(tǒng)
- 27上海OA信息化:七分組織 兩分流程 一分技術(shù)
- 28企業(yè)為何要實(shí)施上海OA信息化
- 29建立共享的企業(yè)文化
- 30上海環(huán)境集團(tuán)辦公OA信息系統(tǒng)
成都公司:成都市成華區(qū)建設(shè)南路160號(hào)1層9號(hào)
重慶公司:重慶市江北區(qū)紅旗河溝華創(chuàng)商務(wù)大廈18樓
版權(quán)所有:泛普軟件 渝ICP備14008431號(hào)-2 渝公網(wǎng)安備50011202501700號(hào) 咨詢電話:400-8352-114