WebService之样式(Style)和编码(Encode)

WebService 专栏收录该内容
2 篇文章 0 订阅

 

接上篇WebService原理浅析, SOAP编码有多种方式,我们在上一篇中使用的只是其中的一种,上一篇中我们介绍了WSDL的binding部分描述了WebService使用的协议及封装格式,其中封装格式是由样式( style )和编码(encode)控制的,本文将介绍样式和编码的组合是怎么影响SOAP封装,每种组合的优缺点以及使用建议。

 

样式( style )

 

WebService有两种通信样式( style ):

  • document
  • rpc

通过WSDL文件的binding部分可以判断WebService属于哪种样式(style),document示例如下:

......
<!-- document style示例 -->
<binding name="HelloWorldPortBinding" type="tns:HelloWorld"> 
    <!-- style 属性表明使用的是哪种style -->
    <soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/>
.....

rpc示例如下:

......
<!-- rpc style示例 -->
<binding name="HelloWorldPortBinding" type="tns:HelloWorld"> 
    <!-- style 属性表明使用的是哪种style -->
    <soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="rpc"/>
.....

 

编码( encode

 

WebService有两种编码( encode )方式:

  • encode
  • literal

同样,通过WSDL文件的binding部分可以判断WebService属于哪种编码(encode),encode示例如下:

......
<binding name="HelloWorldPortBinding" type="tns:HelloWorld"> 
    <soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/>  
    <operation name="sayHelloWorld"> 
      <soap:operation soapAction=""/>  
      <input> 
        <!-- use属性表明使用的编码格式-->
        <soap:body use="encode"/> 
      </input>
......

literal示例如下:

......
<binding name="HelloWorldPortBinding" type="tns:HelloWorld"> 
    <soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/>  
    <operation name="sayHelloWorld"> 
      <soap:operation soapAction=""/>  
      <input> 
        <!-- use属性表明使用的编码格式-->
        <soap:body use="literal"/> 
      </input>
......

 

样式和编码组合对比

 

样式和编码有四种组合:

  • rpc encode
  • rpc literal
  • document encode
  • document literal

每种组合对应不同的SOAP协议格式,下文将使用上一篇( WebService原理浅析 )中的sayHelloWorld方法举例说明每种组合对应的协议格式,sayHelloWorld对应的Java签名如下:

public String sayHelloWorld(String arg0)

 

rpc encode

 

WSDL文件看起来如下:

...... 
<message name="sayHelloWorldRequest">     
    <part name="arg0" type="xsd:string"/> 
</message> 
......   
<portType name="HelloWorld">     
    <operation name="sayHelloWorld">         
        <input message="sayHelloWorldRequest"/>
        ......
    </operation> 
</portType>   
<binding ....../>

调用sayHelloWorld方法SOAP的协议封装看起来如下:

<soap:envelope>     
    <soap:body>         
        <sayHelloWorld>              
            <arg0 xsi:type="xsd:string">jack</arg0>         
        </sayHelloWorld>     
    </soap:body> 
</soap:envelope>

优点:

  • WSDL文件简单明了
  • 消息里面有方法名sayHelloWorld和参数名arg0

缺点:

  • 参数里面包含了类型信息,这样会降低传输性能,因为要多传输类型信息
  • 无法验证SOAP表示的xml,元素sayHelloWorld和arg0根本就没有定义

 

rpc literal

 

WSDL文件看起来如下:

...... 
<message name="sayHelloWorldRequest">     
    <part name="arg0" type="xsd:string"/> 
</message> 
......   
<portType name="HelloWorld">     
    <operation name="sayHelloWorld">         
        <input message="sayHelloWorldRequest"/>
        ......
    </operation> 
</portType>   
<binding ....../>

调用sayHelloWorld方法SOAP的协议封装看起来如下:

<soap:envelope>     
    <soap:body>         
        <sayHelloWorld>              
            <arg0>jack</arg0>         
        </sayHelloWorld>     
    </soap:body> 
</soap:envelope>

优点:

  • WSDL文件简单明了
  • 消息里面有方法名sayHelloWorld和参数名arg0

缺点:

  • 无法验证SOAP表示的xml,元素sayHelloWorld和arg0没有定义。

 

document encoded

 

没有人使用这种风格,所以我们不做介绍。

 

document literal

 

WSDL文件看起来如下:

...... 
<types>
    <schema>
        <element name="arg0" type="xsd:string"/>
    <schema>
</type>
<message name="sayHelloWorldRequest">     
    <part name="arg0" element="arg0"/> 
</message> 
......   
<portType name="HelloWorld">     
    <operation name="sayHelloWorld">         
        <input message="sayHelloWorldRequest"/>
        ......
    </operation> 
</portType>   
<binding ....../>

调用sayHelloWorld方法SOAP的协议封装看起来如下:

<soap:envelope>     
    <soap:body>                
        <arg0>jack</arg0>
    </soap:body> 
</soap:envelope>

优点:

  • SOAP表示的xml可以验证,可以找到元素arg0的定义。

缺点:

  • WSDL文件复杂了一些,因为定义了 一些新的xml元素arg0
  • 消息里面没有方法名sayHelloWorld

 

document literal wrapped

 

综合四种组合的优缺点document literal wrapped应运而生, WSDL文件看起来如下:

...... 
<types>
    <schema>
        <element name="sayHelloWorld">
            <complexType>                
                <element name="arg0" type="xsd:string"/> 
            </complexType>
        </element>
    <schema>
</types>
<message name="sayHelloWorldRequest">     
    <part name="parameters" element="sayHelloWorld"/> 
</message> 
......   
<portType name="HelloWorld">     
    <operation name="sayHelloWorld">         
        <input message="sayHelloWorldRequest"/>
        ......
    </operation> 
</portType>   
<binding ....../>

调用sayHelloWorld方法SOAP的协议封装看起来如下:

<soap:envelope>     
    <soap:body>      
        <sayHelloWorld>          
            <arg0>jack</arg0>
        </sayHelloWorld>
    </soap:body> 
</soap:envelope>

优点:

  • 包含了方法名和参数
  • SOAP的xml文件可以验证,sayHelloWorld和arg0元素都已经定义了

缺点:

  • WSDL文件变复杂了,增加了sayHelloWorld和arg0元素

 

应该选用哪种方式?

 

虽然document literal wrapped 会增加WSDL的复杂度,但是WSDL文件往往不需要人来处理,有现成的框架可以读取WSDL文件生成代码。所以document literal wrapped是最好的一种协议封装方式,我们应该优先使用这种方式,上一篇中便是使用了这种封装方式。

document literal wrapped虽好但是也有它不适用的场景,当WebService中有重载的方法名时,document literal wrapped 将不再适用,因为无法在xml中定义两个相同的方法名元素。

 

最后

 

style用来控制SOAP封装里面是否有方法名,document没有方法名,rpc有方法名,document wrapped也有方法名。

encode/literal用来控制SOAP封装的参数是否有数据类型,encode有数据类型,literal没有数据类型。

 

 

 

 

 

参考:

 

https://www.ibm.com/developerworks/library/ws-whichwsdl/index.html

 

  • 0
    点赞
  • 0
    评论
  • 1
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

©️2021 CSDN 皮肤主题: 技术黑板 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值