级别: 初级 Jordi Albornoz (jordi@us.ibm.com), 软件工程师, Advanced Internet Technology,IBM
2002 年 10 月 01 日 有无数的标准对 Web 服务进行了定义。每个标准都全面到可以独立于其它的标准,但同时针对性又强到只解决 Web 服务的一小部分难题。SOAP、WSDL、XML Schema、HTTP 等标准之间的交互可以变得非常复杂。这一点,加上各个标准的解释的不同之处以及标准之间的关系,就造成了互操作性问题。软件包经常声称支持“Web 服务”或某个特定的标准,比如 SOAP 或 WSDL。所以开发者可能会因为两个产品都自豪地标上了这种首字母缩写就以为它们可以很容易地互相通信。但是,编写这些标准时并没有说产品包装盒上简单的首字母缩写就能够确保甚至暗示其兼容性。本系列将通过描述一些流行的 Web 服务标准的特定用途,解释支持这些标准中的每一种实际意味着什么,这些标准如何进行交互以及哪里容易发生兼容性问题(这一点最重要),从而引导您了解这些标准。本文还将讨论其中很多标准被修订后将出现的相关改变之处。在这个系列的第一篇文章中,Jordi Albornoz 将介绍标准之间的复杂交互问题并描述与 SOAP 有关的一些问题。
问题介绍
Web 服务这个概念非常抽象。W3C 的 Web Services Architecture 工作组目前给出的定义粗略地把它定义可通过使用 XML 进行消息传递、描述和发现的网际协议访问的软件应用程序。当您问不同的人 Web 服务是什么时,他们告诉您 Web 服务就是分布式计算的化身、概括或是再次创新。它是 Web 版本的 CORBA 或 DCE,但远不是一般意义上的远程过程调用。由于 Web 服务这个概念是如此抽象,它的范围已超越了任何一个标准或技术。但即便 Web 服务这种思想很全面,软件开发者仍是主要把三个特定的标准当作 Web 服务基础架构的核心。
第一个是 Web 服务描述语言(Web Services Description Language,WSDL),它是一种格式,用来指定 Web 服务公开的操作、服务公开这些操作时所使用的具体传输机制以及服务的位置。第二个是 SOAP,一种强行规定 XML 中消息结构的协议。最后一个是 XML Schema,一种用来描述 XML 数据类型的格式。它们分别为我们提供了一种接口定义语言、一种有线格式(wire format)和一个类型系统,所有这些都是与平台无关的。这样,它们就组成了一个与平台无关的分布式计算框架所必需的基本内容。然而,这些标准并不仅仅是与平台无关的。它们还与传输无关、与语言无关,并且是可扩展的。所以我们就有了这样一个分布式计算框架,它有可能在最适合任务的传输上实现,并且可以用最适合某个特定任务的技术(比如新类型系统)来扩展。这种一般性的确可以使标准的适用期变得出奇的长,但同时也会使系统变得更复杂,带来负面影响。
所有这些意味着与 Web 服务进行通信不只是需要理解 WSDL、SOAP 和 XML Schema。这些信息是不够的。我们还需要理解 WSDL 的特定扩展、发送 SOAP 信封时使用的特定传输和服务所需的数据编码以及其他信息。就象大家经常开玩笑说 XML 是这样一个标准,它的唯一目的是产生更多的标准。Web 服务的一系列标准好象都有这个特征。无疑,我们不久将看到以某种特定的方式使用 WSDL 和 SOAP 的更高级规范。在 Web 服务术语中,这些更高级的规范经常被称为绑定。此外,这些主要规范中的每一个都包含一些会妨碍互操作性的含糊之处,因此大家就需要理解规范的明确解释。每个标准都有可扩展的程度、可选的部分和含糊之处,这些将导致其实现在功能上的不同。
SOAP 的含义
有一个标准最常与 Web 服务关联在一起,同时也最普通、最常被曲解,因此最容易引起互操作性问题。这个标准就是 SOAP。就象 W3C 纪要(W3C 正把 W3C 纪要精制成一个官方推荐)中定义的那样,SOAP 的最常用版本是 SOAP 版本 1.1。SOAP 经常被当作一个 RPC 框架、一个用来访问 web 上功能的协议。但准确地说,SOAP 本身并不是这些东西。SOAP 只是一种消息格式。SOAP 只是规定了消息由 Envelope 元素后跟可选的 Header 元素以及 Body 元素组成。它定义了一些关于如何处理消息头的语义,比如头的处理是不是可选的。它还定义了一种在消息内部发送错误的格式。
拥有标准消息格式的主要好处就是可以通过任何方法传输消息,并且使消息原样到达接收方,也可以说这就是要求标准消息格式的整个目的。所以,从理论上来说,SOAP 服务器只需采用一个信封作为输入,而不必担心这个信封如何到达它这里。这样就可以通过适合应用程序的传输协议来传送消息。但这意味着声称支持 SOAP 作为通信方法只能说是针对消息格式的,而不可以说是针对传输协议或有效负载格式的。所以,除非代码构成用任意 XML 作为有效负载的 SOAP 信封,否则,声称一个客户机 API 支持任意 SOAP 服务的声明通常情况下都绝不是真的。这种声明大多数都会有关于传输和数据编码的隐式假设。通常只有 HTTP 被作为传输协议支持。
将数据组织为 XML
较高级的 SOAP API 经常会通过自动将某种语言的本机数据类型组织为 XML(然后 XML 将被用作信封的有效负载)来简化 SOAP 信封的创建过程。执行这种工作的 API 会同样就 SOAP 服务的行为方式做出隐式假设。既然 SOAP 标准对有效负载的格式没做什么规定,那么这些较高级的 API 如何确保当它们将“int”数据类型转换为
XML 元素时另一端的服务器仍然能正确识别它?一般情况下是无法保证的。提供这种保证的任何 API 都会对数据编码进行隐式假设。为了说明这一点(即 SOAP 有效负载数据的随意性)以及在客户机与服务间就数据编码达成一致的需要,我们采用了下面的示例。
假设有一个提供我办公室内温度的即时报告的 Web 服务。它只是返回一个表示温度的浮点数。所以我返回一条如
清单 1所示的消息。按照 SOAP 标准,
清单 1 内的消息是一条正确的 SOAP 消息。
清单 1:一个带有用不常见的方式编码的有效负载的有效 SOAP 信封。
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<officeTemperature precision="double" signbit="0"
exponentfield="1029" significand="1.0203125" />
</soap:Body>
</soap:Envelope>
|
但请注意,这个有效负载看起来非常奇怪,不象是只返回一个浮点数的有效负载。事实证明是因为我选择了用假定的工具箱(这种工具箱就用假定的方式对浮点值进行编码)来构建我的假定 Web 服务。根据 IEEE 浮点标准,它只是值的文本表示。您可以想象得到这种序列化对于象科技应用程序这样的东西会比较有用,因为在科技应用程序中舍入方面的错误是不可容忍的,所以需要一种用来对浮点值进行编码的非常有针对性的格式。现在假设我要用一种非常普通的 Java 技术 SOAP 工具箱为我的 Web 服务编写客户机。我试图使用这个工具箱的很不错的高级功能来使自己只需调用 Web 服务就可以得到 Java 编程语言的一个简单的老基本数据类型
double。但我发现这个工具箱无法用那种方式处理我的服务。当它看到
officeTemperature 元素时,并不把这个元素当作一个浮点值。原因是我选择的那个 Java 客户机工具箱只支持某种特定的数据编码,而不支持我的 Web 服务正在使用的数据编码。
当对 SOAP 规范的需求被提出时,许多人都认识到了为 SOAP 信封内的数据编码制订一些标准规则的需要。当时的想法是要使服务和客户机的编写工作更加容易,简单的服务和客户机只需同意在向 XML 转换时遵守一套数据编码规则即可。结果就出现了 SOAP 编码(SOAP Encoding)这套声名狼籍的规则,根据在规范中的位置,这套规则通常被称为“Section 5”。SOAP 编码只是规范中的一个暗示。因此,当一个产品声明与 SOAP 兼容时,它们并不明确声明与 SOAP 编码兼容。这就是这些较高级的 API 一般情况下不能正确地自动组织数据类型的原因。SOAP 在传输方面的可扩展性经常需要进行导致兼容性问题的隐式假设,有效负载数据编码方面的可扩展性也是如此。因此,要想知道客户机 API 是不是将生成特定的 Web 服务能够理解的 SOAP 信封,您必须明确知道该 Web 服务所期望的数据编码以及该客户机 API 是否支持这种编码。
清单 2 显示我的服务使用 SOAP 编码对响应有效负载进行编码时可能采用的许多方法之一。
清单 2:一个带有用 SOAP“Section 5”编码进行编码的有效负载的有效 SOAP 信封。
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soap:Body>
<officeTemperature xsi:type="xsd:double">65.3</officeTemperature>
</soap:Body>
</soap:Envelope>
|
这才是开始
SOAP 的一般性意味着并非所有使用 SOAP 的系统都可以很容易地进行通信。由于 SOAP 与传输无关,并且不强制使用哪种数据编码格式,所以我们不能仅仅知道一个服务支持 SOAP,还必须了解有关该服务的其他信息。需要理解的最重要一点是 SOAP 只是一种消息格式。在这个系列的下一篇文章中,我将解释 SOAP 经常被曲解的另一个方面,即数据编码,它造成了许多互操作性问题。上面的示例说明我们必须了解数据编码以便与 Web 服务正确地通信。但在许多情况下,这是不够的。我将尽力说明不同数据编码的用途,并深入讨论与那个特别容易让人感到迷惑的 SOAP Section 5 编码有关的具体问题。我还将开始讨论 WSDL 以及它与 SOAP 和其他 Web 服务标准的关系。
参考资料
关于作者  | 
|  | Jordi Albornoz 是 IBM 的 Advanced Internet Technology 小组的一名软件工程师。他曾经致力于
Sash脚本编制环境以及
SashXB,目前正在开发面向 JavaScript 的高级 Web 服务 API。他毕业于卡内基-梅隆大学(Carnegie Mellon University)的计算机科学系,并获得了 IBM 的
天才孵化(Extreme Blue)计划的结业证书。您可以通过
jordi@us.ibm.com与 Jordi 联系。
|
对本文的评价
|