wsdl样式之间的区别

本文深入探讨了五种WSDL样式:rpc/encoded、rpc/literal、document/encoded、document/literal及document/literalwrapped,通过具体示例展示了每种样式的优缺点,并给出了不同场景下选择合适样式的建议。

在了解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

使用现在流行的Java-to-WSDL工具,指定rpc/encoded样式,生成rpc/encoded WSDL。

rpc/encoded WSDL for myMethod
<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. -->

现在,以x=5,y=5.0调用myMethod。

rpc/encoded SOAP Message for myMethod
<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

指定rpc/encoded样式,生成rpc/encoded WSDL。

rpc/literal WSDL for myMethod
<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 Message for myMethod
<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/

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值