一个WSDL描述了一个Web Service。一个WSDL binding描述了这个service是怎么绑定到一个消息协议上的,特别的如SOAP消息协议。WSDL SOAP绑定可以是一个RPC(Remote Procedure Call)样式的绑定,也可以是一个document样式的绑定。SOAP绑定也可以有一个encoding use或一个literal use。因此我们有了四种style/use模式:
- RPC/encoded
- RPC/literal
- Document/encoded
- Document/literal
再加上document/literal wrapped pattern,当创建一个WSDL文件时就有了五种可选的样式了。那么应该选择哪一个呢?
这里说一点:RPC和document仅仅是一种术语,并不像他们的词义那些来进行区分的。它仅仅指出应该怎么把一个WSDL的binding转换成一个SOAP的message,没有更多的东西,你可以随便使用哪种。
同样的,encoding和literal也只是在WSDL到SOAP的mapping的时候有用。
下面我们就开始讨论这五种不同的样式对。首先我们先假设有一个方法:
public void myMethod(int x, float y);
这个方法对应的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> <binding .../> <!-- I won't bother with the details, just assume it's RPC/encoded. -->
这里要注意的就是假设binding使用的RPC/encoded样式对。当基于这个wsdl转换时,它对应的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/encoded并不是一个WS-I兼容的
先看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> <binding .../> <!-- I won't bother with the details, just assume it's RPC/literal. -->
这里使用的样式对是RPC/literal。对应的soap消息如下:
<soap:envelope>
<soap:body>
<myMethod>
<x>5</x>
<y>5.0</y>
</myMethod>
</soap:body>
</soap:envelope>
这里去掉了类型信息。
优点:
- 直观
- 操作名也存在
- 类型信息去除掉了
- 是一个WS-I兼容的
缺点:
- 无法容易的进行有效的验证
没有人使用这种样式对,因此不讨论
首先我们先看下面的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> <binding .../> <!-- I won't bother with the details, just assume it's document/literal. -->
对应的Soap消息如下:
<soap:envelope> <soap:body> <myMethod> <x>5</x> <y>5.0</y> </myMethod> </soap:body> </soap:envelope>
这个消息看起来有点像RPC/literal的soap消息。但是他们有不同。在RPC/literal消息中的myMethod是来自操作名,而这里的myMethod来自元素名。
对于一个document/literal pattern wrapped样式对,有一点基本的特征:
- 每个input message只会有一个part
- 这个part还是一个element
- 这个element名和operation名一样
- element只有子元素没有属性
这种样式的优点如下:
- 没有type信息
- 每个在soap:body里定义的内容都来自一个schema
- 你又可以得到operation名了
- 它是一个WS-I兼容的,并且符合WS-I中soap:body只有一个子元素的约束
缺点:
- wsdl看起来更复杂了