技术开发 频道

SOAP Summarize

  剖析SOAP封套

SOAP1.1规范提供了下面的封套示例:

<SOAP-env:envelope
xmlns:
SOAP-ENV="http://schemas.xmlSOAP.org/SOAP/envelope/";
SOAP-ENV:
encodingStyle="http://schemas.xmlSOAP.org/SOAP/encoding/";>
<SOAP-ENV:Header>
<t:Transactionxmlns:t="some-URI">
SOAP-ENV:mustUnderstand="1"
5
</t:Transaction>
</SOAP-ENV:Header>
<SOAP-ENV:Body>
<m:GetLastTradePricexmlns:m="some-URI">
<symbol>DEF</Symbol>
</m:GetLastTradePrice>
</SOAP-ENV:Body>
</SOAP-Envelope>

  在这个例子中,getlasttradeprice请求被传送给网络上某个位置的一个存储-引用服务。该请求带有一个字符型参数,一个订单符号,并在SOAP响应中返回一个浮点数。

  SOAP封套是表示SOAP消息的xml文档的顶层元素。xml命名空间用于将SOAP标识符与应用程序的特定标识符区分开。xml命名空间在SOAP中使用很频繁,以把消息的元素的作用域限制在一个特定的领域。理解SOAP命名空间有助于熟悉xml命名空间规范。如果您没有理解命名空间,也可以简单地把它看作一种邻近的标识符,它通过把SOAP元素与特定的位置(真实的或想像的)相关联,从而有助于惟一地标识SOAP元素。

  命名空间

  上面例子中的第一个命名空间参照了在SOAP消息中定义元素和属性的SOAP模式。第二个命名空间参照了SOAP编码,即前文中讨论过的“Section5”数据类型。由于没有指定额外的通用元素编码,这种编码将适用于整篇文档。

  报头

  在SOAP封套报头示例中标识的第一个元素是一个transaction(交易)元素,它带有一个命名空间属性和一个值为1的mustUnderstand属性。既然mustUnderstand的属性值设为1,接受该消息的服务器必须在该transaction节点上执行中间处理。您可以对此作这样的解释:服务器与客户端事先已就管理该报头元素处理的语义达成了一致,因而服务器确切地知道要处理的元素的内容,本例中元素的内容是“5”。

  如果接收消息的服务器不理解transaction报头的语义,它就会拒绝请求并抛出一个错误。错误元素是SOAP报文和定义良好的机制的一个特殊部分,用于把错误信息送回给客户端。

  像这样的中间处理节点是SOAP可扩展性的一个例子。客户端在SOAP消息中包含这样的节点,以在可以处理消息的报文内容前,指示要发生的特殊的处理需要。要保证向后兼容不能提供这种处理的现有的服务器,只需把mustunderstand属性设置为0,它使操作是可选的。

  除了定义像上例中所示的transaction节点外,SOAP消息还可包含报头项目,它们用于指定节点执行身份验证处理、加密、状态的永久性、业务逻辑处理等。报头有助于把SOAP构建成一种可扩展的模态包模型。只需记住报头处理是完全独立于SOAP消息的报文的。

  报文

  上面例子中的SOAP报文包含一个XML载荷,我们可以推测RPC没有为我们对其作详细解释。SOAP不仅是一种模态包模型,它还是一种相当神秘的包模型。

  没有什么迹象清楚地显示rpc将要开始做什么。我们在报文中所看到的是几个xml元素,其中一个用命名空间进行了限制。它取决于SOAP服务器理解文档语义并执行正确的处理。事实上,服务器提供了一种架构,以有意义的方式处理xml载荷。这里的“有意义”意味着服务器在某些后台数据库上调用远程过程,以为消息报文中包含的股票-符号元素接收股票价格。所有这些魔术般的操作都是在SOAPrpc幕后发生的。

  SOAP-RPC

  SOAP消息本质上是一种从发送方到接收方的单向传输,但是SOAP经常组合到实现请求/响应机制中。要让RPC使用SOAP,必须遵循几条规则。首先,请求和响应消息必须被编码成结构类型。对一个操作的每一个输入参数,都必须有一个同名元素(或输入结构的成员)作为参数。对每一个输出参数,都必须有一个名称匹配的元素(或输出结构的成员)。

基于RPC的观点,会省略一些更早一点显示的SOAP消息。只带有报文部分的SOAP请求与响应封套如下所示:

请求
<SOAP-ENV:Body>
<m:GetLastTradePricexmlns:m="some-URI">
<symbol>DEF</Symbol>
</m:GetLastTradePrice>
</SOAP-ENV:Body>

响应
<SOAP-ENV:Body>
<m:GetLastTradePriceResponsexmlns:m="some-URI">
<price>22.50</price>
</m:GetLastTradePriceResponse>
</SOAP-ENV:Body>

  请求要调用getlasttradeprice方法。注意响应定义了getlasttradepriceresponse操作。对附加响应到响应操作尾部的一个常用的SOAP调用规则是:创建响应结构。这种输出结构包含一个名称为price的元素,它返回方法调用的结果,假定为浮点型。

  在SOAP封套中没有什么地方的数据类型是显式声明的,注意到这一点很重要,这样如果只查看SOAP消息,就不会知道符号类型或结果参数price(价格)的类型。客户端应用程序一般通过“section5”编码定义数据类型,或通过与服务器私下达成的协议来定义数据类型。在任何一种情况下,这些包含在SOAP消息中的定义都不是显式的。

  最后,为了进行rpc,需要一种低级协议如http。尽管SOAP1.0规范强制要求使用http作为传输协议,但SOAP1.1规范(及其姊妹规范“带有附件的SOAP消息”)允许使用ftp、smtp、甚至(可能)原始的tcp/ip套接字。所有这些对SOAP通用的序列化和编码规则,也适用于rpc参数。

Internet上某些地方的客户端应用程序使用Web服务。
Web服务(通过SOAP)显示对象方法。
对象方法访问Web上任意位置的远程数据。
对这些网络命题应用传递逻辑,我们可以为Web服务和SOAP下一个总的结论:某些位置的客户端可以使Web上任意位置的数据。这就是所要证明的。

  SOAP客户端使用UDDI注册来查找Web服务。不用直接操作WSDL,大多数情况下SOAP应用程序将硬连接到使用特定类型的端口和特定样式的绑定,并且它将通过UDDI动态配置要调用的、与发现的Web服务匹配的服务地址。
 
  客户端应用程序创建SOAP消息,它是一个可执行想要的请求/响应操作的XML文档。
 
  客户端把SOAP消息传送给监听SOAP请求的Web服务器上的页面。
 
  SOAP服务器解析SOAP包并在其领域调用合适的对象方法,在SOAP文档中包含的参数中传递。在SOAP服务器接收消息之前,中间处理节点可以执行SOAP报头指示的特殊功能,可视情况确定是否执行这步操作。
 
  请求对象执行指示的功能,并返回数据给SOAP服务器,它把响应打包到SOAP封套中。服务器把SOAP封套包裹在要发送回请求机器的响应对象中,如servlet或COM对象。
 
  客户端接收对象,剥离出SOAP封套并把响应文档发送给最初发出请求的程序,完成请求/响应循环。
 
  小结

  SOAP是一种基于XML的协议,它用于在分布式环境中发送消息,并执行远程过程调用。使用SOAP,不用考虑任何特定的传输协议(尽管通常选用HTTP协议),就能使数据序列化。

  用SOAP来构建平台与语言中性的互操作系统是一个好的选择。总之,SOAP和web服务已为在XML上构建分布式应用程序基础结构所需的一切都考虑好了。通过解决COM和JAVA组件对象模型之间的冲突,SOAP把多个平台在访问数据时所出现的不兼容性问题减至最少。

0
相关文章