WSDL樣式詳解

Web 服務是通過WSDL文檔來描述的。WSDL綁定描述瞭如何把服務綁定到消息傳遞協議(特別是SOAP消息傳遞協議)。WSDL SOAP綁定style描述了服務調用方式,即遠程過程調用rpc (Remote Procedure Call)方式或文檔document方式use定義了類型是編碼encoded 方式還是文字literal方式

創建綁定時,可以選擇 document 樣式或 rpc樣式。二者均具有自己的優點和缺點。使用 rpc樣式時,要執行的方法的名稱同時也是有效負載的根元素的名稱。

WSDL調用服務提供了6種樣式:

1rpc/encoded

2rpc/literal

3document /encoded

4document /literal

5document/literal/wrapped

6document/encoded/wrapped

 

1.       rpc/encoded樣式

SOAP消息定義實際類型信息。

WSDL 文檔樣例:

<wsdl:types>

 <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"

         targetNamespace="http://org.apache.axis2/xsd"

         elementFormDefault="unqualified"

         attributeFormDefault="unqualified">

...

 </xs:schema>

</wsdl:types>

<wsdl:message name="createNewAdRequest">

 <wsdl:part name="content" type="xsd:string" />

 <wsdl:part name="endDate" type="xsd:string" />

</wsdl:message>

...

<wsdl:portType name="ClassifiedServicePortType">

 <wsdl:operation name="createNewAd">

    <wsdl:input message="tns:createNewAdRequest" />

    <wsdl:output message="tns:createNewAdResponse" />

 </wsdl:operation>

...

</wsdl:portType>

<wsdl:binding name="ClassifiedServiceBinding"

 type="tns:ClassifiedServicePortType">

 <soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="rpc" />

 <wsdl:operation name="createNewAd">

    <soap:operation soapAction="createNewAd" style="rpc"/>

    <wsdl:input>

      <soap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"

 namespace="http://ws.apache.org/axis2"/>

    </wsdl:input>

    <wsdl:output>

      <soap:body use="literal" namespace="http://ws.apache.org/axis2" />

    </wsdl:output>

 </wsdl:operation>

...

</wsdl:binding>

...

SOAP請求報文樣例:

<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: createNewAd  xmlns:req="http://daily-moon.com/classifieds/">

         <req:content xsi:type="xs:string">Vintage 1963 T-Bird...</req:content>

         <req:endDate xsi:type="xs:string">4/30/07</req:endDate>

     </req: createNewAd >

   </env:Body>

</env:Envelope>

優點:

l        WSDL 基本達到了儘可能地簡單易懂的要求。

l        操作名出現在消息中,這樣接收者就可以很輕鬆地把消息發送到方法的實現。

缺點:

l        類型編碼信息(比如 xsi:type="xsd:int" )通常就是降低吞吐量性能的開銷。

l        不能簡單地檢驗此消息的有效性,因爲只有 <req:content xsi:type="xs:string">Vintage 1963 T-Bird...</req:content> 行包含在 Schema 中定義的內容;其餘的 soap:body 內容都來自 WSDL 定義。

2.       rpc/literal樣式

WSDL樣例:

...

<wsdl:types>

 <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"

         targetNamespace="http://org.apache.axis2/xsd"

         elementFormDefault="unqualified"

         attributeFormDefault="unqualified">

...

 </xs:schema>

</wsdl:types>

<wsdl:message name="createNewAdRequest">

 <wsdl:part name="content" type="xsd:string"/>

 <wsdl:part name="endDate "type="xsd:string"/>

</wsdl:message>

...

<wsdl:portType name="ClassifiedServicePortType">

 <wsdl:operation name="createNewAd">

    <wsdl:input message="tns:createNewAdRequest" />

    <wsdl:output message="tns:createNewAdResponseMessage" />

 </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="rpc"/>

    <wsdl:input>

      <soap:body use="literal" namespace="http://ws.apache.org/axis2"/>

    </wsdl:input>

    <wsdl:output>

      <soap:body use="literal" namespace="http://ws.apache.org/axis2" />

    </wsdl:output>

 </wsdl:operation>

...

</wsdl:binding>

...

SOAP請求報文樣例:

<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: createNewAd  xmlns:req="http://daily-moon.com/classifieds/">

       <req:content>Vintage 1963 T-Bird</req:content>

       <req:endDate>4/30/2007</req:endDate>

    </req: createNewAd >

  </env:Body>

</env:Envelope>

優點:

l        WSDL 還是基本達到了儘可能地簡單易懂的要求。

l        操作名仍然出現在消息中。

l        去掉了類型編碼。

缺點:

l        仍然不能簡單地檢驗此消息的有效性。因爲只有 < req:content > <req:endDate>行中包含定義在 Schema 中的內容;soap:body 內容的其餘部分來自於 WSDL 定義。

3.       document/encoded樣式

此種方式很少使用。

WSDL樣例:

...

<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="xs:string" name="content" />

    <xs:element type="xs:string" name="endDate" />

...

 </xs:schema>

</wsdl:types>

<wsdl:message name="createNewAdRequestMessage">

 <wsdl:part name="part1" element="ns1:content" />

 <wsdl:part name="part2" element="ns1:endDate" />

</wsdl:message>

...

<wsdl:portType name="ClassifiedServicePortType">

 <wsdl:operation name="createNewAd">

    <wsdl:input message="tns:createNewAdRequestMessage" />

    <wsdl:output message="tns:createNewAdResponseMessage" />

 </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="encoded" />

    </wsdl:input>

    <wsdl:output>

      <soap:body use=" encoded" />

    </wsdl:output>

 </wsdl:operation>

...

</wsdl:binding>

SOAP請求報文樣例:

<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:content xsi:type="xs:string">Vintage 1963 T-Bird</req:content>

       <req:endDate xsi:type="xs:string">4/30/07</req:endDate>

 </env:Body>

</env:Envelope>

4.       document/literal樣式

WSDL樣例:

...

<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="xs:string" name="content" />

    <xs:element type="xs:string" name="endDate" />

...

 </xs:schema>

</wsdl:types>

<wsdl:message name="createNewAdRequestMessage">

 <wsdl:part name="part1" element="ns1:content" />

 <wsdl:part name="part2" element="ns1:endDate" />

</wsdl:message>

...

<wsdl:portType name="ClassifiedServicePortType">

 <wsdl:operation name="createNewAd">

    <wsdl:input message="tns:createNewAdRequestMessage" />

    <wsdl:output message="tns:createNewAdResponseMessage" />

 </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" />

    </wsdl:input>

    <wsdl:output>

      <soap:body use="literal" />

    </wsdl:output>

 </wsdl:operation>

...

</wsdl:binding>

SOAP請求報文樣例:

<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:content>Vintage 1963 T-Bird...</req:content>

       <req:endDate>4/30/07</req:endDate>

</env:Body>

</env:Envelope>

優點:

l        沒有編碼信息

l        可以在最後用任何 XML 檢驗器檢驗此消息的有效性。 soap:body中每項內容都定義在 Schema 中。

缺點:

l        SOAP 消息中缺少操作名。而如果沒有操作名,發送就可能比較困難,並且有時變得不可能。

5.       document/literal/wrapped樣式

WSDL樣例:

...

<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:schema>

</wsdl:types>

<wsdl:message name="createNewAdRequestMessage">

 <wsdl:part name="part1" element="ns1:createNewAdRequest" />

</wsdl:message>

...

<wsdl:portType name="ClassifiedServicePortType">

 <wsdl:operation name="createNewAd">

    <wsdl:input message="tns:createNewAdRequestMessage" />

    <wsdl:output message="tns:createNewAdResponseMessage" />

 </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://ws.apache.org/axis2" />

    </wsdl:input>

    <wsdl:output>

      <soap:body use="literal" namespace="http://ws.apache.org/axis2" />

    </wsdl:output>

 </wsdl:operation>

...

</wsdl:binding>

...

SOAP請求報文樣例:

<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>

</env:Envelope>

注意此時SOAP Body中第一個元素的名稱並不是操作的名稱,而是Schema中的元素的名稱。此時Schema中的元素的名稱可以與操作名相同,也可以不同。如果取相同則是一種將操作名放入SOAP消息的巧妙方式。

SOAP 消息看起來非常類似於 RPC/literal SOAP 消息。您可能會說,它看起來與 RPC/literal SOAP 消息是完全一樣的,不過,這兩種消息之間存在着微妙的區別。在 RPC/literal SOAP 消息中, <soap:body> 下的< req:createNewAd> 根元素是操作的名稱。在document/literal/wrapped SOAP 消息中, < req:createNewAdRequest > 子句是單個輸入消息的組成部分引用的元素的名稱。

document/literal/wrapped樣式的特徵有:

l        輸入消息只有一個組成部分。

l        該部分就是一個元素。

l        該元素有與操作相同的名稱。

l        該元素的複雜類型沒有屬性。

優點:

l        沒有編碼信息。

l        出現在 soap:body 中的每項內容都是由 Schema 定義的,可以很容易地檢驗此消息的有效性。

l        方法名又出現在 SOAP 消息中。

缺點:

l        WSDL 較爲複雜。

6.       document/encoded/wrapped樣式

此種方式很少使用

WSDL樣例:

...

<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:schema>

</wsdl:types>

<wsdl:message name="createNewAdRequestMessage">

 <wsdl:part name="part1" element="ns1:createNewAdRequest" />

</wsdl:message>

...

<wsdl:portType name="ClassifiedServicePortType">

 <wsdl:operation name="createNewAd">

   <wsdl:input message="tns:createNewAdRequestMessage" />

    <wsdl:output message="tns:createNewAdResponseMessage" />

 </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="encoded" namespace="http://ws.apache.org/axis2" />

    </wsdl:input>

    <wsdl:output>

      <soap:body use="encoded" namespace="http://ws.apache.org/axis2" />

    </wsdl:output>

 </wsdl:operation>

...

</wsdl:binding>

...

SOAP請求報文樣例:

<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 xsi:type="xs:string">Vintage 1963 T-Bird...</req:content>

         <req:endDate xsi:type="xs:string">4/30/07</req:endDate>

     </req:createNewAdRequest>

   </env:Body>

</env:Envelope>

附錄:WSDL1.1規範中的SOAP Binding 信息( 對其中關鍵部分進行了中文翻譯 )

SOAP Binding

WSDL includes a binding for SOAP 1.1 endpoints, which supports the specification of the following protocol specific information:

  • An indication that a binding is bound to the SOAP 1.1 protocol
  • A way of specifying an address for a SOAP endpoint.
  • The URI for the SOAPAction HTTP header for the HTTP binding of SOAP
  • A list of definitions for Headers that are transmitted as part of the SOAP Envelope

This binding grammar it is not an exhaustive specification since the set of SOAP bindings is evolving. Nothing precludes additional SOAP bindings to be derived from portions of this grammar. For example:

  • SOAP bindings that do not employ a URI addressing scheme may substitute another addressing scheme by replacing the soap:address element defined in section 3.8.
  • SOAP bindings that do not require a SOAPAction omit the soapAction attribute defined in section 3.4.

3.1 SOAP Examples

In the following example, a SubscribeToQuotes SOAP 1.1 one-way message is sent to a StockQuote service via a SMTP binding. The request takes a ticker symbol of type string, and includes a header defining the subscription URI.

Example 3. SOAP binding of one-way operation over SMTP using a SOAP Header

<?xml version="1.0"?>
<definitions name="StockQuote"
          targetNamespace="http://example.com/stockquote.wsdl"
          xmlns:tns="http://example.com/stockquote.wsdl"
          xmlns:xsd1="http://example.com/stockquote.xsd"
          xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
          xmlns="http://schemas.xmlsoap.org/wsdl/">
 
    <message name="SubscribeToQuotes">
        <part name="body" element="xsd1:SubscribeToQuotes"/>
        <part name="subscribeheader" element="xsd1:SubscriptionHeader"/>
    </message>
 
    <portType name="StockQuotePortType">
        <operation name="SubscribeToQuotes">
           <input message="tns:SubscribeToQuotes"/>
        </operation>
    </portType>
 
    <binding name="StockQuoteSoap" type="tns:StockQuotePortType">
        <soap:binding style="document" transport="http://example.com/smtp"/>
        <operation name="SubscribeToQuotes">
           <input message="tns:SubscribeToQuotes">
               <soap:body parts="body" use="literal"/>
               <soap:header message="tns:SubscribeToQuotes" part="subscribeheader" use="literal"/>
           </input>
        </operation>
    </binding>
 
    <service name="StockQuoteService">
        <port name="StockQuotePort" binding="tns:StockQuoteSoap">
           <soap:address location="mailto:[email protected]"/>
        </port>
    </service>
 
    <types>
        <schema targetNamespace="http://example.com/stockquote.xsd"
               xmlns="http://www.w3.org/2000/10/XMLSchema">
           <element name="SubscribeToQuotes">
               <complexType>
                   <all>
                       <element name="tickerSymbol" type="string"/>
                   </all>
               </complexType>
           </element>
           <element name="SubscriptionHeader" type="uriReference"/>
        </schema>
    </types>
</definitions>

This example describes that a GetTradePrice SOAP 1.1 request may be sent to a StockQuote service via the SOAP 1.1 HTTP binding. The request takes a ticker symbol of type string, a time of type timeInstant, and returns the price as a float in the SOAP response.

Example 4. SOAP binding of request-response RPC operation over HTTP

<?xml version="1.0"?>
<definitions name="StockQuote"
          targetNamespace="http://example.com/stockquote.wsdl"
          xmlns:tns="http://example.com/stockquote.wsdl"
          xmlns:xsd="http://www.w3.org/2000/10/XMLSchema"
          xmlns:xsd1="http://example.com/stockquote.xsd"
          xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
          xmlns="http://schemas.xmlsoap.org/wsdl/">
 
    <message name="GetTradePriceInput">
        <part name="tickerSymbol" element="xsd:string"/>
        <part name="time" element="xsd:timeInstant"/>
    </message>
 
    <message name="GetTradePriceOutput">
        <part name="result" type="xsd:float"/>
    </message>
 
    <portType name="StockQuotePortType">
        <operation name="GetTradePrice">
           <input message="tns:GetTradePriceInput"/>
           <output message="tns:GetTradePriceOutput"/>
        </operation>
    </portType>
 
    <binding name="StockQuoteSoapBinding" type="tns:StockQuotePortType">
        <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
        <operation name="GetTradePrice">
           <soap:operation soapAction="http://example.com/GetTradePrice"/>
           <input>
               <soap:body use="encoded" namespace="http://example.com/stockquote"
                          encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
           </input>
           <output>
               <soap:body use="encoded" namespace="http://example.com/stockquote"
                         encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
           </output>
        </operation>>
    </binding>
 
    <service name="StockQuoteService">
        <documentation>My first service</documentation>
        <port name="StockQuotePort" binding="tns:StockQuoteBinding">
           <soap:address location="http://example.com/stockquote"/>
        </port>
    </service>
</definitions>

This example describes that a GetTradePrices SOAP 1.1 request may be sent to a StockQuote service via the SOAP 1.1 HTTP binding. The request takes a stock quote symbol string, an application defined TimePeriod structure containing a start and end time and returns an array of stock prices recorded by the service within that period of time, as well as the frequency at which they were recorded as the SOAP response.  The RPC signature that corresponds to this service has in parameters tickerSymbol and timePeriod followed by the output parameter frequency, and returns an array of floats.

Example 5. SOAP binding of request-response RPC operation over HTTP

<?xml version="1.0"?>
<definitions name="StockQuote"
 
targetNamespace="http://example.com/stockquote.wsdl"
          xmlns:tns="http://example.com/stockquote.wsdl"
          xmlns:xsd="http://www.w3.org/2000/10/XMLSchema"
          xmlns:xsd1="http://example.com/stockquote/schema"
          xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
          xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
          xmlns="http://schemas.xmlsoap.org/wsdl/">
 
    <types>
       <schema targetNamespace="http://example.com/stockquote/schema"
              xmlns="http://www.w3.org/2000/10/XMLSchema">
           <complexType name="TimePeriod">
              <all>
                  <element name="startTime" type="xsd:timeInstant"/>
                  <element name="endTime" type="xsd:timeInstant"/>
              </all>
           </complexType>
           <complexType name="ArrayOfFloat">
              <complexContent>
                  <restriction base="soapenc:Array">
                      <attribute ref="soapenc:arrayType" wsdl:arrayType="xsd:float[]"/>
                  </restriction>
              </complexContent>
           </complexType>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章