IBM®
跳转到主要内容
    中国 [选择]    使用条款
 
 
Select a scope: Search for:    
    首页    产品    服务与解决方案     支持与下载    个性化服务    
跳转到主要内容

developerWorks 中国  >  SOA and Web services  >

逐步了解 Web 服务标准,第 2 部分: SOAP 和 WSDL 的更多复杂性

对 SOAP 数据进行编码时会遇到的一些问题

developerWorks
文档选项

未显示需要 JavaScript 的文档选项


级别: 初级

Jordi Albornoz (jordi@us.ibm.com), 软件工程师, Advanced Internet Technology,IBM

2003 年 2 月 01 日

在前一篇文章中,Jordi 解释了每个 Web 服务标准是如何被设计为非常全面,从而实现可扩展性的。(请参阅 参考资料)。但是,每个标准只能解决创建分布式计算框架时的一个非常特定的问题。因此,仅了解一种产品支持 SOAP 并不足以确定另一种作出类似声称的产品是否能与其互操作。您还必须了解更多的细节,如应该被用于交换 SOAP 信封的传输以及用于信封有效负载的数据编码。究其本质,SOAP 只不过是一种消息格式。就用于传送消息的传输以及每条消息中包含的数据的格式而言,SOAP 是可扩展的。数据编码可扩展性对于 SOAP 消息的交换非常重要。所以,用于对数据进行编码的规则也被创建以供参考。在本文中,Jordi 解释了数据编码与 SOAP 及其他标准之间的关系。

无数的标准对 Web 服务进行了定义。每个标准都全面到可以独立于其他标准,但同时针对性又强到只解决 Web 服务的一小部分难题。SOAP、WSDL、XML Schema、HTTP 等标准之间的交互可以变得非常复杂。这一点,加上各个标准的解释的不同之处以及标准之间的关系,就造成了互操作性问题。软件包经常声称支持“Web 服务”或某个特定的标准(如 SOAP 或 WSDL)。所以开发者可能会因为两个产品都自豪地标上了这样的首字母缩写就以为它们可以很容易地互相通信。但是,编写这些标准时并没有说产品包装盒上简单的首字母缩写就能够确保甚至暗示其兼容性。在本系列的这第二篇文章中,我继续讨论 SOAP,并使用一个假定返回我办公室内温度的服务。我在 清单 1 中给出了一个示例,它说明了如何用 SOAP Section 5 编码为服务的响应信封进行编码。


清单 1. 带有用 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 Section 5 编码只是经常被使用的编码之一。另一种很常用的编码按 SOAP 术语来说并非真正的编码。这种编码通常被称为文字编码。文字编码仅表明 SOAP 消息的有效负载完全是由一个特定的模式(通常是 XML Schema)定义的。这个领域中存在着许多误解,因为 SOAP Section 5 还经常被解释为也要利用 XML Schema。SOAP Section 5 编码规范在它对 XML Schema 数据类型的要求方面被认为是模棱两可的。SOAP Section 5 编码本身并不能由 XML Schema 文档完全表达清楚,这会使误解越来越深。为了消除这种误解,我将总结编码概念的精髓。





回页首


您的数据看上去像什么?

SOAP 上下文中的编码只不过是一组规定如何将指定的数据模型转换为 XML Infoset 的规则。道理在于:这些 SOAP 信封就是一个 XML Infoset,因为 SOAP 信封都是 XML 格式的。但并非所有的数据都以类似 XML Infoset 的层次数据结构存储。所以,对于这样的数据,您就需要一种转换机制,或者说一种编码,简单地说也就是一种达成一致的用来序列化和反序列化数据的方式。

不能直接适合 XML Infoset 的数据结构的一个例子就是图,即通过边互相任意连接的一组节点。XML Infoset 与树结构非常相似,而且易于构造不是树的图(只需以不产生明显的根节点的方式连接节点)。SOAP Section 5 编码规定了将图序列化为 XML 的方式。其方式为定义诸如 id 属性和 ref 属性之类的 XML 构造来将图结构序列化为 XML,从而使接收方可以在另一端创建相同的图。SOAP Seciton 5 编码中选择图作为一种数据模型是因为,对于进行 RPC 而言,树结构常常限制过多,而编码本来就是为了方便 RPC 而设计的。

请注意,我在讨论 SOAP 编码数据模型的时候并未涉及过任何与 XML Schema 数据类型有关的内容。这是因为编码中没有任何强迫使用数据类型的内容。编码只处理节点和边的抽象概念。这意味着即使 SOAP 编码本身足够全面,声称能够使用 SOAP 编码组织数据的代码也不可以在没有作出另一个隐式的假设的情况下声称能够将该数据组织为一种语言的本机类型。

例如,请注意,在 清单 1中,遵循 SOAP 编码规则进行了编码的有效负载利用 XML Schema 将元素注释为 double。要是我已经选择了使用除 XML Schema 之外的另一种类型系统,该怎么办?例如,我可能使用了 XML 数据简化(XML-Data Reduced,XDR)规范的数据类型集合对 清单 1中的节点进行了注释。如果我已经这么做了,这个 SOAP 信封看起来就应该如 清单 2 中所示。


清单 2. 带有用 XDR 数据类型注释的 SOAP Section 5 编码进行编码的有效负载的有效 SOAP 信封
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
        xmlns:dt="urn:schemas-microsoft-com:datatypes"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <soap:Body>
        <officeTemperature xsi:type="dt:r8">65.3</officeTemperature>
    </soap:Body>
</soap:Envelope>

即使根据 SOAP 编码对这个 SOAP 信封进行了适当的编码,工具箱可能也已经不能处理它了。我本来还可以选择完全省略 xsi:type属性,而该 SOAP 信封将仍为有效的已编码形式。所以,即使您高级别的 API 用 SOAP Section 5 编码为您创建一个 SOAP 信封,而且您感兴趣的 Web 服务期望通过 SOAP 编码对数据进行编码,这个 SOAP 信封可能还是不起作用。这是因为 Web 服务很有可能期望的不仅仅是针对其数据的 SOAP 编码。它还未能告诉您它期望用一个类型规范对您发送给它的已编码的图中的每个节点进行检测。它需要知道节点中数据的类型。SOAP 或 SOAP 编码不能满足这样的要求,所以大多数 Web 服务要求检测带有 XML Schema 数据类型的类型。这只是因为 XML Schema 数据类型是一组被广泛理解的数据类型,它们被设计为由 XML 使用。通常,Web 服务将要求有效负载数据仅使用 XML Schema 内建类型,而不使用从这些类型中派生的任意类型。

这意味着,如果您想要知道特定的客户机 API 是否将生成与特定的 Web 服务兼容的 SOAP 信封,您需要知道 API 和服务是否支持特定的传输、特定的编码样式以及在使用 SOAP Section 5 编码的情况下是否支持可能需要的特定类型系统。SOAP Section 5 编码中的这个类型系统模糊性是许多开发者倾向于将文字编码用于他们的 Web 服务的一个原因。

跳过 SOAP 编码

文字编码就意味着 Web 服务和客户机同意使用数据的精确格式,而不是让它们同意遵循一组用于序列化数据的规则。这种差别经常被称作读者正确(reader-makes-right)与作者正确(writer-makes-right)。文字编码可以只包括服务创始人编写的某个没有固定格式的文档,该文档精确地描述了有效负载的具体情况。但是,如果该格式是用 XML Schema 来描述的,工具箱将读取该格式并用它来自动将数据从本机语言结构组织为 XML。所以,在这种情况下,工具箱只需了解整个 XML Schema 规范,而不需了解若干特定的编码规则的组合,也不需了解所选的类型系统。剩下的与使用文字编码有关的唯一问题就是工具将如何找到特定服务的 XML Schema。这个问题由 WSDL 解决。

没有一种机器可以理解的标准能够用来描述 SOAP Section 5 编码使用的数据模型,所以,开发者正倾向于利用 XML Schema 的文字编码,这是因为当使用 XML Schema 时,开发者工具常常把这些功能作为语法帮助提供,也作为对 XML Schema 建模的数据的验证支持。但是,这种情况可能很快就会改变,因为 Web Services Description 工作小组正在考虑创建一种语言以将 SOAP Section 5 数据模型描述为 WSDL 版本 1.2 中的 SOAP 的 WSDL 绑定的一部分。





回页首


SOAP 总结

我希望 SOAP、SOAP 编码和 XML Schema 之间的关系现在明朗多了。我希望我已经消除了很多误解,它们使开发者相信 SOAP 是他们所需要的一切的解决方案。SOAP 是一项很强大很重要的技术,但是它有非常特定的用途和作用域。您需要理解的一个概念是,SOAP 只不过是一种消息格式,这一点很重要。为了能够与 Web 服务通信,您需要知道的不仅仅是它支持 SOAP。用于使用和创建服务的大多数 SOAP API 要么显式地、要么暗示地指定了它们所期望的数据编码以及它们所支持的传输。您需要全面地评估用于您特定的任务的技术是否是兼容的。





回页首


WSDL 适合于哪些情况

一些人说,SOAP 是您创建和使用 Web 服务所需要的一切。因为 SOAP 只不过是一种消息格式,所以这种说法严格来说并不正确。如果您选择一个传输协议(如 HTTP)和一种数据编码(如 SOAP Section 5 编码),您就拥有了创建和使用 Web 服务所需的所有部分,这是真的。然而,在编写了几个客户机和服务之后,您将看到接下来会出现重复工作,开发过程中还有可以自动化的余地。

SOAP 服务将需要某个解释了被公开的操作以及这些操作的参数的文档。但是,如果这个文档不符合机器可以理解的标准格式,那么它就类似于给某人一个实现有用功能的共享库,但没有包括库的头文件。从理论上讲,如果您在某个文档中解释了被公开的方法,您就可以使用这个 SOAP 服务了。然后,您可以将库装入到您的地址空间中并使用函数指针调用方法。但是您为什么必须这么做呢?

这么做基本上是自己从写好的文档中重新创建头文件。没有多少人会怀疑头文件的有用性。在 Web 服务的情况下,类似的文件是一个 Web 服务描述语言(Web Services Descriptin Language,WSDL)文档。它是用于 Web 服务的头文件。它是描述了 Web 服务的操作的标准,而且可以被机器理解。它还指定 Web 服务用来公开这种功能的有线格式(wire format)和传输协议。它还可以用一个类型系统描述有效负载数据。

在本系列的下一篇文章中,我将讨论与 WSDL 有关的问题。我将试着总结 WSDL 提供的内容的本质,而且我将在讨论 SOAP 和 WSDL 的同时提出一些与创建和使用 Web 服务有关的实际建议以促进互操作性,我还会提出关于 Web 服务标准的将来的一些设想。



参考资料



关于作者

作者

Jordi Albornoz 是 IBM 的 Advanced Internet Technology 小组的一名软件工程师。他曾经致力于 Sash 脚本编制环境以及 SashXB,目前正在开发面向 JavaScript 的高级 Web 服务 API。他毕业于卡内基-梅隆大学(Carnegie Mellon University)的计算机科学系,并获得了 IBM 的 天才孵化(Extreme Blue)计划的结业证书。您可以通过 jordi@us.ibm.com 与 Jordi 联系。




对本文的评价










回页首


IBM 公司保留在 developerWorks 网站上发表的内容的著作权。未经IBM公司或原始作者的书面明确许可,请勿转载。如果您希望转载,请通过 提交转载请求表单 联系我们的编辑团队。
    关于 IBM 隐私条约 联系 IBM 使用条款