文章目录
SOAP是一种基于XML的计算机间信息交换协议。
尽管SOAP可以在各种消息传递系统中使用,并且可以通过各种传输协议传递,但是SOAP的最初重点是通过HTTP传输的远程过程调用。因此,SOAP使客户端应用程序能够轻松地连接到远程服务并调用远程方法。例如(我们将很快看到),客户机应用程序可以通过定位正确的SOAP服务并调用正确的方法,立即将语言翻译添加到其功能集。
其他框架,包括CORBA、DCOM和Java RMI,提供了与SOAP类似的功能,但是SOAP消息完全用XML编写,因此与平台和语言无关。例如,在Linux上运行的SOAP Java客户机或在Solaris上运行的Perl客户机可以连接到在Windows 2000上运行的microsoftsoap服务器。
因此,SOAP代表了web服务体系结构的基石,使各种应用程序能够轻松地交换服务和数据。
虽然还处于初级阶段,但SOAP已经得到了广泛的行业支持。现在有许多SOAP实现,包括Java、COM、Perl、C#和Python的实现。与此同时,数以百计的SOAP服务在Web上蓬勃发展。
本章旨在为您提供SOAP的基本知识。包括以下主题:
•快速概述SOAP协议和SOAP对话示例•SOAP XML消息规范的详细信息•概述SOAP编码规则,包括简单类型、数组和结构的规则•关于通过HTTP使用SOAP的详细信息•概述与SOAP相关的W3C活动•概述四个主要的SOAP实现和主要SOAP互操作性问题的描述
3.1SOAP
SOAP规范定义了三个主要部分:
SOAP规范
SOAP XML信封定义了用于封装在计算机之间传输的数据的特定规则。这包括特定于应用程序的数据,例如要调用的方法名、方法参数或返回值。它还可以包括有关谁应该处理信封内容的信息,以及在出现故障时如何对错误消息进行编码的信息。
数据编码规则
要交换数据,计算机必须就编码特定数据类型的规则达成一致。例如,处理股票报价的两台计算机需要一个商定的规则来编码浮动数据类型;同样,处理多个股票报价的两台计算机需要一个商定的规则来编码数组。因此,SOAP包含它自己的一组编码数据类型的约定。这些约定大多基于W3C XML模式规范。
RPC约定
SOAP可以用于各种消息传递系统,包括单向和双向消息传递。对于双向消息传递,SOAP定义了一个表示远程过程调用和响应的简单约定。这使客户端应用程序能够指定远程方法名、包含任意数量的参数并从服务器接收响应。
为了检查SOAP协议的细节,我们首先展示一个SOAP会话示例。net提供了一个简单的天气服务,按邮政编码列出当前的温度。(参见图3-1。)服务方法getTemp需要一个邮政编码字符串并返回一个浮点值。
图3-1。SOAP在起作用:连接XMethods天气服务
3.1.2 SOAP request
客户端请求必须包含要调用的方法的名称和任何必需的参数。下面是发送到XMethods的示例客户机请求:
这里有几个重要的因素需要注意。首先,请求包含一个必需的信封元素,而信封元素又包含一个必需的Body元素。
其次,总共定义了四个XML名称空间。名称空间用于消除XML元素和属性的歧义,通常用于引用外部模式。在我们的示例SOAP请求中,我们将使用名称空间来消除与SOAP信封(http://schemas.xmlsoap.org/SOAP/Envelope/)相关的标识符的歧义,通过XML模式(http://www.w3.org/2001/XMLSchema-instance和http://www.w3.org/2001/XMLSchema)进行数据编码,以及特定于XMethods的应用程序标识符(urn:XMethods Temperature)。这使应用程序模块化成为可能,同时也为将来对规范的更改提供了最大的灵活性。
Body元素封装了SOAP消息的主要“负载”。唯一的元素是getTemp,它绑定到XMethods名称空间并对应于远程方法名。方法的每个参数都显示为子元素。在本例中,我们有一个邮政编码元素,它被分配给XML Schema xsd:string数据类型并设置为10016。如果需要其他参数,每个参数都可以有自己的数据类型。
3.1.2 SOAP响应
下面是XMethods的SOAP响应
与请求一样,响应包括Envelope和Body元素,以及相同的四个XML名称空间。然而,这次Body元素包含了一个getTempResponse元素,对应于我们的初始请求。response元素包含一个返回元素,指示xsd:float数据类型。在撰写本文时,邮政编码10016的温度为71华氏度。
3.2 SOAP消息
如果您急于开始编写自己的SOAP应用程序,那么您可能需要跳到本章后面的第3.6节。否则,下一节将提供有关SOAP规范本身的其他详细信息。
单向消息、来自客户端的请求或来自服务器的响应正式称为SOAP消息。每个SOAP消息都有一个必需的Envelope元素、一个可选的Header元素和一个必需的Body元素。(参见图3-2。)这些元素中的每一个都有一组相关的规则,理解这些规则将有助于您调试自己的SOAP应用程序。
## 3.2.1信封
每个SOAP消息都有一个根信封元素。与其他规范(如HTTP和XML)不同,SOAP没有基于主要和次要版本号(如htp1.0与htp1.1)定义传统的版本控制模型。相反,SOAP使用XML名称空间来区分版本。必须在信封元素中引用版本。例如:
SOAP 1.1命名空间URI是http://schemas.xmlsoap.org/SOAP/envelope/,而soap1.2命名空间URI是http://www.w3.org/2001/09/SOAP-envelope。[1] 如果信封位于任何其他命名空间中,则将其视为版本控制错误。
3.2.2 Header
可选的Header元素提供了一个灵活的框架,用于指定附加的应用程序级需求。例如,Header元素可用于为受密码保护的服务指定数字签名;同样,它可用于为按次使用付费的SOAP服务指定帐号。许多当前的SOAP服务不使用Header元素,但是随着SOAP服务的成熟,Header框架为身份验证、事务管理和支付授权提供了一种开放的机制。
Header元素的细节是有意开放的,因此为应用程序提供者提供了最大的灵活性。但是,协议确实指定了两个头属性:
参与者属性
SOAP协议将消息路径定义为SOAP服务节点的列表。每个中间节点都可以执行一些处理,然后将消息转发到链中的下一个节点。通过设置Actor属性,客户端可以指定SOAP头的接收者。
MustUnderstand属性
指示头元素是可选的还是必需的。如果设置为true,[2]则收件人必须根据其定义的语义理解和处理头属性,或者返回错误。(MustUnderstand故障代码见表3-2。)
报头指定了一个付款帐户,SOAP服务器必须理解和处理该帐户。下面是一个示例标题:
3.2.3主体
Body元素是所有SOAP消息的必需元素。正如我们已经看到的,Body元素的典型用法包括RPC请求和响应。
3.2.4故障
如果出现错误,Body元素将包含一个Fault元素。表3-1定义了故障子元素,包括faultCode、faultString、faultActor和detail元素。预定义的SOAP故障代码在表3-2中定义。以下代码是一个示例故障。客户端已请求名为ValidateCreditCard的方法,但服务不支持此类方法。这表示客户端请求错误,服务器返回以下SOAP响应:
3.3 SOAP编码
SOAP包含一组用于编码数据类型的内置规则。这使SOAP消息能够指示特定的数据类型,例如整数、浮点数、双精度数或数组。大多数情况下,编码规则是由您选择的SOAP工具包直接实现的,因此对您是隐藏的。尽管如此,了解SOAP编码的基础知识还是很有用的,特别是当您截取SOAP消息并尝试调试应用程序时。还要注意,尽管W3C规范鼓励使用SOAP编码规则,但这些规则不是必需的;这使您能够在需要时选择不同的编码模式。
在探索SOAP编码规则时,必须注意XML 1.0规范不包括编码数据类型的规则。因此,原始的SOAP规范必须定义自己的数据编码规则。继SOAP规范的早期草案之后,W3C发布了XML模式规范。XML Schema第2部分:数据类型规范提供了一个标准框架,用于对XML文档中的数据类型进行编码。因此,SOAP规范采用了XML模式约定。
3.3.1标量类型
对于标量类型,SOAP采用XML模式规范指定的所有内置简单类型。这包括字符串、浮点数、双精度数和整数。表3-3列出了主要的简单类型,摘自XML Schema第0部分:Primer(http://www.w3.org/TR/2000/WD-xmlschema-0-20000407/)。
例如,下面是一个具有双数据类型的SOAP响应:
如您所见,xsi:type属性设置为xsd:double,表示返回的double值。
SOAP规范提供了几个选项来指示特定XML元素的数据类型。第一个选项是为每个元素指定xsi:type属性。第二个选项是将数据类型信息存储在外部XML模式中,甚至存储在人类可读的文档中。SOAP工具包在实现这一需求方面各不相同。例如,Apache SOAP工具包自动在每个元素中包含xsi:type属性,而microsoftsoap工具包则省略xsi:type属性,并采用外部XML模式定义。本章中的示例来自Apache SOAP,因此使用xsi:type属性。详见本章下文第3.6.1节。
3.2.2 复合数据
SOAP数组有一组非常特定的规则,这些规则要求您同时指定元素类型和数组大小。SOAP还支持多维数组,但并非所有SOAP实现都支持多维功能。(有关详细信息,请查看您选择的SOAP工具包。)
要创建数组,必须将其指定为xsi:类型的数组。数组还必须包含arrayType属性。此属性用于指定包含元素的数据类型和数组的维度。例如,以下属性指定一个10个双值数组:arrayType=“xsd:double[10]”。相反,以下属性指定一个二维字符串数组:arrayType=“xsd:string[5,5]”。
3.3.3文字编码
如前所述,您不需要使用SOAP编码样式。实际上,有时您可能希望完全忽略SOAP编码规则,并将整个XML文档(或文档的一部分)直接嵌入到SOAP消息中。这样做被称为文本XML编码,它要求您指定文本XML编码样式。在ApacheSOAP中,文本XML样式由命名空间http://XML.Apache.org/XML-SOAP/literalxml指定。
例如,下面是编码产品信息的第二个选项。与将产品编码为SOAP结构不同,数据编码为文本XML文档:
3.4通过HTTP的SOAP
SOAP没有绑定到任何一个传输协议。实际上,SOAP可以通过SMTP、FTP、IBM的MQSeries或Microsoft消息队列(MSMQ)进行传输。然而,SOAP规范只包含HTTP的细节,HTTP仍然是最流行的SOAP传输协议。
从逻辑上讲,SOAP请求是通过HTTP请求发送的,SOAP响应是在HTTP响应的内容中返回的。虽然SOAP请求可以通过HTTP GET发送,但规范仅包含HTTP POST的详细信息。(首选HTTP POST,因为大多数服务器对GET请求设置字符限制。)此外,HTTP请求和响应都需要将其内容类型设置为text/xml。
作为附加要求,客户端必须指定SOAPAction头。SOAPAction头是一个特定于服务器的URI,用于指示请求的意图。这使得快速确定SOAP请求的性质成为可能,而无需实际检查SOAP消息负载。实际上,防火墙经常使用报头作为阻止SOAP请求或将SOAP消息快速发送到特定SOAP服务器的机制。
SOAP规范要求客户机必须提供SOAPAction头,但是SOAPAction头的实际值取决于SOAP服务器实现。例如,要访问由XMethods托管的AltaVista BabelFish翻译服务,必须将urn:xmethodsBabelFish#BabelFish指定为SOAPAction头。即使服务器不需要完整的SOAPAction头,客户端也必须指定空字符串(“”)或空值。例如:
3.5 SOAP和W3C
SOAP 1.1最初于2000年5月提交给W3C。官方提交者包括大公司,如微软、IBM和阿里巴,以及小公司,如用户土地软件和开发。
2000年9月,W3C创建了一个新的XML协议工作组。该小组的目标是制定一个用于信息交换的XML协议,并推荐该协议作为W3C的官方推荐。
2001年7月,XML协议工作组发布了SOAP1.2的“工作草案”。在W3C中,这个文档是一个正式的正在进行的工作,这意味着文档可能在最终确定之前被多次更新。然而,到目前为止,SOAP 1.2并不代表与soap1.1的根本区别,它的主要目的是澄清soap1.1规范中的不明确问题。因此,大多数开发人员应该会发现从1.1到1.2的转换相对来说没有什么痛苦。
W3C将SOAP1.2规范分为两部分。第一部分描述了SOAP消息传递框架和信封规范。第二部分描述了SOAP编码规则、SOAPRPC约定和HTTP绑定的详细信息。
一旦最终确定,SOAP可能会达到W3C的官方推荐状态。但在此之前,必须注意的是,SOAP没有W3C的官方承诺,甚至SOAP 1.1也有一个“note”状态,这意味着它目前向W3C成员开放供讨论。
3.6 SOAP实现
现在有几十种SOAP实现免费存在于互联网上。实际上,在撰写本文之前,SOAPWare.org总共引用了65个实现。下面是四个最流行和被广泛引用的实现。
ApacheSOAP(http://xml.Apache.org/SOAP/)
SOAP协议的开源Java实现;基于IBM SOAP4J实现
Microsoft SOAP工具包2.0(http://msdn.Microsoft.com/SOAP/default.asp)
C~(++)、C++、Visual Basic或其他COM兼容语言SOAP协议的COM实现
用于Perl的SOAP::Lite(http://www.soaplite.com/)
由Paul Kulchenko编写的SOAP协议的Perl实现,包括对WSDL和UDDI的支持
心灵之胶(http://www.themmedilector.com)
SOAP协议的Java实现,包括对WSDL和UDDI的支持