WSDL绑定样式各种组合优劣势比较
目前Web服务的相关标准是WSDL【Web服务描述语言】,一种标准的类似XML Schema的语言,用它来详细说明Web服务和SOAP【简单对象访问协议】,Web服务使用的实际的沟通协议就是SOAP。WSDL 绑定样式由两个属性组合而成:style、use;style可以是RPC/Document,use可以是Encoded/Literal;下面解释下这4个名词的意思:
RPC 样式
RPC样式指定<soap:body>元素包含一个将被调用的web方法的名称的元素(wrapper element(封装元素))。这个元素依次为该方法的每个参数还有返回值作了记录。
Document 样式
如果是document 样式,就没有像在RPC样式中的wrapper元素。转而代之的是消息片断直接出现在<soap:body>元素之下。没有任何SOAP格式化规则规定<soap:body>元素下能包含什么;它包含的是一个发送者和接收者都达成一致的XML文档。
Encoded 编码
如果use的值是”encoded”,则每个消息片段将使用类型属性来引用抽象类型。通过应用由 encodingStyle属性所指定的编码样式,可使用这些抽象类型生成具体的消息。最常用到的SOAP编码样式是在SOAP1.1中定义的一组序列化规则,它说明了对象、结构、数组和图形对象应该如何序列化。通常,在应用程序中使用SOAP编码着重于远程进程调用和以后适合使用RPC消息样式。
Literal 文字?
如果use的值是”Literal”, 则每个片段使用element 属性(对于简单片段)或type 属性(对于复合片段)来引用具体架构,例如,数据根据指定的架构来序列化,这架构通常使用W3C XML架构来表述。
根据不同的组合,形成了四种绑定模型;另外,还有一种用Document模拟RPC样式的包装组合也很常见;
- RPC/Encoded
- RPC/Literal
- Document/Encoded
- Document/Literal
- Document/Literal Wrapped
从生成soap消息的角度看:
rpc和document的差别在于方法的操作名是否出现在生成的Soap消息中。use="literal" 意味着type定义遵循xml模式定义
document:<soap:body>的内容由定义在<wsdl:type>中的xml模式指定。他不需要遵循特定的soap规范。简言之,
soap消息是通过<soap:body>中的document发送出去,而没有额外的要遵循的格式规则。document style是一种默认的选择。
rpc: <soap:body>元素的结构需要遵循特定的规则(soap1.1规范第7部分有细节)。根据这些规则,<soap:body>可以
包含唯一一个元素,这个元素在operation后被命名,所有的参数都必须写成这个元素的子元素。
literal和encoded编码方式的差别在于参数类型是否出现在生成的Soap消息中。use="encoded" 参考xml中已有的应用数据,通常指的是soap1.1规范中的soap编码规则。如果文档中没有自定义数据,就可以选择encoded。
对于以上5种组合方式,由于Document/Encoded不被现有平台所支持,在实际中应用很少,所以这里就暂时不讨论该种组合;对于剩下的4种组合,我们结合一个表格和实例来对比下各自的优劣情况;
Binding Type | Advantage/DisAdvantage |
RPC/ Encoded | 优点:
缺点:
|
RPC/ Literal |
优点:
缺点:
|
Document/Litaral |
优点:
缺点:
|
Document/LiteralWrapped |
优点:
缺点:
|
假设我们需要调用的WS的method为:public void myMethod(int x); 各种绑定样式生成的WSDL/SOAP片段如下:
Binding Type | WSDL | SOAP |
RPC/ Encoded | <message name="myMethodRequest"> |
<soap:envelope> |
RPC/ Literal | <message name="myMethodRequest"> |
<soap:envelope> |
Document/ Litaral | <types> |
<soap:envelope> |
Document/ Literal Wrapped | <types> |
<soap:envelope> |
采用 RPC/编码的理由有很多。其中两个主要的原因是:
数据图形
多态性
数据图形设想您有一个二进制树,其中的节点定义在 清单12中。
清单12. 二进制树节点 Schema
|
根据这种节点定义,我们可以构造一个树形结构,它的根节点 A 通过它左边和右边的的链接可以指向节点 B(请参见 图1)。
发送数据图形的标准方式是使用 href 标记,它是 RPC/编码的样式( 清单13)的一部分。
清单:13. RPC/编码的二进制树
<A> <name>A</name> <left href="12345"/> <right href="12345"/></A><B id="12345"> <name>B</name> <left xsi:nil="true"/> <right xsi:nil="true"/></B> |
在任何文字的样式中,href 属性都是不可用的,这样图形链接就不再起作用了( 清单14和 图2)。您仍然有一个根节点 A,它从左边指向一个节点 B,从右边指向另一个节点 B。这两个 B 节点是等同的,但它们不是相同的节点。是复制了数据而不是引用了两次数据。
14. 文字二进制树
<A> <name>A</name> <left> <name>B</name> <left xsi:nil="true"/> <right xsi:nil="true"/> </left> <right> <name>B</name> <left xsi:nil="true"/> <right xsi:nil="true"/> </right> </A> |
在文字样式中,您可以通过各种方法构造图形,但是却没有标准的方法;所以您做的任何事情很可能不能与网络中其他端点上的服务进行互操作。
多态性看一看 清单15中使用多态性 Schema 的 WSDL。
清单 15. 一个多态性 WSDL 的示例<types> <schema> <complexType name="animal"> <sequence> <element name="name" type="xsd:string"/> </sequence> </complexType> <complexType name="dog"> <complexContent mixed="false"> <extension base="animal"> <sequence> <element name="breed" type="xsd:string"/> </sequence> </extension> </complexContent> </complexType> </schema></types><message name="in"> <part name="trainee" type="animal"/></message><message name="empty"/><portType name="AnimalTrainer"> <operation name="train"> <input message="in"/> <output message="empty"/> </operation></portType> |
当您把一个 dog 的实例传送给 train 操作时,所生成的 SOAP 消息必须包含类型编码信息,这样接收终端才能知道它所接收的是 animal 的哪一个扩展(请参见 清单16)。这种类型编码信息可用在 RPC/编码的样式中。
清单 16. 一个多态性 SOAP 消息<soap:envelope> <soap:body> <train> <trainee xsi:type="Dog"> <name>Bob</name> <breed>Bloodhound</breed> </trainee> </train> </soap:body> </soap:envelope> |
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属性的
转自:老唐 的专栏
我应该彩哪一种WSDL样式 (Russell Butek, 软件工程师, IBM)
SOAP风格中 RPC与Document的区别
Web Service描述语言 WSDL 详解