梦想与现实的落差,就是我们离成功的距离!!
执子之手<-->与子偕老
Web 服务最佳实践
概要
Web服务是作为一种沟通技术而被很好地制订出来,它为Internet提供最佳的互通能力。它们的标准化进程正高速地进行着,这必将引起它们会被更广泛的接受。尽管如此,从许多邮件列表、用户组和各种讨论来判断,在不同Web服务设计(Web Service Design)方法中仍然存在相当多的混乱情形。“Document/Literal” 意味着什么,而“RPC-style”又是什么,怎样使SOAP“message-style” 适合这呢?
这篇文章将会阐明和详细解释那些由Web服务标准化组定义的不同的Web服务设计方法学,阐明各种术语,着重解释它们的不同之处。在这里,我们将把精力放在如下的几个Web服务设计方法学,评估它们的优点和缺点,并在设计一种互通性Web服务中探究每一种类型得到多大程度的支持。
介绍
在市场上Web服务在相对存在较短的时间内,得到了巨大的认同和广泛的应用。其中一个主要原因当然是它们的那些非常早期的开放式标准,而这些标准就是市场上所有主要的Web服务推崇者所推动的;另一方面,在Web服务看起来应该像什么和他们应该如何通信这些方面,这些推崇者各有自己的偏爱。这已经导致今天的标准支持各种不同的关于web服务消息能怎样格式化和它们如何通信的方法,事实上,那些不同的通信类型是需要的。
这些描述和使用Web服务的相关标准是WSDL(Web服务描述语言),一种标准的类似XML Schema的语言,用它详细说明Web服务和简单对象访问协议(SOAP),Web服务使用的实际的沟通协议就是简单对象访问协议(SOAP)。在了解真正的设计方法学之前,让我们先阐述下在web服务领域中频繁使用到的各种术语。
沟通模式
让我们从沟通模式开始,在使用Web服务时我们应能本质地区别三种沟通方法:
SOAP 协议格式化规则
现在我们转到一个Web服务的SOAP的消息(本质上是消息的<soap:body> 元素)能如何格式化,WSDL1.1 区分两种不同绑定形式(参考soap的绑定形式):RPC和Document(文档)。(译者注:RPC(消息包含参数并返回值)Document(消息包含文档))
RPC样式指定<soap:body> 元素包含一个将被调用的web方法的名称的元素(wrapper element(封装元素))。这个元素依次为该方法的每个参数还有返回值作了记录。
如果是document 样式,就没有像在RPC样式中的wrapper元素。转而代之的是消息片断直接出现在<soap:body> 元素之下。没有任何SOAP格式化规则规定<soap:body>元素下能包含什么;它包含的是一个发送者和接收者都达成一致的XML文档。
第二种格式规则就是‘Use’ 属性。这与各种类型如何在XML中显示有关,它指定使用某种编码规则对消息片段进行编码,还是使用消息的具体架构来定义片段。如下就是提供的两种选择:
如果use的值是”encoded”, 则每个消息片段将使用类型属性来引用抽象类型。通过应用由 encodingStyle 属性所指定的编码样式,可使用这些抽象类型生成具体的消息。最常用到的SOAP编码样式是在SOAP1.1中定义的一组序列化规则,它说明了对象、结构、数组和图形对象应该如何序列化。通常,在应用程序中使用SOAP编码着重于远程进程调用和以后适合使用RPC消息样式。
如果use 的值是”Literal”, 则每个片段使用 element 属性(对于简单片段)或 type 属性(对于复合片段)来引用具体架构,例如,数据根据指定的架构来序列化,这架构通常使用W3C XML架构来表述。
表1总结了各种不同的web服务参数的可选项。一个重要的事实就是,每个web服务开发人员要做三个独立的决定,使用什么“沟通模式”?什么SOAP格式化“样式”?最后用到什么SOAP消息编码类型?
WSDL 参数
可用选项
Communication Patterns
远程进程调用或单方消息发送
Style
Document 或 RPC
Use
Encoded 或 Literal
表1.Web服务参数。
虽然,理论上说,这些选项的任何一种组合都是可以的,但在实践中会明确偏爱某种组合而不是其它的,同时,各种标准和Web服务互用性组织(WS-I)也有某种明确的偏爱。
因此在实践中,仅Document/Literal 和 RPC/Encoded 得到了广泛的应用,同时也被大部分平台直接支持,这些平台显示在表2中。这个表也显示了对不同的style/use组合的WS-I 一致性测试结果。
Style/Use 组合
支持的 Soap 工具
WS-I 一致性
RPC/Encoded
Microsoft, Axis 1.1
Failed
RPC/Literal
Axis 1.1
Document/Literal
Microsoft , Axis1.1
Passed
表2. Web服务格式支持
由于Document/Encoded这种组合不支持现有使用的平台,所以没有测试。事实上Document/Encoded组合还没有真实的应用环境。
一个简单Web服务例子
现在我们来更详细的了解被使用和支持最多的RPC/Encoded与Document/Literal的style/use组合。我们将利用一个叫做 “SendTemperature” 的web方法举例来说明每一种的style/use组合,那个web方法使用的参数是一个用户自定义的复杂对象,返回一个void类型,这些在清单1中有描述。
我们选择了这么一个使用复杂数据类型例子,就是为了让各种样式之间的不同更加明显。
清单
针对这个web方法,我们将展示各种web服务样式就它们各自的SOAP请求形式怎样在WSDL中中实现,重点讲述它们的不同之处。我们利用Microsoft VS.NET和Axis SOAP 工具箱来实现。
注意,为了简单,在这篇文章中我们忽略了WSDL文件的名称空间、前缀和服务部分。清单2列出了常用的名称空间和前缀。
实质上RPC/Encoded 是一种典型的遵循“远程进程调用”模式的样式,在这种模式中客户端发送一个同步请求给服务器来执行一次操作。SOAP请求包含了要执行的方法的名称和它携带的参数。运行web服务的的服务器把该请求转化成适当的对象,然后执行操作并向客户端做出响应反馈一个SOAP消息。在客户端,该响应被用来合成一个适当的对象并返回给客户端所需要的的信息。在RPC样式的web服务中,整个方法在WSDL文件和SOAP体中被指定,包含方法的发送参数和返回值。因此我们用这种样式会有相当紧密的耦合关系。
清单3显示在RPC/Encoded样式中SendTemperature 的WSDL定义。
注意绑定的style的值被设为‘rpc’ 而use的值是‘encoded’. 在 <message> 这节中,可以有任意数目的<part> 元素,该元素包含一个type 属性,对‘rpc’ 样式来说,该属性的值是惟一的。现在我们看看调用这个SendTemperature web方法会发生什么,传送的参数是包含两个元素的数组。清单4显示了SOAP消息形式的结果。
清单4
在SOAP消息中每个参数都会被类型编码(译者注:例如xsi:type="xsd:int"),注意,在SOAP消息中的‘href’ tags 标签,实质上也是RPC/Encoded样式的一部分,它被用来查询数组中的元素。在任何literal 样式中,这个‘href’ 标签是不可用的。让我们来分析下WSDL定义和它的SOAP消息形式。
优点:
缺点:
现在我们来看同样的web方法用RPC/Literal样式实现并看看它是否能消除RPC/Encode样式中的一些缺陷。
这里的WSDL定义看起来和先前的非常相似,惟一可预见的改变就是<soap:body> 元素中‘use’ 的值由‘encoded’ 变为 ‘literal’,这显示在清单5中。就如上面所描述的,这就意味着数据类型定义并是由引用的XML Schema所提供,而不是RPC编码。
然而,使用这种样式仍然存在一个主要的缺陷。独立的XML Schema 不会告诉你消息体中的信息集合包含了些什么,你也必需知道RPC规则。因此,该schema描述的一种RPC/Literal消息但并不足以验证那种消息。
在清单6中让我们看看针对RPC/Literal样式的SOAP消息形式。注意,类型编码被完全移除掉了。
现在,我们来看看Document/Literal样式,来看一下该样式是否能减少现有的缺陷。
Document样式和上面的RPC样式最主要的不同就是,前者中客户在一个规范的XML文档中向服务器发送服务参数,而代替了后者中的一组离散的方法的参数值。这使得Document样式比RPC样式有更加松散的耦合关系。
Web服务提供者处理规范的XML文档,执行操作并向客户端作出响应,返回的也是一个规范的XML文档。在服务器对象(参数,方法调用等)和XML数据值之间并没有一种直接的映射关系。应用程序负责映射XML数据值。Document样式中SOAP消息在它的SOAP体中包含了一个或者更多的XML文档。协议并没有约束文档需要如何组织构成;这完全是在程序级处理的。另外,Document样式web服务遵循异步处理范例。
就像在清单7中显示的那样,相比RPC样式,该样式的WSDL定义有了很大的改变。
注意,绑定style 的值是‘document’ 以及 use 的值是 ‘literal’. 在‘message’ 这一节中,仅可能有一个<part> 元素,该元素包含了一个叫做element的属性。
这片断指出一个描述了soap体的全部内容的schema元素申明。注意,现在集合被定义为一个元素而不上一种类型。Document/Literal样式的主要特点,相比RPC/Literal样式的关键有益之处就是schema 元素申明完全描述了<soap:body>的内容。这样就意味着你只通过查看schema而不要任何附加规则就能说出消息体信息集中包含了什么。因此你就能接收schema描述一个Document/Literal消息并用它验证消息,这可是用RPC/Literal样式无法完成的。
现在让我们来看看在清单8中该样式相应的SOAP消息形式。注意,没有指定类型编码数据,还有操作名也消失了。
清单 8. SendTemperature 在Document/Literal 样式中SOAP 消息
下面就是对这种样式的优点和缺点的总结。
我们已经看到Document/Literal 样式消除了许多RPC/Literal样式中的缺点,另一方面,它也引入了一个新的缺点:在SOAP消息中丢失了操作名。
由于第四种样式选项,Document/Encoding样式,没有实际使用,将不对它进行描述了。而是我们将看看Document/Literal样式的扩展,即Document/Literal外覆样式。
该样式被微软推荐来消除因标准的Document/Literal 样式引起的缺点。虽然在WSDL1.1标准中没有对该样式进行说明,但现在许多SOAP工具都支持它。
让我们看清单9中的WSDL定义,以及清单10中相应的SOAP消息。
清单 9. SendTemperature在Document/Literal 外覆样式中的WSDL定义.
首先,注意在清单9中操作名被重新引入到WSDL文件的第一个‘element’ 标签中,也注意到,在清单10中SOAP消息看起来跟RPC/Literal样式的SOAP消息类似,但是有一个细微的差别,在RPC/Literal样式SOAP消息中<soap:body> 元素的子元素<SendTemperature> 是操作名,而在Document/Literal外覆样式的SOAP消息中,<SendTemperature> 是元素名,单一输入消息片断引用该元素,该样式用一种狡猾的方法把操作名重新引入到SOAP消息中。
这些就是document/Literal外覆样式的主要特征:
清单 10. SendTemperature在Document/Literal 外覆样式中的WSDL消息.
下面就是该方法缺点与优点的总结:
到现在为止,我们看到Document/Literal 和Document/Literal外覆样式相比于任何其它样式,带给我们许多的弹性和优点,但是仍存在一些有待解决的问题。
Document/Literal 和 Document/Literal 外覆样式的局限性
假设,我们如清单11中显示的那样重载了操作。
public void SendTemperature (Temperature[] TempCollection){}
public void SendTemperature (Temperature[] TempCollection, int week){}
清单11. 重载 SendTemperature 方法.
在这种情况,就不可能使用Document/Literal外覆样式,即使WSDL规范允许有重载的方法。原因就是,当我们在一个WSDL文档中增加一个外覆样式时,你将需要一个跟操作相同名字的元素(请看清单9)。当我们想在XML Schema有两个同名称的元素时问题就出现了。因此,我们为了重载的操作的来个二选一,要么寻找非Ddocument/Literal外覆样式,要么一种RPC样式。
让我们看看我们怎么在Document/Literal样式中实现它,这儿在WSDL定义的schema 节为上述的两个web方法有了修改。
清单12. SendTemperature在WSDL定义的Schema 节作了更改
我们仅向集合中添加了另一个元素,所有其它的跟清单7中保持相似。有趣的是让我们看看用VS.NET wsdl.exe 实用工具生成的客户端代理。
清单13. 为重载操作SendTemperature生成的C#代理代码
注意到有另外一个名称为“weekSpecified”的Boolean型参数被自动创建,现在客户端就能用两种方法调用这个重载操作的web方法,如果一个客户端调用的方法有week参数以及 weekSpecified 的值设为 “false”时,我们调用的是清单11中的第一个方法,还有SOAP请求也跟清单10中的一种相同。
另一方面客户端调用的方法weekSpecified 的值被设为 “true”时,那么它引用在清单11中的重载方法,以及现在的SOAP请求看起来就像清单14的那样,以一个XML标签来传递“week” 参数。
清单14. 第二个重载操作的SOAP消息形式
现在我们已经看到因Document/Literal 外覆样式引起的问题怎样通过使用标准的Document/Literal样式而巧妙地解决了。
结论
Document-centric和RPC 样式的Web服务提供了非常不同的应用环境,Document样式的web服务更加适合于企业到企业在Internet上的交互,开发一个Document样式的web服务也许需要比RPC样式付出更多的努力。我们看到了Document/Literal 样式和Document/Literal 外覆样式相比于其它设计样式带给我们更多弹性和优点。任何时候,你不要对已经存在的RPC样式进行接口连接,document样式的益处通常价值大于对服务进行接口连接。如果你设计web服务的主要需求是互用性,协调工作,那么RPC/Encoded样式就十分气馁了。
在WS-I Basic profile 1.0不提倡使用RPC/Encoded方法,推荐使用Document/Literal方法,还有RPC/Literal是惟一允许的RPC 样式的style/use组合。许多人都认为在将来的WSI-profile版本中会屏弃RPC/Literal样式 。
参考
昵称: [登录] [注册]
主页:
邮箱:(仅博主可见)
验证码: 看不清,换一个
评论内容:
登录 注册
[使用Ctrl+Enter键快速提交评论]
Powered by: 博客园 Copyright © 叶漂