WSDL样式详解

来源:互联网 发布:消音伴奏软件 编辑:程序博客网 时间:2024/05/18 20:53

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:subscribe@example.com"/>
        </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>