转自IBM java dev
------------------
Web 服务是通过 WSDL 文档来描q的。WSDL l定描述了如何把服务l定到消息传递协议(特别?SOAP 消息传递协议)。WSDL SOAP l定可以?RPC 样式的绑定,也可以是文档样式的绑定。同PSOAP l定可以有编码的用法Q也可以有文字的用法。这l我们提供了四种样式/用法模型Q?/p>
- RPC/~码
- RPC/文字
- 文档/~码
- 文档/文字
除了q些样式之外Q还有一U样式也很常见,它称为文?文字包装的样式,上q一U,在创?WSDL 文g时您有了五U绑定样式可以从中选择。您应该选择哪一U呢Q?/p>
对于本文的讨论,让我们从 清单1中的 Java Ҏ开始,q且对其应用 JAX-RPC Java-to-WSDL 规则
清单 1. Java Ҏ
public void myMethod(int x);
|
RPC/~码
采用 清单1中的Ҏq且使用您喜Ƣ的 Java-to-WSDL 工具来运行它Q指定您惌它生?RPC/~码?WSDL。您最后应该得到如 清单2所C的 WSDL 片断?
清单 2. 用于 myMethod ?RPC/~码?WSDL
<message name="myMethodRequest">
<part name="x" type="xsd:int"/>
</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. -->
|
现在?#8220;5”作ؓ参数 x
的值来调用此方法。我们将发送一个与 清单3cM?SOAP 消息?
清单 3. 用于 myMethod ?RPC/~码?SOAP 消息
<soap:envelope>
<soap:body>
<myMethod>
<x xsi:type="xsd:int">5</x>
</myMethod>
</soap:body>
</soap:envelope>
|
对于q个 RPC/~码的示例中?WSDL ?SOAP 消息Q有许多需要注意的事项Q?/p>
优点
- WSDL 基本辑ֈ了尽可能地简单易懂的要求?/li>
- 操作名出现在消息中,q样接收者就可以很轻村֜把消息发送到Ҏ的实现?/li>
~点
- cd~码信息Q比?
xsi:type="xsd:int"
Q通常是降低吞吐量性能的开销? - 您不能简单地验此消息的有效性,因ؓ只有
<x xsi:type="xsd:int">5</x>
行包含在 Schema 中定义的内容Q其余的 soap:body
内容都来?WSDL 定义?
有没有一U方法能够保留这些优点而消除其中的~点呢?或许有。让我们来看一?RPC/文字的样式?/p>
回页?/a>
RPC/文字
用于我们的方法的 RPC/文字?WSDL 看v来与 RPC/~码?WSDL 几乎一P请参?清单4Q。只是绑定的用法?~码改ؓ 文字。仅此而已?
清单
4. 用于 myMethod ?RPC/文字?WSDL
<message name="myMethodRequest">
<part name="x" type="xsd:int"/>
</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/文字?SOAP 消息又是怎样的呢Q请参见 清单 5Q?q里的更改要多一炏V去掉了cd~码?
清单 5. 用于 myMethod ?/strong>
RPC/文字?SOAP 消息
<soap:envelope>
<soap:body>
<myMethod>
<x>5</x>
</myMethod>
</soap:body>
</soap:envelope>
|
下面是这U方法的优点和缺点:
优点
- WSDL q是基本辑ֈ了尽可能地简单易懂的要求?/li>
- 操作名仍然出现在消息中?/li>
- L了类型编码?/li>
~点
- 您仍然不能简单地验此消息的有效性,因ؓ只有
<x xsi:type="xsd:int">5</x>
行包含在 Schema 中定义的内容Q其余的 soap:body
内容都来?WSDL 定义?
文档样式如何呢?它们能够帮助克服q些困难吗?
回页?/a>
文档
我不知道有谁懂得q种Ҏ的真正含义。我也不知道q种Ҏ的Q何实现。它可能从 WSDL 的后l版本中消失。所以我们还是讨论别的吧?/p>
回页?/a>
文档
文档/文字?WSDL ?RPC/文字?WSDL 作了一些更攏V它们之间的不同之处昄?清单6中?
清单6. 用于 myMethod 的文?文字?WSDL
<types>
<schema>
<element name="xElement" type="xsd:int"/>
</schema>
</types>
<message name="myMethodRequest">
<part name="x"
element="xElement"/>
</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. -->
|
而现在的 SOAP 应该?清单 7所C:
清单7. 用于 myMethod 的文?文字?SOAP 消息
<soap:envelope>
<soap:body>
<xElement>5</xElement>
</soap:body>
</soap:envelope>
|
下面是这U方法的优点和缺点:
优点
- 没有~码信息
- 您可以在最后用M XML 验器验此消息的有效性?
soap:body
Q?<xElement>5</xElement>
Q中每项内容都定义在 Schema 中?
~点
- WSDL 变得有些复杂。不q,q是一个非常小的缺点,因ؓ WSDL q没有打由人来d?/li>
- SOAP 消息中缺操作名。而如果没有操作名Q发送就可能比较困难Qƈ且有时变得不可能?/li>
文档/文字的样式看hg只是重新安排?RPC/文字的模型的优点和缺炏V您可以验消息的有效性,但是您失M操作名。有没有一U方法可以改q这一点呢Q有的。它是文档/文字包装的样式?/p>
回页?/a>
文档
在我说明文档/文字包装的样式的含义之前Q让我给您展C?清单 8?清单9中的 WSDL ?SOAP 消息?
清单8. 用于 myMethod 的文?文字包装?WSDL
<types>
<schema>
<element name="myMethod"/>
<complexType>
<sequence>
<element name="x" type="xsd:int"/>
</sequence>
</complexType>
</element>
</schema>
</types>
<message name="myMethodRequest">
<part name="
parameters" element="
myMethod"/>
</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. -->
|
WSDL Schema 现在把参数放在包装中Q请参见 清单9Q?
清单:9. 用于 myMethod 的文?文字包装?SOAP 消息
<soap:envelope>
<soap:body>
<myMethod>
<x>5</x>
</myMethod>
</soap:body>
</soap:envelope> |
注意到此 SOAP 消息看v来非常类g RPC/文字?SOAP 消息。您可能会说Q它看v来与 RPC/文字?SOAP 消息是完全一LQ不q,q两U消息之间存在着微妙的区别。在 RPC/文字?SOAP 消息中, <soap:body>
?<myMethod>
子句是操作的名称。在文档/文字包装?SOAP 消息中, <myMethod>
子句是单个输入消息的l成部分引用的元素的名称。因此,包装的样式具有这L一个特征,输入元素的名UC操作的名U是相同的。此样式是把操作名放?SOAP 消息的一Uy妙方式?
文档/文字包装的样式的特征有:
- 输入消息只有一个组成部分?/li>
- 该部分就是一个元素?/li>
- 该元素有与操作相同的名称?/li>
- 该元素的复杂cd没有属性?/li>
下面是这U方法的优点和缺点:
优点
- 没有~码信息?/li>
- 出现?soap:body 中的每项内容都是?Schema 定义的,所以您现在可以很容易地验此消息的有效性?/li>
- Ҏ名又出现?SOAP 消息中?/li>
~点
- WSDL 甚至更复杂,但是q仍然是一个非常小的缺炏V?/li>
如您所见,文档/文字包装的样式还是有一些缺点,不过与优ҎhQ它们都昑־无轻重?/p>
文档/文字的样式在哪里定义
q种包装的样式来源于 Microsoft。没有定义这U样式的规范Q所以虽然这U样式是一个好的东西,但不q的是,Z?Microsoft 和其他公司的实现q行互操作,现在惟一的选择是Ҏ Microsoft WSDL 的输出来猜测它是如何工作的。文?文字包装的样式也实现?IBM WebSphere SDK for Web Services 中(请参?参考资?/a>Q。在q个CZ中,样式是相当明昄Q但是也存在个别情况Q在q些情况中,׃~少定义而导致需要操作的适当事项不够特别清晰。我们希望看到的最理想的情况就是将来能有像 Web 服务互操作组l(Web Services Interoperability OrganizationQ这L独立团体来帮助对此进行稳定化和标准化?
回页?/a>
Z么不始终采用文档/文字包装的样?/span>
xQ本文已l给了您q样的一个印象,文档/文字包装的样式是最好的Ҏ。而实际的情况往往实如此。不q,仍然存在着一些情况,在这些情况下Q您最好是换一U别的样式?/p>
采用文档/文字非包装的样式的理?/span>
如果您已l重载了操作Q就不能采用文档/文字包装的样式?
惌一下,除了我们一直在使用的方法之外,q有另一U方法,请参?清单10?
清单10. 用于文档/文字包装的问题方?/strong>
public void myMethod(int x);
public void myMethod(int x, String y);
|
WSDL 允许重蝲的操作。但是当您添加包装的样式?WSDL Ӟ需要元素有与操作相同的名称Qƈ且在 XML 中不能有两个名称相同的元素。所以您必须采用文档/文字非包装的样式或某U?RPC 样式?/p>
采用 RPC/文字的样式的理由
׃文档/文字非包装的样式没有提供操作名,所以在有些情况下,您将需要采用某U?RPC 样式。比如说 清单11中的一l方法?
清单11. 用于文档/文字非包装的样式的问题方?/strong>
public void myMethod(int x);
public void myMethod(int x, String y);
public void someOtherMethod(int x);
|
现在假定您的服务器接收到文档/文字?SOAP 消息Q您可以回过头在 清单 7中看一看它Q。服务器应该发送哪一U方法呢Q所有您能确切知道的是Q它一定不?myMethod(int x, String x)
Q因为消息只有一个参敎ͼ而这U方法需要两个参数。它可能是其他两U方法中的一U。采用文?文字的样式,您没有办法知道是哪一U方法?
假定服务器接收到一?RPC/文字的消息(比如 清单5中的Q,而不是文?文字的消息。对于这U消息,服务器很Ҏ军_把它发送到哪一U方法。您知道操作名是 myMethodQƈ且也知道只有一个参敎ͼ所以它必定?myMethod(int x)
?
采用
采用 RPC/~码的理由有很多。其中两个主要的原因是:
数据囑Ş
设想您有一个二q制树,其中的节点定义在 清单12中?
清单12. 二进制树节点 Schema
<complexType name="Node">
<sequence>
<element name="name" type="xsd:string"/>
<element name="left" type="Node" xsd:nillable="true"/>
<element name="right" type="Node" xsd:nillable="true"/>
</sequence>
</complexType>
|
Ҏq种节点定义Q我们可以构造一个树形结构,它的根节?A 通过它左边和双的的链接可以指向节点 BQ请参见 ?Q?
发送数据图形的标准方式是?href 标记Q它?RPC/~码的样式( 清单13Q的一部分?
清单:13. RPC/~码的二q制?/strong>
<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>
|
在Q何文字的样式中,href 属性都是不可用的,q样囑Ş链接׃再v作用了( 清单14??Q。您仍然有一个根节点 AQ它从左Ҏ向一个节?BQ从双指向另一个节?B。这两个 B 节点是等同的Q但它们不是相同的节炏V是复制了数据而不是引用了两次数据?
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> |
在文字样式中Q您可以通过各种Ҏ构造图形,但是却没有标准的ҎQ所以您做的M事情很可能不能与|络中其他端点上的服务进行互操作?/p>多态?/strong>
看一?清单15中用多态?Schema ?WSDL?
清单
15. 一个多态?WSDL 的示?/strong>
<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 消息必须包含cd~码信息Q这h收终端才能知道它所接收的是 animal 的哪一个扩展(请参?清单16Q。这U类型编码信息可用在 RPC/~码的样式中?
清单
16. 一个多态?SOAP 消息
<soap:envelope>
<soap:body>
<train>
<trainee xsi:type="Dog">
<name>Bob</name>
<breed>Bloodhound</breed>
</trainee>
</train>
</soap:body>
</soap:envelope> |
ȝ
有四U绑定样式(其实真正有五U,不过文档/~码的样式没有什么意义)。虽然每U样式都有自q用武之地Q但是在大多数情况下Q最好的样式是文?文字包装的样式?/p>
]]>