RPC/编码、RPC/文字、文档/文字?应该采用哪一种?
WSDL
绑定样式可以是
RPC
样式或文档样式。用法可以是编码的,也可以是文字的。您如何决定使用哪一种样式
/
用法的组合呢?本文将帮助您解决这个问题。
Web
服务是通过
WSDL
文档来描述的。
WSDL
绑定描述了如何把服务绑定到消息传递协议(特别是
SOAP
消息传递协议)。
WSDL SOAP
绑定可以是
RPC
样式的绑定,也可以是文档样式的绑定。同样,
SOAP
绑定可以有编码的用法,也可以有文字的用法。这给我们提供了四种样式
/
用法模型
:
1.
RPC/
编码
2.
RPC/
文字
3.
文档
/
编码
4.
文档
/
文字
除了这些样式之外,还有一种样式也很常见,它称为文档
/
文字包装的样式,算上这一种,在创建
WSDL
文件时您就有了五种绑定样式可以从中选择。您应该选择哪一种呢?
于本文的讨论,让我们从
清单1
中的
Java
方法开始,并且对其应用
JAX-RPC Java-to-WSDL
规则(请参见
参考资料
)。
清单
1. Java
方法
public void myMethod(int x);
|
RPC/
编码
采用
清单1
中的方法并且使用您喜欢的
Java-to-WSDL
工具来运行它,指定您想让它生成
RPC/
编码的
WSDL
。您最后应该得到如
清单2
所示的
WSDL
片断。
清单
2.
用于 myMethod 的 RPC/编码的 WSDL
|
现在用
“5”
作为参数
x
的值来调用此方法。我们将发送一个与
清单3
类似的
SOAP
消息。
清单
3.
用于 myMethod 的 RPC/编码的 SOAP 消息
5
|
![]() |
|
对于这个
RPC/
编码的示例中的
WSDL
和
SOAP
消息,有许多需要注意的事项:
优点
- WSDL 基本达到了尽可能地简单易懂的要求。
- 操作名出现在消息中,这样接收者就可以很轻松地把消息发送到方法的实现。
缺点
- 类型编码信息(比如xsi:type="xsd:int")通常就是降低吞吐量性能的开销。
- 您不能简单地检验此消息的有效性,因为只有 5 行包含在 Schema 中定义的内容;其余的soap:body内容都来自 WSDL 定义。
有没有一种方法能够保留这些优点而消除其中的缺点呢?或许有。让我们来看一看
RPC/
文字的样式。
RPC/
文字
用于我们的方法的
RPC/
文字的
WSDL
看起来与
RPC/
编码的
WSDL
几乎一样(请参见
清单4
)。只是绑定的用法由
编码
改为
文字
。仅此而已。
清单
4. 用于 myMethod 的 RPC/文字的 WSDL
4. 用于 myMethod 的 RPC/文字的 WSDL
|
RPC/
文字的
SOAP
消息又是怎样的呢(请参见
清单 5
)?这里的更改要多一点。去掉了类型编码。
清单
5.
用于
myMethod
的
RPC/ 文字的 SOAP 消息
RPC/ 文字的 SOAP 消息
5
|
下面是这种方法的优点和缺点:
优点
- WSDL 还是基本达到了尽可能地简单易懂的要求。
- 操作名仍然出现在消息中。
- 去掉了类型编码。
缺点
- 您仍然不能简单地检验此消息的有效性,因为只有 5 行包含在 Schema 中定义的内容;其余的soap:body内容都来自 WSDL 定义。
文档样式如何呢?它们能够帮助克服这些困难吗?
文档
文档
/
文字的
WSDL
对
RPC/
文字的
WSDL
作了一些更改。它们之间的不同之处显示在
清单6
中。
清单 6. 用于 myMethod 的文档 / 文字的 WSDL
element="xElement"
/>
|
而现在的
SOAP
应该如
清单 7
所示:
清单 7. 用于 myMethod 的文档 / 文字的 SOAP 消息
5
|
![]() |
|
下面是这种方法的优点和缺点:
优点
- 没有编码信息
- 您可以在最后用任何 XML 检验器检验此消息的有效性。soap:body( 5 )中每项内容都定义在 Schema 中。
缺点
- WSDL 变得有些复杂。不过,这是一个非常小的缺点,因为 WSDL 并没有打算由人来读取。
- SOAP 消息中缺少操作名。而如果没有操作名,发送就可能比较困难,并且有时变得不可能。
文档
/
文字的样式看起来似乎只是重新安排了
RPC/
文字的模型的优点和缺点。您可以检验消息的有效性,但是您失去了操作名。有没有一种方法可以改进这一点呢?有的。它就是文档
/
文字包装的样式。
文档
在我说明文档
/
文字包装的样式的含义之前,让我给您展示
清单 8
和
清单9
中的
WSDL
和
SOAP
消息。
清单 8. 用于 myMethod 的文档 / 文字包装的 WSDL
parameters
" element="
myMethod
"/>
|
WSDL Schema
现在把参数放在包装中(请参见
清单9
)。
清单 :9. 用于 myMethod 的文档 / 文字包装的 SOAP 消息
5
|
注意到此
SOAP
消息看起来非常类似于
RPC/
文字的
SOAP
消息。您可能会说,它看起来与
RPC/
文字的
SOAP
消息是完全一样的,不过,这两种消息之间存在着微妙的区别。在
RPC/
文字的
SOAP
消息中,
的
子句是操作的名称。在文档
/
文字包装的
SOAP
消息中,
子句是单个输入消息的组成部分引用的元素的名称。因此,包装的样式具有这样的一个特征,输入元素的名称与操作的名称是相同的。此样式是把操作名放入
SOAP
消息的一种巧妙方式。
文档
/
文字包装的样式的特征有:
- 输入消息只有一个组成部分。
- 该部分就是一个元素。
- 该元素有与操作相同的名称。
- 该元素的复杂类型没有属性。
下面是这种方法的优点和缺点:
优点
- 没有编码信息。
- 出现在 soap:body 中的每项内容都是由 Schema 定义的,所以您现在可以很容易地检验此消息的有效性。
- 方法名又出现在 SOAP 消息中。
缺点
- WSDL 甚至更复杂,但是这仍然是一个非常小的缺点。
如您所见,文档
/
文字包装的样式还是有一些缺点,不过与优点比起来,它们都显得无足轻重。
文档
/文字的样式在哪里定义
这种包装的样式来源于 Microsoft 。没有定义这种样式的规范;所以虽然这种样式是一个好的东西,但不幸的是,为了与 Microsoft 和其他公司的实现进行互操作,现在惟一的选择就是根据 Microsoft WSDL 的输出来猜测它是如何工作的。文档 / 文字包装的样式也实现在 IBM WebSphere SDK for Web Services 中(请参见 参考资料 )。在这个示例中,样式是相当明显的;但是也存在个别情况,在这些情况中,由于缺少定义而导致需要操作的适当事项不够特别清晰。我们希望看到的最理想的情况就是将来能有像 Web 服务互操作组织( Web Services Interoperability Organization )这样的独立团体来帮助对此进行稳定化和标准化。
为什么不始终采用文档
/文字包装的样式
至此,本文已经给了您这样的一个印象,文档
/
文字包装的样式是最好的方法。而实际的情况往往确实如此。不过,仍然存在着一些情况,在这些情况下,您最好是换一种别的样式。
采用文档
/文字非包装的样式的理由
如果您已经重载了操作,就不能采用文档 / 文字包装的样式。
想象一下,除了我们一直在使用的方法之外,还有另一种方法,请参见
清单10
。
清单 10. 用于文档/文字包装的问题方法
public void myMethod(int x);
public void myMethod(int x, String y);
|
![]() |
|
WSDL
允许重载的操作。但是当您添加包装的样式到
WSDL
时,需要元素有与操作相同的名称,并且在
XML
中不能有两个名称相同的元素。所以您必须采用文档
/
文字非包装的样式或某种
RPC
样式。
采用
RPC/文字的样式的理由
由于文档/文字非包装的样式没有提供操作名,所以在有些情况下,您将需要采用某种 RPC 样式。比如说 清单11中的一组方法。
由于文档/文字非包装的样式没有提供操作名,所以在有些情况下,您将需要采用某种 RPC 样式。比如说 清单11中的一组方法。
清单 11. 用于文档/文字非包装的样式的问题方法
public void myMethod(int x);
public void myMethod(int x, String y);
public void someOtherMethod(int x);
|
现在假定您的服务器接收到文档
/
文字的
SOAP
消息(您可以回过头在
清单 7
中看一看它)。服务器应该发送哪一种方法呢?所有您能确切知道的就是,它一定不是
myMethod(int x, String x)
,因为消息只有一个参数,而这种方法需要两个参数。它可能是其他两种方法中的一种。采用文档
/
文字的样式,您没有办法知道是哪一种方法。
假定服务器接收到一个
RPC/
文字的消息(比如
清单5
中的),而不是文档
/
文字的消息。对于这种消息,服务器很容易决定把它发送到哪一种方法。您知道操作名是
myMethod
,并且也知道只有一个参数,所以它必定是
myMethod(int x)
。
采用
RPC/编码的
理由有很多。其中两个主要的原因是:
- 数据图形
- 多态性
数据图形
设想您有一个二进制树,其中的节点定义在
清单12
中。
清单 12. 二进制树节点 Schema
|
根据这种节点定义,我们可以构造一个树形结构,它的根节点
A
通过它左边和右边的的链接可以指向节点
B
(请参见
图1
)。

发送数据图形的标准方式是使用
href
标记,它是
RPC/
编码的样式(
清单13
)的一部分。
清单 :13. RPC/编码的二进制树
A
B
|
在任何文字的样式中,
href
属性都是不可用的,这样图形链接就不再起作用了(
清单14
和
图2
)。您仍然有一个根节点
A
,它从左边指向一个节点
B
,从右边指向另一个节点
B
。这两个
B
节点是等同的,但它们不是相同的节点。是复制了数据而不是引用了两次数据。
14. 文字二进制树
A
B
B
|

在文字样式中,您可以通过各种方法构造图形,但是却没有标准的方法;所以您做的任何事情很可能不能与网络中其他端点上的服务进行互操作。
多态性
看一看
清单15
中使用多态性
Schema
的
WSDL
。
清单
15. 一个多态性 WSDL 的示例
15. 一个多态性 WSDL 的示例
|
当您把一个
dog
的实例传送给
train
操作时,所生成的
SOAP
消息必须包含类型编码信息,这样接收终端才能知道它所接收的是
animal
的哪一个扩展(请参见
清单16
)。这种类型编码信息可用在
RPC/
编码的样式中。
清单
16. 一个多态性 SOAP 消息
16. 一个多态性 SOAP 消息
Bob
Bloodhound
|
总结
有四种绑定样式(其实真正有五种,不过文档
/
编码的样式没有什么意义)。虽然每种样式都有自己的用武之地,但是在大多数情况下,最好的样式是文档
/
文字包装的样式。
参考资料
- 您可以参阅本文在 developerWorks 全球站点上的 英文原文.
- 阅读 WSDL 的规范 Web 服务描述语言(Web Services Description Language,WSDL 1.1)。
- 看一看介绍 SOAP 1.2 规范的 SOAP 1.2 入门。
- 获取 IBM WebSphere SDK for Web Services(WSDK)版本 5.1,它是一个用于创建、发现、调用和测试 Web 服务的工具包。您可以通过此链接下载 WSDK 5.0.1 和大量的教程。
- Java API for XML-Based RPC(JAX-RPC)下载和规范提供了指向 JAX-RPC 1.0 规范本身以及 javadocs、类文件和 Sun 的 JAX-RPC 参考实现的链接。
- 浏览 WS-I(Web Services Interoperability)组织的 Web 页面。
- 阅读 WS-I 的基本概要 1.0(Basic Profile 1.0)。