WSDL的binding标签中 use/style 属性详解

根据WSDL定义,binding标签用于将抽象的数据定义与具体的实现协议、编码方式等进行绑定。这里用到两个重要的属性:
  style:RPC、Document
  use:encoded、literal
<binding>标签片段如下:

<binding name="ExamplePortBinding" type="tns:Example">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http"
style
="rpc"></soap:binding>
<operation name="sayHello">
<soap:operation soapAction="sayHello"></soap:operation>
<input>
<soap:body use="literal" namespace="http://www.jsoso.com/wstest"></soap:body>
</input>
<output>
<soap:body use="literal" namespace="http://www.jsoso.com/wstest"></soap:body>
</output>
<fault name="HelloException">
<soap:fault name="HelloException" use="literal"></soap:fault>
</fault>
</operation>
</binding>

 

use用于确定SOAP消息的编码方式,即数据类型是否出现在SOAP消息中,差别如下:

RPC/encoded

WSDL片段:
<message name="myMethodRequest">
<part name="x" type="xsd:int"/>
<part name="y" type="xsd:float"/>
</message>
<message name="empty"/>

<portType name="PT">
<operation name="myMethod">
<input message="myMethodRequest"/>
<output message="empty"/>
</operation>
</portType>

SOAP片段:
<soap:envelope>
<soap:body>
<myMethod>
<x xsi:type="xsd:int">5</x>
<y xsi:type="xsd:float">5.0</y>
</myMethod>
</soap:body>
</soap:envelope>
RPC/literal

WSDL片段:
<message name="myMethodRequest">
<part name="x" type="xsd:int"/>
<part name="y" type="xsd:float"/>
</message>
<message name="empty"/>

<portType name="PT">
<operation name="myMethod">
<input message="myMethodRequest"/>
<output message="empty"/>
</operation>
</portType>

SOAP片段:
<soap:envelope>
<soap:body>
<myMethod>
<x>5</x>
<y>5.0</y>
</myMethod>
</soap:body>
</soap:envelope>

 style用于确定SOAP消息的格式,即是否使用Schema定义数据类型,以及operation名称是否出现在SOAP消息中。

RPC/literal

WSDL片段:
<message name="myMethodRequest">
<part name="x" type="xsd:int"/>
<part name="y" type="xsd:float"/>
</message>
<message name="empty"/>

<portType name="PT">
<operation name="myMethod">
<input message="myMethodRequest"/>
<output message="empty"/>
</operation>
</portType>





SOAP片段:
<soap:envelope>
<soap:body>
<myMethod>
<x>5</x>
<y>5.0</y>
</myMethod>
</soap:body>
</soap:envelope>
Document/literal

WSDL片段:
<types>
<schema>
<element name="xElement" type="xsd:int"/>
<element name="yElement" type="xsd:float"/>
</schema>
</types>

<message name="myMethodRequest">
<part name="x" element="xElement"/>
<part name="y" element="yElement"/>
</message>
<message name="empty"/>

<portType name="PT">
<operation name="myMethod">
<input message="myMethodRequest"/>
<output message="empty"/>
</operation>
</portType>

SOAP片段:
<soap:envelope>
<soap:body>
<xElement>5</xElement>
<yElement>5.0</yElement>
</soap:body>
</soap:envelope>

从上面的比较可以看出,literal优于encoded的地方在于可以避免将具体的类型描述(如xsi:type="xsd:int")放在SOAP中,这可以节省不少数据流量;
Document优于RPC的地方在于它将使用Shema确定数据类型便于SOAP格式的验证,但是它却在SOAP消息中丢去了具体的方法标签,不利于服务分发层定位具体的服务实现。

鉴于上面的讨论,我们给出了一种更好的解决办法,即使用 

Document/literal wrapped 模式

。它的实现方式如下:

WSDL片段:
<types>
<schema>
<element name="myMethod">
<complexType>
<sequence>
<element name="x" type="xsd:int"/>
<element name="y" type="xsd:float"/>
</sequence>
</complexType>
</element>
<element name="myMethodResponse">
<complexType/>
</element>
</schema>
</types>
<message name="myMethodRequest">
<part name="parameters" element="myMethod"/>
</message>
<message name="empty">
<part name="parameters" element="myMethodResponse"/>
</message>

<portType name="PT">
<operation name="myMethod">
<input message="myMethodRequest"/>
<output message="empty"/>
</operation>
</portType>

SOAP片段:
<soap:envelope>
<soap:body>
<myMethod>
<x>5</x>
<y>5.0</y>
</myMethod>
</soap:body>
</soap:envelope>

该模式通过引入一个与方法(operation)名相同的输入参数的复杂类型包装完整的参数信息,有效地避免了RPC与Document固有的缺陷:
  既使用schema定义了数据类型便于消息验证,
  又将方法名留在了SOAP中便于后续的服务分派。
因此,我们在大部分情况下都使用Document/literal wrapped 模式。

但是也有一些特殊场合让前面介绍的几种组合有用武之地:
1、使用普通Document/literal模式的情形:
    当存在方法重载(overload)时,
      public void myMethod(int x, float y);
      public void myMethod(int x);
    此时,我们无法在WSDL中定义两个相同名称的复杂类型作为方法的输入参数。
    (wrapper模式要求方法输入参数的复杂类型名誉方法名相同)

2、使用RPC/literal的情形:
    当同时存在重载方法与不同名但参数列表相同的方法时
    (1)public void myMethod(int x, float y);
    (2)public void myMethod(int x);
    (3)public void someOtherMethod(int x, float y);
    此时,Document/literal由于没有方法名无法区分(1)方法与(3)方法

3、使用RPC/encoded的情形:
    当需要传递数据图(data graph)信息时,需要使用href属性。
    而任何literal风格的SOAP消息是不允许使用href属性的。(还是任何属性都不允许用???

参考文档:
http://www.ibm.com/developerworks/webservices/library/ws-whichwsdl/

 

 

posted @ 2012-02-26 17:12  万法自然~  阅读(2680)  评论(0编辑  收藏  举报