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 |
RPC/literal |
style用于确定SOAP消息的格式,即是否使用Schema定义数据类型,以及operation名称是否出现在SOAP消息中。
RPC/literal
|
Document/literal |
从上面的比较可以看出,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/