Web 服务互操作性和 SOAP
发表于:2007-06-30来源:作者:点击数:
标签:
摘要:本文概要说明了在通过 SOA P 进行 RPC 调用时当前实际存在的互操作性问题,同时讨论了导致互操作性问题的三个 因素:HTTP 问题、XML 问题和 SOAP 间断性。 目录 简介 什么是 SOAP? 常见的互操作性问题 传输问题 XML 问题 SOAP 问题 后续话题 简介 当前
摘要:本文概要说明了在通过
SOAP 进行 RPC 调用时当前实际存在的互操作性问题,同时讨论了导致互操作性问题的三个
因素:HTTP 问题、XML 问题和 SOAP 间断性。
目录
简介
什么是 SOAP?
常见的互操作性问题
传输问题
XML 问题
SOAP 问题
后续话题
简介
当前有多种创建应用程序的平台。但每种平台都习惯于使用自身的协议(本质上通常是二进制代码)来实现机器间的集
成。因此,跨平台的应用程序在数据共享方面的能力相当有限。认识到这些限制后,人们一直在致力于建立有关数据格式
和数据交换方面的标准,藉此以实现“不论服务采用何种软件,使用何种硬件,都能够跨越这一传统的界限以 Web 的形式
无缝地将它们集成在一起”这一远景目标。目前,这一目标已迅速发展成为一种新的计算范例。
该目标的核心是互操作性概念,即不同系统能够无缝地进行通信和共享数据。这也是 Web 服务追求的目标。Web 服务是一
种可以用标准 Internet 协议来访问的可编程应用逻辑;从另一个角度来说,Web 服务是有关机器间和应用程序间透明通
信的、借助于 Web 的标准的具体实现。
目前,实现机器间消息传递的 Web 服务技术多种多样,例如简单对象访问协议 (Simple Object A
clearcase/" target="_blank" >ccess Protocol,
SOAP)、Web 服务说明语言 (Web Service Description Language, WSDL) 和超文本传输协议 (HyperText Transfer
Protocol, HTTP)。这些消息的复杂程度各不相同,既有简单的方法调用,也有复杂的订单提交。在 Web 服务的功能中,
最一般但又较高级的功能是实现 RPC(远程过程调用)形式的通信(通过 RPC,一台计算机上的程序可以执行另一台计算
机的程序。)本文从实用的角度介绍了在使用 SOAP 进行 RPC 形式的通信时当前常见的互操作性问题,以后还将撰文探讨
有关通过 SOAP、WSDL 以及其它协议传送消息的问题。
图 1:Web 服务路线图:有线协议元素、服务说明和发现
什么是 SOAP?
SOAP 是 Simple Object Access Protocol(简单对象访问协议)的缩写。该协议的当前版本为 1.1,其具体规范发布在下
列站点上: www.w3.org/tr/soap(英文)。SOAP 以 XML 为基础,说明了机器间通信的消息传送格式。此外,它还包括几
个可选部分,用于描述方法调用 (RPC) 和详细说明通过 HTTP 发送 SOAP 消息的方法。(有关 SOAP 和 Web 服务的详细
背景
知识,请参见 Web 服务的平台(英文)。)
以下是一个典型的 SOAP 请求(包括 HTTP 标头),它请求名为 EchoString 的 RPC 方法调用,并将一个字符串当作参
数:
POST /test/simple.asmx HTTP/1.1
Host: 131.107.72.13
Content-Type: text/xml; charset=utf-8
Content-Length: length
SOAPAction: "http://soapinterop.org/echoString"
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:tns="http://soapinterop.org/" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<tns:echoString>
<inputString>string</inputString>
</tns:echoString>
</soap:Body>
</soap:Envelope>
如上所示,该请求将方法名编码为 XML : <tns:echoString>,将字符串参数编码为 <inputString>。它所代表的 C# 方法
类似于以下内容:
public String echoString(String inputString);
以下是来自
服务器的响应:
HTTP/1.1 200 OK
Content-Type: text/xml; charset=utf-8
Content-Length: length
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:tns="http://soapinterop.org/" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<tns:echoStringResponse>
<Return>string</Return>
</tns:echoStringResponse>
</soap:Body>
</soap:Envelope>
有关序列化字符串数据类型以及方法调用形状的规则在 SOAP 1.1 的第 5 节和第 7 节 (www.w3.org/tr/soap(英文))
中定义。
常见的互操作性问题
当执行 RPC 形式的 SOAP 消息传送时,可能会因为多种原因导致互操作性问题。有趣的是,许多互操作性问题都不是
SOAP 本身的问题,而是基本传输引擎或 XML 引擎所导致的互操作性问题。也就是说,互操作性问题可能是:
HTTP 问题
XML 问题,或
SOAP 间断性
还应指出的是,这些规范的制定者也有考虑不周的地方,他们有时可能会模棱两可,这样就很难确定唯一正确的行为。
传输问题
XML Web 服务消息的核心在于发送消息的传输机制。当通过 SOAP 进行 RPC 调用时,HTTP 是目前最为常用的传输机制。
这意味着 SOAP 堆栈之间必然存在 HTTP 互操作性问题。
HTTP 互操作性问题的一个简单示例就是 SOAPAction 的使用。SOAPAction 是一种 HTTP 标头,它必须存在于通过 HTTP
传送的 SOAP 消息中。此标头可以赋以多个不同的值,例如:
SOAPAction: "http://tempuri.org/"
SOAPAction 的值虽然可以完全为空,但必须用引号引起来:
SOAPAction:
问题就在这儿:如果服务器要求空值 SOAPAction,有些客户端将无法满足这一要求,因为并非所有 HTTP 客户端 API 都
具有设置空 HTTP 标头值的方法。这种问题可能存在两种解决方法:修正客户端 API 和/或确保服务器不要求空值
SOAPAction。通常,避免这类问题的唯一方法是确保所使用的 HTTP API 稳定强壮,并且已知可以在 Web 上工作。即便如
此,这类问题仍可能出现;要彻底消除它们,测试可能是唯一的方法。
XML 问题
这是可能存在的第二类互操作性问题,它们涉及到 XML 语法分析和 XSD 架构处理。SOAP 使用 XML 和 XML 架构作为核
心,因此这两者的互操作性是 SOAP 互操作性的基础。
有一个有趣的互操作性问题示例,它同时涉及到 XML 语法分析和 HTTP 传输,并且与字节顺序标记 (Byte Order Mark,
BOM) 相关。当通过 HTTP 发送数据时,您可以在 Content-Type 标头中指定数据的编码形式,如 UTF-16 或 UTF-8。也可
以通过插入一组用来指定编码形式的字节来表示某一段 XML 的编码形式。当发送 UTF-16 时,即使 Content-Type 标头中
指定了编码形式,也仍需要 BOM 来指示是 big-endian 还是 little-endian;但对于 UTF-8,BOM 则是不必要的。例如:
HTTP/1.1 200 OK
Content-Type: text/xml; charset=utf-8
Content-Length: length
n++<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:tns="http://soapinterop.org/" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<tns:echoStringResponse>
<Return>string</Return>
</tns:echoStringResponse>
</soap:Body>
</soap:Envelope>
示例中的前三个字符是字节顺序标记的十六进制代码,用于指示编码形式为 UTF-8,不过,您可以看到,Content-Type 也
指出了这点。即使不需要,但是有些实现方案仍会为 UTF-8 发送 BOM。而其它实现方案有了 BOM 反而无法处理 XML。为
了解决这一问题,应避免在不需要的时候发送 BOM,并且应正确处理 BOM。由于在处理 UTF-16 消息时需要 BOM,所以在
这种情况下务必要正确处理 BOM。虽然没有任何单一的方法可以提早解决这些问题,不过当发现问题时,最好的方法就是
参考描述标准的具体规范(通常在 W3C 上可以找到),然后应用这些规范来评判遇到的问题。
SOAP 问题
现在,我们将讨论问题的核心:SOAP 问题本身。如上所述,SOAP 的互操作性首先要求解决传输(通常是 HTTP)和 XML
问题。解决这两个问题之后,再来解决 SOAP 问题。
SOAP 本身的问题相对简单。它要求将消息装入信封,并将消息的实际内容放在正文元素中。SOAP 使标头等元素成为可选
项,对正文元素中可包含的内容允许存在一定的灵活性。以下是一个简单的 SOAP 消息示例,大多数堆栈与它进行互操作
时不会存在问题:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body >
<foo />
</soap:Body>
</soap:Envelope>
虽然这个示例不是十分有趣,但是 SOAP 还提供一种对常见数据类型进行编码的方法(请参见 SOAP 规范的第 5 节),它
进一步说明了如何对 RPC 方法调用进行编码。您可能已注意到,在前面的示例中,方法名是正文的子标记,参数则是方法
名的子标记。
即使不用这么麻烦,您也可以找到许多有趣的互操作性问题。例如,SOAP 规范规定,如果您收到 mustUnderstand 属性设
置为“1”的 SOAP 标头,就必须理解它,否则将出错。但许多实现方案并没有做到这点。以下是 mustUnderstand 标头的
示例:
HTTP/1.1 200 OK
Content-Type: text/xml; charset=utf-8
Content-Length: length
n++<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:tns="http://soapinterop.org/" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header>
<Foo SOAP-ENV:mustUnderstand="1">
Hello!
</Foo>
</SOAP-ENV:Header>
<soap:Body soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<tns:echoStringResponse>
<Return>string</Return>
</tns:echoStringResponse>
</soap:Body>
</soap:Envelope>
这个示例是通过 SOAP 互操作性测试发现的众多问题之一。有关现已发现的互操作性问题的更多示例,请参见
http://groups.yahoo.com/group/soapbuilders(英文)中的档案。总之,为了确保 SOAP 在实现 RPC 形式通信时的互操
作性,全世界的 SOAP 构建者已经做了很多工作,并取得了丰硕的成果。从 5 月 8 日到 5 月 10 日,在拉斯维加斯将举
行 Networld+Interop 会议,到时,SOAP 团体的许多成员将在会上将充分展示这方面的成果。如果您在使用 SOAP 堆栈或
对其感兴趣,欢迎惠顾这次演示会。
另外,有关 XML Web 服务的许多讨论和测试已经在 http://groups.yahoo.com/group/soapbuilders(英文)、
http://www.mssoapinterop.org/(英文)和 http://www.xmethods.net/ilab/(英文)等站点上进行。这些站点包含到许
多互操作性测试端点的链接。构建 SOAP 堆栈的所有人员都应该阅读这些档案并参与互操作性测试。
后续话题
本文简要概括了在 XML Web 服务领域中发现的一些早期互操作性问题。不过,这方面的讨论并不会就此停止。除了通过
HTTP 进行 RPC 调用之外,SOAP 还有许多更为有趣的情况需要讨论。其中包括“document”形式的消息传递、基于 SMTP
和其它传输机制的 SOAP、WSDL 以及各种 SOAP 标头测试 - 所有这些都值得在今后的文章中进行讨论。
原文转自:http://www.ltesting.net