創(chuàng)建 WSDL 文檔
Christine 負(fù)責(zé)實際的數(shù)據(jù),而 Larry 負(fù)責(zé)在服務(wù)及其客戶機間傳遞的實際消息。為了處理這些消息,他創(chuàng)建了 WSDL 文檔。
消息
Larry 的第一步是決定服務(wù)將實際執(zhí)行的函數(shù),然后再為服務(wù)定義消息。與部門的其他人商議后,他制訂了函數(shù)及其對應(yīng)消息的列表,我們將在這一部分的其余內(nèi)容中討論這些函數(shù)。
createNewAd
此函數(shù)在廣告結(jié)束日期接受廣告的內(nèi)容,并返回新創(chuàng)建的廣告的內(nèi)容(請參見清單 10 和清單 11)。
清單 10. createNewAdRequest(輸入)
<env:Envelope
xmlns:env="http://schemas.xmlSOAP.org/SOAP/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<env:Body>
<req:createNewAdRequest
xmlns:req="http://daily-moon.com/classifieds/">
<req:content>Vintage 1963 T-Bird...</req:content>
<req:endDate>4/30/07</req:endDate>
</req:createNewAdRequest>
</env:Body>
|
清單 11. createNewAdResponse(輸出)
<env:Envelope
xmlns:env="http://schemas.xmlSOAP.org/SOAP/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<env:Body>
<res:createNewAdResponse
xmlns:res="http://daily-moon.com/classifieds/">
<res:newAdId>1138</res:newAdId>
</res:createNewAdResponse>
</env:Body>
|
editExistingAd
此函數(shù)接受現(xiàn)有廣告,并替換其在數(shù)據(jù)庫中的內(nèi)容。它將返回一個 Boolean 值聲明,指示操作是否成功(請參見清單 12 和清單 13)。
清單 12. editExistingAdRequest(輸入)
<env:Envelope
xmlns:env="http://schemas.xmlSOAP.org/SOAP/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<env:Body>
<req:editExistingAdRequest
xmlns:req="http://daily-moon.com/classifieds/">
<req:ClassifiedAd>
<req:id>1138</req:id>
<req:content>Vintage 1963 T-Bird...</req:content>
<req:startDate>4/1/2007</req:startDate>
<req:endDate>4/30/2007</req:endDate>
<req:ClassifiedAd>
</req:editExistingAdRequest >
</env:Body>
|
清單 13. editExistingAdResponse(輸出)
<env:Envelope
xmlns:env="http://schemas.xmlSOAP.org/SOAP/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<env:Body>
<res:editExistingAdResponse
xmlns:res="http://daily-moon.com/classifieds/">
<res:isOK>true</res:isOK>
</res:editExistingAdResponse>
</env:Body>
|
getExistingAds
此函數(shù)將返回現(xiàn)有 ClassifiedAds
的列表(請參見清單 14 和清單 15)。
清單 14. getExistingAdsRequest(輸入)
<env:Envelope
xmlns:env="http://schemas.xmlSOAP.org/SOAP/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<env:Body>
<req:getExistingAdsRequest
xmlns:req="http://daily-moon.com/classifieds/">
</req:getExistingAdsRequest>
</env:Body>
|
清單 15. getExistingAdsResponse(輸出)
<env:Envelope
xmlns:env="http://schemas.xmlSOAP.org/SOAP/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<env:Body>
<res:getExistingAdsResponse
xmlns:res="http://daily-moon.com/classifieds/">
<res:ClassifiedList>
<res:ClassifiedAd>
<res:id>1138</res:id>
<res:content>Vintage 1963 T-Bird...</res:content>
<res:startDate>4/1/2007</res:startDate>
<res:endDate>4/30/2007</res:endDate>
</res:ClassifiedAd>
<res:ClassifiedAd>
<res:id>2883</res:id>
<res:content>Championship playoff
tickets...</res:content>
<res:startDate>4/1/2007</res:startDate>
<res:endDate>4/30/2007</res:endDate>
</res:ClassifiedAd>
</res:ClassifiedList>
</res:getExistingAdsResponse >
</env:Body>
|
finalizeIssue
此函數(shù)是“僅輸入”的函數(shù),接收最終的發(fā)布日期,而并不返回任何數(shù)據(jù)(請參見清單 16)。
清單 16. finalizeIssueRequest(輸入)
<env:Envelope
xmlns:env="http://schemas.xmlSOAP.org/SOAP/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<env:Body>
<req:finalizeIssueRequest
xmlns:req="http://daily-moon.com/classifieds/">
<req:issueDate>4/10/06</req:issueDate>
</req:FinalizeIssueRequest >
</env:Body>
|
有了這些消息后,Larry 開始著手創(chuàng)建實際的 WSDL 文檔。
創(chuàng)建基本文檔
Larry 首先創(chuàng)建 WSDL 文檔的基本框架(請參見清單 17)。
清單 17. 基本 WSDL 文檔
<wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
targetNamespace="http://ws.apache.org/axis2">
<wsdl:types>
</wsdl:types>
<wsdl:message name="createNewAdRequestMessage">
</wsdl:message>
<wsdl:portType name="ClassifiedServicePortType">
</wsdl:portType>
<wsdl:binding name="ClassifiedServiceBinding">
</wsdl:binding>
<wsdl:service name="ClassifiedService">
</wsdl:service>
</wsdl:definitions>
|
像其所定義的 SOAP 消息一樣,WSDL 也是由 XML 組成的。定義位于 definitions
元素內(nèi),如此處所示。首先看下面,您定義了 service
。service
使用一個特殊的 binding
,而后者是 portType
的一個實現(xiàn)。portType
定義操作,而操作由 messages
組成。消息中包含由 types
部分中定義的 XML 組成。
definitions
元素定義兩個命名空間。第一個使用前綴 wsdl
:,為組成 WSDL 的實際元素提供命名空間。第二個 targetNamespace
定義 WSDL 定義的項所屬的命名空間。
Larry 首先定義的是類型。
定義類型
Larry 拿到 Christine 提供的定義,并將其放入 types
元素中,從而在文檔內(nèi)創(chuàng)建了一個新模式,如清單 18 中所示。
清單 18. 定義類型
<wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:ns1="http://org.apache.axis2/xsd"
targetNamespace="http://ws.apache.org/axis2">
<wsdl:types>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://org.apache.axis2/xsd"
elementFormDefault="unqualified"
attributeFormDefault="unqualified">
<xs:element type="ns1:ClassifiedAd" name="ClassifiedAd" />
<xs:complexType name="ClassifiedAd">
<xs:sequence>
<xs:element type="xs:int" name="id" />
<xs:element type="xs:string" name="content" />
<xs:element type="xs:string" name="endDate" />
<xs:element type="xs:string" name="startDate" />
</xs:sequence>
</xs:complexType>
<xs:element type="ns1:ClassifiedList" name="ClassifiedList" />
<xs:complexType name="ClassifiedList">
<xs:sequence>
<xs:element minOccurs="0" type="ns1:ClassifiedAd"
name="ClassifiedAd" maxOccurs="unbounded" />
</xs:sequence>
</xs:complexType>
<xs:element name="createNewAdRequest">
<xs:complexType>
<xs:sequence>
<xs:element type="xs:string" name="content" />
<xs:element type="xs:string" name="endDate" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="createNewAdResponse">
<xs:complexType>
<xs:sequence>
<xs:element type="xs:int" name="newAdId" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="editExistingAdRequest">
<xs:complexType>
<xs:sequence>
<xs:element type="ns1:ClassifiedAd"
name="ClassifiedAd" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="editExistingAdResponse">
<xs:complexType>
<xs:sequence>
<xs:element type="xs:boolean" name="isOK" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="getExistingAdsRequest">
<xs:complexType />
</xs:element>
<xs:element name="getExistingAdsResponse">
<xs:complexType>
<xs:sequence>
<xs:element type="ns1:ClassifiedList"
name="ClassifiedList" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="finalizeIssueRequest">
<xs:complexType>
<xs:sequence>
<xs:element type="xs:string" name="issueDate" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
</wsdl:types>
</wsdl:definitions>
|
從代碼的起始處開始,請注意我們有兩個命名空間部分。第一個位于 schema
元素本身中。此處 Larry 定義了兩個命名空間。第一個命名空間是 XML Schema 命名空間,使用前綴 xs
:。第二個命名空間是 targetNamespace
,定義模式創(chuàng)建的定義所屬的命名空間。也就是說,當(dāng)?shù)诙€版本創(chuàng)建名為 ClassifiedAd
的 complexType
時,該定義屬于命名空間 http://org.apache.axis2/xsd
。不過,為了引用該命名空間,Larry 需要創(chuàng)建另一個別名。您可以在以 ns1
: 為前綴的 definitions 元素上看到此別名。(Larry 可以直接將該定義放在 schema 元素上,但他稍后需要在 schema 元素外使用此定義。)后面兩個屬性 elementFormDefault
和 attributeFormDefault
表示元素和屬性是否應(yīng)該有命名空間前綴。
前面四個定義來自 Christine 提供給 Larry 的定義,但其余定義用于定義 Larry 前面創(chuàng)建的消息。
有關(guān)命名空間的說明
和許多編程語言一樣,在 XML 中,經(jīng)常有必要為各種元素和屬性指定“命名空間”。這樣就能方便地對具有相同名稱但用途不同(來源也可能不同)的元素進行區(qū)分。XML 通過 URI 引用命名空間。例如,XML 模式命名空間為 http://www.w3.org/2001/XMLSchema
。不過,為了方便起見,還為其分配了一個別名(或前綴)。例如,此處的模式命名空間的前綴為 xs:
。請記住,別名只是一個別名而已,重要的是 URI。因此,屬于 ns1:
命名空間的元素或?qū)傩砸彩悄J降?targetNamespace
的一部分。
創(chuàng)建消息
定義了各個類型后,Larry 就可以定義將在 SOAP 信封中來回傳遞的消息了(請參見清單 19)。
清單 19. 創(chuàng)建消息
<wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:ns1="http://org.apache.axis2/xsd"
targetNamespace="http://ws.apache.org/axis2">
<wsdl:types>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://org.apache.axis2/xsd"
elementFormDefault="unqualified"
attributeFormDefault="unqualified">
...
<xs:element name="createNewAdRequest">
<xs:complexType>
<xs:sequence>
<xs:element type="xs:string" name="content" />
<xs:element type="xs:string" name="endDate" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="createNewAdResponse">
<xs:complexType>
<xs:sequence>
<xs:element type="xs:int" name="newAdId" />
</xs:sequence>
</xs:complexType>
</xs:element>
...
</xs:schema>
</wsdl:types>
<wsdl:message name="createNewAdRequestMessage">
<wsdl:part name="part1" element="ns1:createNewAdRequest"
/>
</wsdl:message>
<wsdl:message name="createNewAdResponseMessage">
<wsdl:part name="part1" element="ns1:createNewAdResponse" />
</wsdl:message>
<wsdl:message name="getExistingAdsResponseMessage">
<wsdl:part name="part1" element="ns1:getExistingAdsResponse" />
</wsdl:message>
<wsdl:message name="editExistingAdRequestMessage">
<wsdl:part name="part1" element="ns1:editExistingAdRequest" />
</wsdl:message>
<wsdl:message name="getExistingAdsRequestMessage">
<wsdl:part name="part1" element="ns1:getExistingAdsRequest" />
</wsdl:message>
<wsdl:message name="editExistingAdResponseMessage">
<wsdl:part name="part1" element="ns1:editExistingAdResponse" />
</wsdl:message>
<wsdl:message name="finalizeIssueRequestMessage">
<wsdl:part name="part1" element="ns1:finalizeIssueRequest" />
</wsdl:message>
<wsdl:portType name="ClassifiedServicePortType">
</wsdl:portType>
<wsdl:binding name="ClassifiedServiceBinding">
</wsdl:binding>
<wsdl:service name="ClassifiedService">
</wsdl:service>
</wsdl:definitions>
|
每個消息都具有一個 name
,以便稍后對其進行引用。在每個消息內(nèi),您可以定義一個或多個 part
。請注意,WSDL 2.0 僅允許每個 message
包含一個 part
,因此 Larry 此處嚴(yán)格遵循了此約定。
每個 part
都有一個 name
,而由 element
的名稱組成該 part
。元素名稱將反過來引用在 types
元素中定義的類型。請注意,元素的名稱以 ns1:
為前綴,即與模式的 targetNamespace
匹配的命名空間前綴。也就是說,當(dāng) Larry 創(chuàng)建 createNewAdResponse
的定義時,該定義進入了 http://org.apache.axis2/xsd namespace
中,由于前綴 ns1:
也引用此命名空間,因此現(xiàn)在可以使用該前綴引用此命名空間。
定義接口 (portType)
消息本身并不會帶來什么好處,因此 Larry 需要將其與特定的操作關(guān)聯(lián)。這些 operation
屬于 portType
的一部分。portType
僅包含定義,而不包含實現(xiàn)。就這個意義而言,它與接口很相似。事實上,在 WSDL 2.0 中,portType
的名稱已更改為 interface
。Larry 為每個功能創(chuàng)建了一個操作(請參見清單 20)。
清單 20. 添加操作
<wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:tns=http://ws.apache.org/axis2
xmlns:ns1="http://org.apache.axis2/xsd"
targetNamespace="http://ws.apache.org/axis2">
<wsdl:types>
...
</wsdl:types>
<wsdl:message name="createNewAdRequestMessage">
<wsdl:part name="part1" element="ns1:createNewAdRequest" />
</wsdl:message>
<wsdl:message name="createNewAdResponseMessage">
<wsdl:part name="part1" element="ns1:createNewAdResponse" />
</wsdl:message>
...
<wsdl:message name="finalizeIssueRequestMessage">
<wsdl:part name="part1" element="ns1:finalizeIssueRequest" />
</wsdl:message>
<wsdl:portType name="ClassifiedServicePortType">
<wsdl:operation name="finalizeIssue">
<wsdl:input message="tns:finalizeIssueRequestMessage" />
</wsdl:operation>
<wsdl:operation name="createNewAd">
<wsdl:input message="tns:createNewAdRequestMessage" />
<wsdl:output message="tns:createNewAdResponseMessage" />
</wsdl:operation>
<wsdl:operation name="editExistingAd">
<wsdl:input message="tns:editExistingAdRequestMessage" />
<wsdl:output message="tns:editExistingAdResponseMessage" />
</wsdl:operation>
<wsdl:operation name="getExistingAds">
<wsdl:input message="tns:getExistingAdsRequestMessage" />
<wsdl:output message="tns:getExistingAdsResponseMessage" />
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="ClassifiedServiceBinding">
</wsdl:binding>
<wsdl:service name="ClassifiedService">
</wsdl:service>
</wsdl:definitions>
|
Larry 創(chuàng)建了兩種類型的消息。一類消息(如 finalizeIssue
)是“僅輸入”的操作,因為它僅具有輸入消息。消息 finalizeIssueRequest
是前面定義的,和前面一樣,我們將創(chuàng)建一個新前綴 tns:
來引用其所屬的命名空間。
第二種操作類型是請求/響應(yīng)操作,如 createNewAd
。在這種情況下,Larry 將同時定義輸入和輸出消息。
定義綁定
如果 portType
像接口,則 binding
為該接口的實現(xiàn)(請參見清單 21)。
清單 21. 創(chuàng)建綁定
<wsdl:definitions
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:tns="http://ws.apache.org/axis2"
xmlns:ns1="http://org.apache.axis2/xsd"
targetNamespace="http://ws.apache.org/axis2">
<wsdl:types>
</wsdl:types>
<wsdl:message name="createNewAdRequestMessage">
<wsdl:part name="part1" element="ns1:createNewAdRequest" />
</wsdl:message>
...
<wsdl:portType name="ClassifiedServicePortType">
<wsdl:operation name="finalizeIssue">
<wsdl:input message="tns:finalizeIssueRequestMessage" />
</wsdl:operation>
<wsdl:operation name="createNewAd">
<wsdl:input message="tns:createNewAdRequestMessage" />
<wsdl:output message="tns:createNewAdResponseMessage" />
</wsdl:operation>
<wsdl:operation name="editExistingAd">
<wsdl:input message="tns:editExistingAdRequestMessage" />
<wsdl:output message="tns:editExistingAdResponseMessage" />
</wsdl:operation>
<wsdl:operation name="getExistingAds">
<wsdl:input message="tns:getExistingAdsRequestMessage" />
<wsdl:output message="tns:getExistingAdsResponseMessage" />
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="ClassifiedServiceBinding"
type="tns:ClassifiedServicePortType">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http"
style="document" />
<wsdl:operation name="createNewAd">
<soap:operation soapAction="createNewAd" style="document" />
<wsdl:input>
<soap:body use="literal"
namespace="http://daily-moon.com/classifieds" />
</wsdl:input>
<wsdl:output>
<soap:body use="literal"
namespace="http://daily-moon.com/classifieds" />
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="finalizeIssue">
<soap:operation soapAction="finalizeIssue" style="document" />
<wsdl:input>
<soap:body use="literal"
namespace="http://daily-moon.com/classifieds" />
</wsdl:input>
</wsdl:operation>
<wsdl:operation name="editExistingAd">
<soap:operation soapAction="editExistingAd" style="document" />
<wsdl:input>
<soap:body use="literal"
namespace="http://daily-moon.com/classifieds" />
</wsdl:input>
<wsdl:output>
<soap:body use="literal"
namespace="http://daily-moon.com/classifieds" />
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="getExistingAds">
<soap:operation soapAction="getExistingAds" style="document" />
<wsdl:input>
<soap:body use="literal"
namespace="http://daily-moon.com/classifieds" />
</wsdl:input>
<wsdl:output>
<soap:body use="literal"
namespace="http://daily-moon.com/classifieds" />
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="ClassifiedService">
</wsdl:service>
</wsdl:definitions>
|
首先,請注意綁定 type
引用 Larry 已經(jīng)創(chuàng)建的 ClassifiedServicePortType
。其次,請注意添加了 soap:
命名空間。此 binding
用于 HTTP 上的 SOAP 消息,如 soap:binding
元素中所示。請注意 transport
屬性。(尚不用擔(dān)心 style
,我們將在接下來的部分中對其進行討論。)
對于共享其在 portType
中的名稱的每個操作,Larry 現(xiàn)在都要添加一個 soap:operation
元素。此元素執(zhí)行兩個操作。根據(jù)此元素的說明,第一個操作實際上是 SOAP 操作。第二個操作用于指定 soapAction
,此為在實際 SOAP 消息前發(fā)送的 HTTP Header。服務(wù)器可以使用此 Header 來將請求路由到相應(yīng)的操作。
請注意,soapAction
始終有一定的問題,雖然在 WSDL 1.1 是可選的,但已經(jīng)完全從 WSDL 2.0 中刪除了。
每個操作還定義 input
和 output
消息(或者,使用僅輸入的消息時,只定義 input
消息),但現(xiàn)在 Larry 還將添加特定的 SOAP 信息。同樣,不用擔(dān)心 use
屬性;我們也將在稍后討論此屬性。此元素還為有效負(fù)載的內(nèi)容定義命名空間。
定義服務(wù)
定義了接口和綁定后,接下來就要定義服務(wù)了(請參見清單 22)。
清單 22. 定義服務(wù)
...
<wsdl:binding name="ClassifiedServiceBinding"
type="tns:ClassifiedServicePortType">
...
</wsdl:binding>
<wsdl:service name="ClassifiedService">
<wsdl:port name="ClassifiedServicePort"
binding="tns:ClassifiedServiceBinding">
<soap:address location=
"http://127.0.0.1:8080/axis2/services/ClassifiedService" />
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
|
service
可以具有多個端點,每個端點都由其自己對應(yīng)的 port
元素進行定義。port
元素與特定綁定對應(yīng),包括有關(guān)如何訪問此綁定的信息。在本例中,Larry 指定可以通過 SOAP 在以下位置訪問該端口:http://127.0.0.1:8080/axis2/services/ClassifiedService
。
為服務(wù)添加注釋
定義了服務(wù)后,還要進行一個步驟。雖然是可選的,但真的應(yīng)該進行此步驟。WSDL 允許您向 WSDL 文檔中的任何元素添加 documentation 元素。清單 23 提供了一個示例。
清單 23. 為服務(wù)添加注釋
...
<wsdl:portType name="ClassifiedServicePortType">
<wsdl:document>The finalizeIssue operation is an "in-only"
operation that tells the system not to accept any
more ads for a particular date.</wsdl:document>
<wsdl:operation name="finalizeIssue">
<wsdl:input message="tns:finalizeIssueRequestMessage" />
</wsdl:operation>
...
|
有關(guān) WSDL 的知識還有很多,但上面這些是基本的內(nèi)容。不過,繼續(xù)學(xué)習(xí)本教程之前,讓我們了解一些您可能遇到的更為復(fù)雜的情況。
綁定 SOAP over HTTP 之外的其他協(xié)議
盡管 WSDL 的最常見用法是定義 SOAP over HTTP,但卻不是指定 Web 服務(wù)的唯一方法。例如,Larry 可以創(chuàng)建一個使用 SOAP over E-mail 的綁定,并僅為 finalizeIssue
操作啟用它(請參見清單 24)。
清單 24. 添加其他綁定
...
<wsdl:binding name="ClassifiedServiceEmailBinding"
type="tns:ClassifiedServicePortType">
<soap:binding style="document" transport="http://example.com/smtp"/>
<wsdl:operation name="finalizeIssue">
<wsdl:input message="tns:finalizeIssueRequestMessage">
<soap:body parts="body" use="literal"/>
</wsdl:input>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="ClassifiedService">
<wsdl:port name="ClassifiedServicePort"
binding="tns:ClassifiedServiceBinding">
<soap:address location=
"http://127.0.0.1:8080/axis2/services/ClassifiedService" />
</wsdl:port>
<wsdl:port name="ClassifiedServiceEmailPort"
binding="tns:ClassifiedServiceEmailBinding">
<soap:address location="mailto:finalizeIssue@daily-moon.com" />
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
|
此處 Larry 添加了第二個綁定 ClassifiedServiceEmailBinding
。和 ClassifiedServiceBinding
綁定一樣,此綁定基于 ClassifiedServicePortType portType
。不過,在本例中,他使用的是 SMTP(用于發(fā)送電子郵件的協(xié)議),而不是 HTTP。他可以隨后向服務(wù)添加第二個端口,使其基于新綁定,使用電子郵件 URL 作為地址,而不是 HTTP URL。您可以為單個服務(wù)創(chuàng)建任意多的端口。
SOAP 和 Mime
另一個與此解決方案有關(guān)的主題還不甚明顯,即將 SOAP 用于附件。由于消息不僅是 XML 文檔,您應(yīng)該如何使用 WSDL 進行指定呢?這個問題的答案涉及到一個事實,即消息是使用“多部分 MIME”發(fā)送的。幸運的是,您可以在 WSDL 文檔中指定這一點。例如,Larry 希望指定一個操作,通過此操作,用戶可以編輯從廣告的 PDF 校樣獲得的現(xiàn)有廣告(請參見清單 25)。
>清單 25. 指定包含多個部分的消息
...
<wsdl:operation name="editExistingAd">
<soap:operation soapAction="editExistingAd"
style="document" />
<wsdl:input>
<soap:body use="literal"
namespace="http://daily-moon.com/classifieds" />
</wsdl:input>
<wsdl:output>
<soap:body use="literal"
namespace="http://daily-moon.com/classifieds" />
<mime:multipartRelated>
<mime:part>
<soap:body parts="body" use="literal"/>
</mime:part>
<mime:part>
<mime:content part="docs" type="text/html"/>
</mime:part>
<mime:part>
<mime:content part="proof" type="image/gif"/>
<mime:content part="proof" type="image/jpeg"/>
</mime:part>
</mime:multipartRelated>
</wsdl:output>
...
|
在本例中,返回消息包含 SOAP、一個 HTML 文檔和兩個圖像文件。
WSDL 2.0 中包含的新內(nèi)容
在此部分中,我盡力說明 WSDL 2.0 與 WSDL 1.1 的一些不同之處,如從可能出現(xiàn)多個 portType
的情況變?yōu)閱蝹€ interface
,以及 message
不再能包含多個部分等。其他方面也有一定程度的調(diào)整。
有多個因素促成了這些更改,但大部分更改的目的都是為了提高互操作性——不符合 WS-I 基本概要 (WS-I Basic Profile) 的構(gòu)造通常都禁止使用——或為了更方便地將 WSDL 與經(jīng)過擴展的 SOAP 規(guī)范一起使用。例如,WSDL 2.0 更多使用的是“組件”模型,此模型更適合與 WS-Choreography 等規(guī)范的要求進行集成。
另一個更改與“消息交換模式”的正式規(guī)范有關(guān)。WSDL 2.0 不依賴于用戶確定是同時存在輸入和輸出還是僅有一個輸入消息,它允許您具體地聲明所使用的模式(請參見清單 26)。
清單 26. 指定消息交換模式
...
<wsdl:operation name="finalizeIssue"
pattern=http://www.w3.org/2006/01/wsdl/in-only">
<wsdl:input message="tns:finalizeIssueRequestMessage" />
</wsdl:operation>
<wsdl:operation name="createNewAd"
pattern="http://www.w3.org/2006/01/wsdl/in-out">
<wsdl:input message="tns:createNewAdRequestMessage" />
<wsdl:output message="tns:createNewAdResponseMessage" />
</wsdl:operation>
...
|
現(xiàn)在讓我們深入了解一下 WSDL 樣式。
posted on 2006-12-29 19:09
SIMONE 閱讀(1629)
評論(0) 編輯 收藏 所屬分類:
AXIS 、
JAVA