Web 服务内幕,第 3 部分:Apache 和 Microsoft -- 良好的合作
Web 服务内幕,第 3 部分:  Apache 和 Microsoft -- 良好的合作
内容:
IBM、Microsoft 和 Apache
互操作性 -- xsi:type 属性的问题
一个扩展的股票行情服务,版本 1
家庭作业: NasdaqQuotes 版本 2
参考资料
关于作者
本文评价
SOAP 互操作性就将来临

James Snell (jasnell@us.ibm.com)
软件工程师,Emerging Technologies,IBM
2001 年 5 月

在“Web 服务内幕”的这个部分中,James Snell 通过演示使用 Microsoft SOAP 工具包 Beta 2 获得 Apache 基于 SOAP 的 Web 服务是如此的轻松,表明 Apache 和 Microsoft 可以很好地合作。

(请点击文章顶部或底部的讨论,参与有关这篇文章的讨论论坛。)

Web 服务的概念终于开始为人们所接受。但当您尝试着去实现它时,重要的是不要忘记,无论是开发平台还是编程语言,无缝跨平台互操作性是这项技术的推动力。如果您不把互操作性的问题确定下来,各种 SOAP 和 Web 服务实现都将在进行信息传递的时候遇到故障。Web 服务则会成为又一个失败的试验。

IBM、Microsoft 和 Apache
许多人可能都知道,去年春天 IBM 和 Microsoft 都发行了实现 SOAP 的第一批版本。(后来 IBM 把它的代码给了 Apache,启动了现在的 Apache SOAP 项目计划。)但是,尽管市场上所有有关 SOAP 的著作都承诺其平台互操作性,但工具却并不能提供这一点。在 SOAP 实现方式中有很多错误和细微差别,使得两种工具间几乎不能传递信息。但情况正开始改变。由于 Apache SOAP 项目和 Microsoft 两方面成员所作的一致努力,互操作性已成为一个中心议题。很多最初的问题已经消失,遗留的少数不兼容问题也正被快速而顺利地解决。

请注意:为了试验这里的两个示例,您需要下载最新版 Apache SOAP (2.1 版) 和 Microsoft SOAP 工具包 (Beta 2 或以上)。请参阅参考资料

互操作性 -- xsi:type 属性的问题
如果阅读过 developerWorks 上其他讨论 Web 服务体系结构的文章,那么您一定很熟悉以下的示意图及其代表的含义。(如您没有阅读过这些文章,我强烈建议您上图书馆看一看。)

图 1: Web 服务体系结构的基本组件

图 1 代表 Web 服务体系结构的三个基本组件所执行的三个基本操作:

  • 服务提供者通过在服务代理者那里注册来配置和发布服务;
  • 服务请求者通过查找服务代理者那里的被发布服务登记记录来找到服务;
  • 服务请求者绑定服务提供者并使用可用的服务。

在 Web 服务的世界里,三个操作都包含三个受到称赞的、和截然不同的技术:

  • 发布的服务使用“通用描述、发现和集成(UDDI) API”;
  • 查找服务使用 UDDI 和 Web 服务描述语言的组合(WSDL);
  • 绑定服务处理 WSDL 和简单对象访问协议(SOAP)。

从最基础的层次上来看,绑定操作是三者中最重要的。它包含服务的实际使用,这也是发生大多数互操作性问题的地方。简单地说,是服务提供者和服务请求者对 SOAP 规范的全力支持解决了这些问题,并实现了无缝互操作性。

不幸的是,这个简单的解决方案听起来容易实现,但实际上却难得多。SOAP 的许多可选组件形成的灵活性、及其固有的综合单一性使得我们在尝试实现它时会受到挫折。举个例子,Microsoft 和 Apache SOAP 工具包间产生的 xsi:type 属性冲突是个恼人的小问题,它可以导致一段时间内工具间互操作性的完全中断。

不要忘记,根据 SOAP 规范,一个信封中包含的各个元素可能选择性地使用 xsi:type 属性来识别 其包含的数据类型。如果服务提供者和请求者有一些其它方式来传递此信息,则它不必被包含在信封中。xsi:type 只有当无其它方式传递这些数据类型时,才应使用这个属性。

为了解决这一问题,Microsoft 建立了一个外部服务描述文档的相关性,它描述了数据类型,且能被服务提供者和请求者访问。Apache 要求任何时候都要包含 xsi:type 属性。

这两种方法都是“合法 SOAP”(尽管 Apache 采取的实现方法被认为更合法和更固定一些),但是它们彼此不兼容。附带补充一句,Apache SOAP 没有而且是依然没有理解 Microsoft 采用的服务描述语言。这种语言已有过三次反复。首先是“服务描述语言”或 SDL,其次是“服务合同语言”或 SCL,再次是现在的 “Web 服务描述语言”或 WSDL。

同时 Microsoft 也没有包含任何机制能方便地把 xsi:type 属性添加到工具生成的 SOAP 信封上。不过好在情况已有所改变。Microsoft 现在有一个新的十分灵活的 SOAP 实现方式,它包含对 SOAP 信封更好的支持和更低级别的控制。而 Apache 也已解除需要存在 xsi:type 属性的限制。这样,两个工具间就能互相自由传递信息了。

一个扩展的股票行情服务,版本 1
我们这里的示例将为免费的 NASDAQ InfoQuotes 服务创建一个基于 SOAP 的界面,请参阅 http://quotes.nasdaq.com。这个简单的服务通过 HTTP-GET 请求,以 HTML 或 XML 格式提供扩展的股票行情服务。所有这个项目的 Java 和 XML 源文件在参考资料部分。图 2 的屏幕截图显示行情服务返回的 XML 数据。

图 2:Nasdaq 行情的 XML 数据的屏幕截图

在 NasdaqQuotes Web 服务的版一上,我们将使用一个简单的 Java 类,它表达了一个单独 getQuotes 方法;将 HTTP-GET 请求的 XML 输出作为一个字符串返回,如清单 1 的代码片段所示。

配置这个 Web 服务
要将这个 Java 类配置成一个 Web 服务,应该编译它并确定它在您的 Java Web 服务器的类的路径上(假设您已安装和配置了 Apache SOAP 2.1)。 以下几步将告诉您如何从 Microsoft SOAP 上配置和调用服务。

步骤 1. 创建一个 Apache 配置描述符。Apache SOAP Service Manager 利用配置描述符(一个简单的 XML 文档)收集有关已配置服务的信息。请参阅清单 2 中的 NasdaqQuotes 服务版本 1.0 的配置描述符。

清单 2: 一个 XML 配置描述符

<isd:service xmlns:isd="http://xml.apache.org/xml-soap/deployment"
                   id="urn:NasdaqQuotes">
  <isd:provider type="java"
                     scope="Application"
                     methods="getQuote">
        <isd:java class="NasdaqQuotes" static="false"/>
  </isd:provider>

  <isd:faultListener>org.apache.soap.server.DOMFaultListener</isd:faultListener>

  <isd:mappings>
    <isd:map encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
         xmlns:x="" qname="x:symbol"
         xml2JavaClassName="org.apache.soap.encoding.soapenc.StringDeserializer"/>    
  </isd:mappings>
</isd:service>

Apache SOAP 文档中有 XML 配置描述符的详细结构说明。但是请注意我们例子中的 <isd:mappings> 部分,它从 Apache SOAP 上去掉了 xsi:type 限制。在此,我们已经声明 XML 元素 symbol 映射到 StringDeserializer 类。这个类把 XML 元素的内容转换成一个 java.lang.String 的实例。通过使用这种显式映射,Apache SOAP 无需为了提供映射信息而去寻找 xsi:type。而且,可以假定所有 XML symbol 元素的实例都可看成 String,并进行那样的串并转换。

步骤 2. 一旦已创建配置描述符,您得用它将 NasdaqQuotes 服务配置在服务的注册记录中。通过执行此命令行可以完成配置。

这里 http://acme.com/soap/servlet/rpcrouter 对应您的 SOAP RPC Router Servlet 安装。NasdaqQuotes 服务完成配置,并可以使用了。您可以通过调用本文附带的 zip 包中所提供的基于 java 的客户端来测试此服务。请参阅 readme.txt 的指导。

步骤 3. Microsoft 工具需要使用一个 WSDL 文档,它描述服务的界面和位置。既然 Apache SOAP 不包含对 WSDL 的任何支持,您就有两种选择:用 IBM 的 alphaWorks 的 WSDL 工具包来为指定的 Java 类生成 WSDL,或者自己编写 WSDL 文件。我建议您手写 WSDL (请参阅清单 3 ) -- 把东西写出来会让您对 WSDL 的结构和功能有更好的感觉。如果您需要出色的 XML 编辑器,我大力推荐商用的 XML-Spy 产品,但是其他编辑器也能用。

在编辑完 NasdaqQuotes.wsdl 文件后,该使用 Microsoft 工具了。在这篇文章所带的 zip 包中,您会发现 samp1e 目录里有两个名为 nq.vbsvq.bat 的文件。 nq.vbs (请参阅清单 4 )文件包含使用 Microsoft SOAP 工具包调用 NasdaqQuotes 服务的代码,脚本有 43 行代码,但实际 SOAP 调用的发生只有前六行(它们中的四行由初始化基本变量的代码组成)。您看,Microsoft 下了很大功夫使人们方便地使用他们的工具。

清单 4: 针对 Microsoft SOAP 工具包的 nq.vbs

Set SC = CreateObject("MSSOAP.SoapClient")
SC.mssoapinit "D:\Services\NasdaqQuotesClient.wsdl", "", "", ""
Res = SC.getQuote(WScript.Arguments(0))

通过执行 nq.bat 文件,您可调用 NasdaqQuotes 服务,把您要查询的代号作为一个命令行参数来传入(请参阅图 3)。

图 3: 从命令行运行 NasdaqQuotes

家庭作业: NasdaqQuotes 版本 2
NasdaqQuotes 服务版本 1.0 非常简洁地显示了 Microsoft 和 Apache 有能力互相进行便捷的信息传递。但是行情服务返回的信息是以字符串的形式返回的,这意味着还需更多努力来改善服务。例如:我们可能要求 SOAP 信封实体以 XML 形式来返回查询结果,而不是以返回字符串的形式。在 zip 下载包中的 NasdaqQuotes2 Service 示例能让您采取正确的步骤。您的家庭作业是仔细研究这个例子里的内容。和平常一样,如您有任何问题,请告诉我,看看我是否能帮助您。

参考资料

关于作者
James Snell 是一位撰稿人和开发人员,他也是 IBM Web 服务开发小组最新成员之一。他在进入 IBM 之前,已经具有关于定制企业应用开发和商家对商家这些方面的背景,而且他对 Web 技术前沿方面有极大的热情。可以通过
jasnell@us.ibm.com 与他联系。

(c) Copyright IBM Corp. 2001, (c) Copyright IBM China 2001, All Right Reserved
  关于 IBM  |  隐私条约  |  法律条款  |  联系 IBM