在了解WSDL样式间的区别前,我们首先要了解两个属性的概念,这两个属性在WSDL文件中的wsdl:binding中定义,style和use,他们的组合决定了WSDL的样式。
style定义了如何翻译(解析或转换)WSDL绑定到SOAP消息协议。
use定义了WSDL和SOAP之间的映射关系。
我们可以把这两个属性的定义理解为中英翻译,例如:中文“我是一个学生”译成英文“I'm a student”。翻译工作由style负责,而use负责映射,例如学生映射结果是student。
style=rpc | document,use=encoded | literal,那么,WSDL样式有以下几种:
rpc/encoded
rpc/literal
document/encoded
document/literal
还有一种我们通常称之为document/literal wrapped的样式,这样,在我们创建WSDL文档的时候,我们有5种样式可供选择,那么,我们应该选择哪种呢?
在讨论之前,我们先定义一个Java方法
Java Code:
public void myMethod(int x, float y);
rpc/encoded
<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. -->
<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>
优势
- WSDL简洁,直接了当。
- SOAP消息体包含方法名myMethod,所以消息接收者可以在第一时间调用myMethod方法。
缺点
- SOAP消息体中包含编码信息(如:
xsi:type="xsd:int")增加开销,降低吞吐量。 - 你无法轻易验证此SOAP消息,除了消息体中的<x xsi:type="xsd:int">5</x>和<y xsi:type="xsd:float">5.0</y>,其它消息并没有在WSDL中定义,比如方法名。
- 虽然这是一个合法的WSDL,但是WS-I不兼容rpc/encoded。
rpc/literal
<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. -->
<soap:envelope>
<soap:body>
<myMethod>
<x>5</x>
<y>5.0</y>
</myMethod>
</soap:body>
</soap:envelope>
优势
- WSDL依旧简洁。
- 消息体中包含方法名myMethod。
- 消除编码信息(如:
xsi:type="xsd:int")。 - WS-I兼容rpc/literal。
缺点
- 你依旧无法轻易验证此SOAP消息,除了消息体中的<x xsi:type="xsd:int">5</x>和<y xsi:type="xsd:float">5.0</y>,其它消息并没有在WSDL中定义,比如方法名。
document/encoded
没有人使用这种风格的WSDL,同时WS-I也不兼容这种风格。
document/literal
document/literal的WSDL和rpc/literal的区别还是比较大。
document/literal wsdl for myMethod
<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>
<binding .../>
<!-- I won't bother with the details, just assume it's document/literal. -->
document/literal SOAP Message for myMethod
<soap:envelope>
<soap:body>
<xElement>5</xElement>
<yElement>5.0</yElement>
</soap:body>
</soap:envelope>
优势
- 消除编码信息(如:
xsi:type="xsd:int")。 - SOAP消息体中的内容都在WSDL中定义,你可以轻松是验证SOAP消息。
- WS-I兼容document/literal,但是有限制(参考缺点)。
缺点
- WSDL有一点点的复杂,不适合阅读。
- SOAP消息体中没有方法名。
- WS-I只允许SOAP消息体包含一个方法。
document/literal wrapped
首先看看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>
<binding .../>
<!-- I won't bother with the details, just assume it's document/literal. -->
document/literal wrapped SOAP Message for myMethod
<soap:envelope>
<soap:body>
<myMethod>
<x>5</x>
<y>5.0</y>
</myMethod>
</soap:body>
</soap:envelope>
这个SOAP消息体和rpc/litera基本一模一样,但他们还是有区别的。在rpc/literal SOAP消息中,<soap:body>子节点myMethod是是WSDL中的一个方法名,而document/literal wrapped SOAP消息中的myMethod是WSDL中定义的元素。
优势
- 没有编码信息
- SOAP消息体中的内容都在WSDL中定义,所以,你可以非常容易地验证此消息。
- SOAP消息中的方法名又出现了。
- WS-I兼容document/literal wrapped。
缺点
- WSDL过于复杂。
为什么不一直使用document/literal wrapped?
到现在为止,本文给我们的印象document/literal wrapped是最佳的设计风格。很多时候,这是符合的。但仍然存在其它情况,你会选择其它更合适的WSDL样式。
使用document/literal non-wrapped的原因
如果你重载方法,你就不能使用document/literal wrapped。
public void myMethod(int x, float y);
public void myMethod(int x);
WSDL允许重载方法,但当你使用document/literal wrapped,WSDL定义了一个和方法名相同名称的元素,在xml不允许同时存在两个相同名称的元素,所以你必须使用document/literal或rpc样式中一种。
重载的方法名,服务端接受SOAP消息以参数个数来判断调用哪个方法。
使用rpc/literal的原因
document/literal的SOAP消息中不提供方法名,WS-I不支持多个方法,所以,document/literal不支持以下情况,我们使用其中一种rpc风格:
public void myMethod(int x, float y);
public void myMethod(int x);
public void someOtherMethod(int x, float y);
最后,感谢Russell Butek,详细区别请参考:
http://www.ibm.com/developerworks/webservices/library/ws-whichwsdl/
本文深入探讨了五种WSDL样式:rpc/encoded、rpc/literal、document/encoded、document/literal及document/literalwrapped,通过具体示例展示了每种样式的优缺点,并给出了不同场景下选择合适样式的建议。
2万+

被折叠的 条评论
为什么被折叠?



