在电影Fight Club(“战争俱乐部”)中,Brad Pitt和Edward
Norton是一对密友??心理上对立的两个极端??两个小伙子尝试互相 通信,但十分艰难。令人感兴趣的是??没有给出提示台词??影片中
的大部分剧情都围绕着肥皂的生产进行,看上去像是把多个角色以独一 无二的、令人意想不到的方式绑在了一起。
现在快进到一种不同类型的剧情,Microsoft和Sun这两个软件密友
在Internet也出演了这段剧情,他们每一方都用经过良好定义的视点, 试图弥合彼此间的差异,并与另一方之间建立一条通信线路。进入SOAP
,即简单对象访问协议。
简介
SOAP,简单地讲,就是允许Java对象和COM对象在分布式、分散的、
基于Web的环境中彼此通话。更一般地讲,SOAP允许任何类型的对象(或 代码)??在任何平台上,以任何一种语言??相互通信。目前,已在2
0多个平台上,以60多种语言实现了SOAP。突然之间,任何地方的对象, 无论本地或远程的,无论大或小,都可以互操作。Brad
Pitt和Edward Norton,就像两种截然不同的对象,最终能够通信。
回顾一下这种技术,我最开始将在Web服务的大环境下介绍SOAP, SOAP作为一种协议,它与UDDI(通用描述、发现和集成)一起提供了业
务间注册和消息传递服务。我还将讨论揭示“发布-查找-绑定”范例的 基于Web的基础,并介绍SOAP包装、传输和发送机制。
Web服务的发展
先把所有大肆张扬的宣传放在一边,SOAP仅仅只是一种组件??虽然 是一种中心组件??用于把Web的蓝图描述成用于业务操作的、基于标准
的、语言与平台中性的架构。这些业务操作通常被标上了“Web 服务” 的通用标签,但是Web服务自身也只是一种支持它们的良好的基础。相应
地,Internet有一种快捷的n层基础。
网络分层
在Web服务的发展过程中,有3种网络层是显而易见的:TCP/IP、
HTTP/HTML和XML。现在这3个层相继构建在彼此的顶上,并保持相互之间 的兼容性。
第1层,TCP/IP协议,主要关注的是以分组形式通过线缆传输数据。 作为一种确保通过公共网络传输的协议,TCP/IP强调数据传输的可靠性
和物理连通性。起初是把专用网络粘合在一起,现在则是用Web中枢协议 来连接网络,更高层次的标准协议如HTTP就是依赖于这种中枢协议的。
第2层,HTTP上的HTML,它是一个显示层,自身关注的是基于浏览器 的搜索、检索和信息共享。它强调的是基于GUI(图形用户界面)的导航
和显示格式的处理。在许多方面,HTML更多地是用于显示,而不是转到 别的网页上,并且在可扩展性和真正的编程能力上有所欠缺。虽然如此,
在浏览器环境中共享超文本链接的文档使人们用基于文本的信息与他人 通信的方式引发了革命。网络桌面环境,受专用操作系统和依赖于平台
的软件所限,速度缓慢,毫无疑问会让路于基于标准的,对系统开放的 Internet。
把这种责任引导到这个勇敢的、新的、基于标准的世界的是XML,它 是Internet的第3层,也可能是最引人注目的一层。XML,一种强类型数
据交换格式,它为HTTP/HTML层提供了一个新范围。在XML层中,机器到 机器的通信有可能通过标准接口来进行。XML层??有多种不同的描述,
如A2A(应用程序到应用程序)、B2B(业务到业务)、或C2C(计算机到 计算机)??允许程序在平台上交换数据格式??和显示??独立于编
程的方式。XSLT样式表可以作为一种可选用的显示和/或可传输的组件予 以添加。
XML:描述Web服务的关键
把这种可能变为现实的关键是实现机器到机器的通信,这是XML力所 能及的。作为一种描述数据的词法,XML是定义驱动的(通过使用DTD和
架构),并允许以编程方式处理信息。这意味着大多数可考虑到的工作 都可以从B2B通信中取出来。可以有一致的标记,可以定义接口,处理也
可以是标准化的。Web服务是可重用的组件程序,它们把XML用作一种标 准的、可扩展的通信架构,以方便机器到机器类型的通信。
Web服务为通过HTTP传输的组件数据和业务逻辑提供接口。大量的数 据被放置在服务器端脚本后面的一个传统的位置,等待着被Web浏览器或
客户程序访问。Web服务承诺使许多企业领域的、处于闲置状态的公司软 件资源获得新生。
在把驻留于Web中的数据集成到企业应用程序中和协调用于组件片固 定的业务逻辑方面,XML起了至关重要的作用。特定的业务逻辑和服务
(包括工作流程逻辑、业务逻辑、组件序列逻辑、交易逻辑等)可以封 装在XML文档中,并集成到现有的业务环境中去。这允许业务在内部资源
和Web服务之间,简化业务交易逻辑和通过Web提供链条式交互之间起到 杠杆作用。
由于XML是人们可阅读的和基于文本的,使之可理想地用作传输松耦 合的Web服务的架构。最低限度是:自动化的交易可提高生产率、减少费
用和改善服务。网络标准的存在使自动化交易成为可能、使所有成员的 生产率都能得到提高。
SOAP是一种源于更早的基于XML标准的技术,早期XML标准在某种意义 是指一种称为 ebXML(电子商务XML)的显示标准。EbXML具有一种依次进行的连续
逻辑,它在贸易合作者间提供了一种共享业务消息的综合定义。SOAP适用 的范围更普遍,也更容易实现。
松耦合的系统
Web服务把对象从管理它们的平台上分离开来,也就是说,Web服务使 独立于平台的对象之间的交互更容易,对象可以访问Web上任何地方的数
据。作为脱离专用平台的一部分,Web服务依赖于松散而不是紧密耦合的 Web组件。根据Brian Travis(SOAP顾问和作者)的观点,“依赖于专用
对象的系统被认为是耦合紧密的,因为它们依赖一种定义良好但很脆弱 的接口。如果应用程序与服务对象间通信的任何部分被打断,或者如果
调用不完全正确,将会发生不可预料的结果。”EDI就是一个用于执行电 子商务的耦合紧密的架构的例子。松耦合的系统允许在开放的、分布式
Web环境中进行灵活的和动态的交换。
CORBA第二次降临
网络上的公司??IBM、BEA、Sun,仅举几个例子??同时在与他们 竞争的公司合作。标准化的网络传输协议,独立于平台的编程语言如:
Java、XML和特定行业的专业用语,及开放的基于组件的服务器体系结构 使每个人都能免费享用非专用的资源。现在,Web服务,带着其对包含广
泛的应用程序互操作性的承诺,就像一种最终的“胶水”,使这些技术 交互作用,即使不是无缝的,至少也不会超过以前技术如CORBA和RMI所
带来的累赘。
在某种意义上,Web服务代表着CORBA的第二次降临。但是CORBA是一 种面向对象的、基于IIOP的二进制通信架构,是由基础、骨架和特定于
供应商的ORB装载而成的;而Web服务则是轻型的、基于HTTP的、XML驱动
的及平台和语言完全中性的。如果说CORBA是一只重达600磅的大猩猩, 那么Web服务就是一只小羚羊,在辽阔的Internet禁区里自由地蹦跳。
发布、绑定和查找
Web服务的架构由发布-查找-绑定这个周而复始的循环组成,它通过 服务提供程序使数据、内容和服务能为注册的服务请求者所用,服务请
求者通过定位和绑定到服务来使用资源。请求应用程序使用
WSDL(Web服务描述语言)把请求者转到Web服务上。WSDL为想要的
服务提供了一种低层次的技术信息,并授权访问关于数据编码的XML架构 信息、及通过正确的协议确保调用正确的操作。
发布、绑定和查找机制,在3个独立(但有些等同)的协议中有它们 各自的副本,这3个协议是WSDL、SOAP和UDDI(通用描述和发现接口),
它们组成了Web服务网络栈。
对CORBA作更深层次的类推可以发现,SOAP起到了CORBA中IIOP(或RMI 中的JRMP)的作用。它是对立的端点间的绑定机制。另一方面,WSDL起
到了IDL(接口描述语言)的作用。在这种功能上,WSDL把Web服务定义 成端口和操作的集合。WSDL端口是模拟接口的,而WSDL操作则是模拟方
法的。WSDL 把Web服务接口发布给那些对跨越不同平台通信感兴趣的各 方。
但是,WSDL已经超越了一种接口定义语言;它还包含允许给想发布的 Web服务描述地址和协议信息的构造。关于WSDL的令人感兴趣的事情是它
为Web服务描述了一个抽象接口,同时还允许您??以难以忍受的细节 ??绑定Web服务给特定的传输机制,如HTTP。通过使接口抽象化,WSDL
可用作一种可重用的Web服务技术。通过绑定到特定的传输机制,WSDL生 成了抽象的类聚。如果这看上去有些自相矛盾,可以想一下航天飞机:
它是可重复使用的、但要把全机能太空舱完全绑定到专用的、但不可重 复使用的助力器火箭上。传输机制可能会改变,但有效载荷会保留下来 。
最后,UDDI是用于注册发布和查找Web服务的。在基于Web的注册中, 通过显示服务信息和绑定接口,UDDK为业务和客户提供了一个共享目录
以查找别人的Web服务。
构建Web服务
SOAP可通过远程调用对象上的方法,让您构建应用程序。SOAP消除 了两种系统必须运行于同一平台上、且必须是用同一种编程语言编写而
成的要求。SOAP包不是通过专用的二进制协议调用方法,而是使用XML 这种基本文本的词法来调用方法。请求应用程序与接收对象之间的所有
信息,是作为XML流中的标记数据通过HTTP发送的。从Web服务的角度来 看,SOAP可以看作一种客户端或服务器实现。
SOAP客户端和服务器
SOAP客户端是一种创建XML文档的程序,该XML文档包含在分布式系 统远程调用方法所需的信息。SOAP客户端不是传统意义上的程序,它除
了用作普通的桌面应用程序外,还可以是一种Web服务器或基于服务器 的应用程序。
来自SOAP客户端的消息和请求一般是通过HTTP发送的。因而,SOAP 文档可以穿过几乎所有的防火墙,从而能跨越不同的平台交换信息。
SOAP服务器只是用于监听SOAP消息的特殊代码,它可用作SOAP文档的
分配器和解释器。外部Web服务可以与基于J2EE技术的应用程序服务器交 互,这种应用程序服务器可以处理多种客户端的SOAP请求。
SOAP服务器确保通过HTTP连接接收的文档被转换成可以被另一端对 象理解的语言。由于所有的通信都采用XML格式,某种语言(比如说
Java)中的对象可以通过SOAP与另一种语言(如C++)中的对象通信。 SOAP服务器的工作就是确保各端都能理解??并且满意??为它们提供
服务的SOAP。
SOAP和Java技术
根据SOAP 1.1规范,SOAP是“一种用于在分散的、分布式环境中交换
信息的轻型协议”。SOAP不会委托单一的编程模型??也不会为特定的 编程语言定义语言绑定。在Java编程语言环境中,它取决于Java团队来
定义特定的语言绑定。现在Java语言绑定通过JAX-RPC来集中定义。
在最近的JavaOne开发人员讨论会上对SOAP的讨论中,Sun公司的工程 师Roberto Chinnici和Rahul Sharma把JAX技术家庭的作用定义成“使用
熟悉的、用于Java平台的JSP和EJB组件技术创建Web服务”。Servlets
和无状态会话bean被引用作两种最可能用于封装Web服务的Java技术。
什么是SOAP?真的吗?
我们已经彻底设置好了SOAP舞台,并描述了其在Web服务中至关重要的作用,
现在进一步看看SOAP到底是什么,它执行什么任务,以及是怎样执行的?
SOAP是一种可扩展的、基于文本的架构,它允许在不同角色之间通信,这里的
角色一般是指对象,它们先前并不了解对方或对方所在的平台。从网络对象的角
度来看,SOAP是它们的最后不可见形式。客户端应用程序可以在松耦合的环境中
互操作,以发现和动态地连接到服务,而这并不需要事先在应用程序与服务之间 建立一种协定。
SOAP是可扩展的,这是因为无需中断已有的应用程序,SOAP客户端、服务器和
协议自身都能发展。而且SOAP能极好地支持中间介质和层次化的体系结构。这意
味着处理节点可以把请求的路径置于客户端与服务器之外。中间节点通过使用报
头(用于标识哪个节点处理哪部分消息)来处理SOAP指定的各部分消息。这种类
型的中间报头处理是通过客户端应用程序与中间处理节点之间的私人契约来执行 的。SOAP为报头提供了一个mustUnderstand属性,它允许客户端将
处理指定为是必须执行的还是可选的。如果mustUnderstand被设置
为1,服务器必须执行报头指定的中间处理或给出错误。
SOAP还定义了数据编码规则,称为基准编码或“Section 5(第5节)”编码,
它是出自SOAP规范中描述数据编码规则的那一节内容。应当指出SOAP编码的内容 占了SOAP
1.1规范40页中的大部分篇幅。不必深入到XML数据类型细节??它仍然
是XML架构制定组的专家们研究的范畴??SOAP编码可以简短地描述成简单值或复 合值的集合。
简单值可以是简单类型,如整型、浮点型和字符型,或者是XML架构规范第2部 中定义的内置类型,包括各种数据类型,如字节型数组和枚举。
复合值包括结构、数组和XML架构制定组定义的复杂类型。最后,当然不是至
少,SOAP数据编码指定了对象序列化规则,即通过网络排列和分散数据流的机制。 这些“Section
5”编码在任何情况下都不是强制性的,注意这点很重要,这样客 户端和服务器可以自由地使用不同的数据编码规范,只要它们符合格式就行。但
是这样做的话,就会毁灭SOAP在网络上提供标准化服务所起的推动作用,并且会
带来一个常见的警告:已偏离航线太远,单独的客户端和服务器可以选择较短的 旅行路线。
最后,SOAP建立了一组规则,它允许客户端和服务器把SOAP用作一种通信架构
来执行远程过程调用。SOAP??作为一种面向消息的协议??可以使用这些规范 像RPC类型的型一样良好地工作。对象序列化的机制给SOAP-RPC提供了活力。
消息格式
SOAP在标准化消息格式环境中,可以做所有它能完成的工作。消息的主体部分
是“text/xml”形式的MIME类型,并且包含一个SOAP封套。该封套是一个XML文
档。封套包含了报头(可选的)和报文(必须有的)。封套的报文部分总是用于 最终接收的消息,而报头项目可以确定执行中间处理的目标节点。附件、二进制
数字及其他项目可以附加到报文上。
SOAP提供了一种让客户端指定哪个中间处理节点必须处理报头项目的方法。由
于报头与SOAP消息的主体内容是互不相关的,所以可用它们给消息添加信息,而 不会影响对消息报文的处理。
例如,报头可用于为报文中包含的请求提供数字签名。在这种情形下,身份验
证/授权服务器可以处理报头项目??独立于报文??可以剥离信息以验证签名。
一旦通过验证,封套的其余部分将被传递给SOAP服务器,它将对消息的报文进行
处理。深入研究一下SOAP封套,有助于明了SOAP报头和报文元素的位置和用途。
剖析SOAP封套
SOAP 1.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:Transaction xmlns:t="some-URI">
SOAP-ENV:mustUnderstand="1"
5
</t:Transaction>
</SOAP-ENV:Header>
<SOAP-ENV:Body>
<m:GetLastTradePrice xmlns: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编码,即前文中讨论过的“Section 5”数据类型。 由于没有指定额外的通用元素编码,这种编码将适用于整篇文档。
报头
在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载 荷。这里的“有意义”意味着服务器在某些后台数据库上调用远程过程,以为消
息报文中包含的股票-符号元素接收股票价格。所有这些魔术般的操作都是在SOAP RPC幕后发生的。
SOAP-RPC
SOAP消息本质上是一种从发送方到接收方的单向传输,但是SOAP经常组合到实 现请求/响应机制中。要让RPC使用SOAP,必须遵循几条规则。首先,请求和响应
消息必须被编码成结构类型。对一个操作的每一个输入参数,都必须有一个同名 元素(或输入结构的成员)作为参数。对每一个输出参数,都必须有一个名称匹
配的元素(或输出结构的成员)。
基于RPC的观点,会省略一些更早一点显示的SOAP消息。只带有报文部分的 SOAP请求与响应封套如下所示:
请求
<SOAP-ENV:Body>
<m:GetLastTradePrice xmlns:m="some-URI">
<symbol>DEF</Symbol>
</m:GetLastTradePrice>
</SOAP-ENV:Body>
响应
<SOAP-ENV:Body>
<m:GetLastTradePriceResponse xmlns:m="some-URI">
<price>22.50</price>
</m: GetLastTradePriceResponse>
</SOAP-ENV:Body>
请求要调用GetLastTradePrice方法。注意响应定义了
GetLastTradePriceResponse操作。对附加响应到响应操作尾部的
一个常用的SOAP调用规则是:创建响应结构。这种输出结构包含一个名称为 price的元素,它返回方法调用的结果,假定为浮点型。
在SOAP封套中没有什么地方的数据类型是显式声明的,注意到这一点很重要,
这样如果只查看SOAP消息,就不会知道符号类型或结果参数price(价格)的类 型。客户端应用程序一般通过“Section
5”编码定义数据类型,或通过与服务器 私下达成的协议来定义数据类型。在任何一种情况下,这些包含在SOAP消息中的 定义都不是显式的。
最后,为了进行RPC,需要一种低级协议如HTTP。尽管SOAP 1.0规范强制要求 使用HTTP作为传输协议,但SOAP
1.1规范(及其姊妹规范“带有附件的SOAP消息” )允许使用FTP、SMTP、甚至(可能)原始的TCP/IP套接字。所有这些对SOAP通用
的序列化和编码规则,也适用于RPC参数。
SOAP用例
图1:SOAP用例处理步骤用
现在您看到的就是详细的SOAP封套图,它能帮助我们后退一步从用例的角度观
察SOAP,以帮助我们领会在分布式Web环境中一个来回的处理过程。此处列出了几 条构成Web服务和SOAP的概念中枢的、显目的、概括性命题。
Internet上某些地方的客户端应用程序使用Web服务。
Web服务(通过SOAP)显示对象方法。
对象方法访问Web上任意位置的远程数据。
对这些网络命题应用传递逻辑,我们可以为Web服务和SOAP下一个总的结论:
某些位置的客户端可以使Web上任意位置的数据。这就是所要证明的。
下面是更加详细一点的用例。
SOAP客户端使用UDDI注册来查找Web服务。不用直接操作WSDL,大多数情况下SOAP应用程序将硬连接到使用特定类型的端口和特定样式的绑定,并且它将 通过UDDI动态配置要调用的、与发现的Web服务匹配的服务地址。
客户端应用程序创建SOAP消息,它是一个可执行想要的请求/响应操作的 XML文档。
客户端把SOAP消息传送给监听SOAP请求的Web服务器上的JSP或ASP页面。
SOAP服务器解析SOAP包并在其领域调用合适的对象方法,在SOAP文档中包
含的参数中传递。在SOAP服务器接收消息之前,中间处理节点可以执行SOAP报 头指示的特殊功能,可视情况确定是否执行这步操作。
请求对象执行指示的功能,并返回数据给SOAP服务器,它把响应打包到
SOAP封套中。服务器把SOAP封套包裹在要发送回请求机器的响应对象中,如 servlet或COM对象。
客户端接收对象,剥离出SOAP封套并把响应文档发送给最初发出请求的程 序,完成请求/响应循环。
小结
SOAP是一种基于XML的协议,它用于在分布式环境中发送消息,并执行远程过
程调用。使用SOAP,不用考虑任何特定的传输协议(尽管通常选用HTTP协议), 就能使数据序列化。
用SOAP来构建平台与语言中性的互操作系统是一个好的选择。总之,SOAP和
Web服务已为在XML上构建分布式应用程序基础结构所需的一切都考虑好了。通过
解决COM和Java组件对象模型之间的冲突,SOAP把多个平台在访问数据时所出现的 不兼容性问题减至最少。
先把这些讨论放在一边,SOAP是一种适用于所有类型的对象实体的理想的媒介 ??即使对于像Brad Pitt和Edward
Norton之类的好莱坞电影角色??也可用作 一种通信媒介。就像在电影中一样,期待着这种新技术带来震撼世界的效果。