原文地址:http://www.ibm.com/developerworks/cn/webservices/ws-intwsdl/part3/index.html
使用 WSDL 部署 Web 服务,第 3 部分: SOAP 互操作性
在本文中,Bilal 将从讨论 SOAP 的发展入手,向您展示一些主要的 SOAP 互操作性问题及其细节,并提供一个关于开发互操作性更好的 Web 服务的提纲。Bilal 还将讲述使用 SOAP 中的数据类型的详细情况。
0 评论:
本文是一个由四篇文章组成的系列的第三篇(请参阅 参考资料),本系列文章旨在介绍创建、描述和发布 Web 服务的过程。在第一部分中,我借助 WSDL 编制示例讲解了如何描述一个 Web 服务。在第二部分中,我讨论了 SOAP 的体系结构及其语义。在本文中,我将看一看与 SOAP 相关的互操作性问题。
Web 服务模型将整个 B2B 领域分成三个步骤或三个域:描述一个服务、将该服务与具体的实现绑定,然后通过注册中心发布该服务。这三个步骤彼此独立,会引发各自的互操作性问题。
WSDL(Web 服务描述语言(Web Services Description Language))构成描述域,SOAP 覆盖绑定域,统一描述、发现和集成(Universal Description, Discovery and Integration,UDDI)注册中心覆盖发布域。我在这部分的讨论将仅限于与绑定域相关的互操作性问题。我将从讨论 SOAP 的发展入手,接着讨论实际的 SOAP 互操作性问题。
SOAP 版本的发展
1999 年,当 XML Schema 规范仍在发展中且被视为 SOAP 规范的关键部分的时候,W3C 就开始了关于 SOAP 规范的工作。SOAP 使用 XML Schema 数据类型定义来定义并实例化 SOAP 中的数据类型。
2000 年 5 月,SOAP 1.1 作为 W3C 纪要发行( 参考资料)。这是来自 Microsoft、IBM、Lotus Development 和 UserLand Software, Inc. 的开发人员共同努力的成果。SOAP 1.1 采用带有 1999 名称空间 URI( "http://www.w3.org/1999/XMLSchema")的 XML Schema 工作草案。目前,SOAP 1.2( 参考资料)已经很接近于成为候选推荐,而且它已经采用了 XML Schema 推荐(2001 年 5 月)和 XML Schema 的 2001 名称空间 URI( "http://www.w3.org/2001/XMLSchema")。
互操作性问题
我将从基于传输(HTTP)的 SOAP 互操作性问题入手。
1. 传输
SOAP 1.1 规范允许在 HTTP 请求中发送 SOAP 消息。如同第 2 部分( 参考资料)中所描述的,SOAP 与 HTTP 集成并不会影响 SOAP 的语义。SOAP 规范将必选的 SOAPAction
头添加到 HTTP 请求头中。我在前一篇文章中已经描述过, SOAPAction
头的合法取值有三种:
- 它可以为空
- 它可以是一个用引号括起来的空字符串
- 它还可以是一个任意的 URI
这种灵活性使 SOAP 实现能够选择它们自己的 SOAPAction
样式及其功能。但是这种灵活性已经引发了互操作性问题。
为了研究这些互操作性问题,我创建了一个 SOAP 客户机( 参考资料),该客户机向 SOAP 服务器(由 URL 参数指定的)发送一个请求并且在接收到时显示服务器响应。我在更改 SOAPAction 头的值之后将简单的 SOAP 请求发送给不同的服务器,从而查看服务器如何支持 SOAP 1.1 规范所允许的三种头。
除 SOAPAction
头(这个头由我操作)外,我的测试均按照 SOAPBuilders 的第 2 轮(基本)echoString 测试(SOAPBuilders' Round 2 (Base) echoString test)( 参考资料)进行。您应该访问 SOAPBuilders 的第 2 轮测试站点以获得 WSDL 文件(基本测试),该文件描述了我在执行测试期间将调用的测试 Web 服务。
被测试的 SOAP 服务器
我在本文中测试了下列 SOAP 服务器:
- Apache Axis SOAP Server
- Apache SOAP 2.2 Server
- WhiteMesa 2.7 SOAP Server
- IONA XMLBus
- SOAP::Lite
- EasySOAP++
- 4S4C
- Microsoft ASP.NET Web Services
我在测试中使用了四个 SOAP 请求。
- 清单 1 包含了
SOAPAction
头的值用双引号括起来的 SOAP 请求。SOAPAction
头的值与 WSDL 文件中给定的值( "http://soapinterop.org/")一样。 - 清单 2 包含了相同的
SOAPAction
头值,但是没有双引号( http://soapinterop.org/)。 - 清单 3 包含了一个与 WSDL 文件中给定的头不同的
SOAPAction
头("http://differentfromwsdl.org/")。 - 清单 4 为
SOAPAction
头指定了一个空值。
我向 WhiteMesa SOAP Server 2.7 发送 清单 1,它作出了一个成功响应,说明 WhiteMesa 可以成功地处理这样的 SOAPAction
头。接下来,我向 WhiteMesa 发送 清单 2,它再次成功地对其进行了处理。最后,当我将 SOAPAction
头的值更改为 "http://differentfromwsdl.org/"( 清单 3)时,WhiteMesa 未能成功处理该请求并返回一个故障响应。故障字符串为 “Unrecognized 'SOAPAction' HTTP header received.”。WhiteMesa SOAP Server 2.7 还针对 清单 4 中的请求(其中 SOAPAction
值为空)返回一个故障响应。
我还用 IONA XMLBus 和 SOAP::Lite 对清单 1、 3和 4进行了测试,它们成功地处理了 清单 1中的请求,但却针对清单 3和 4中的请求返回了故障消息。IONA XMLBus 也针对 清单 2(未用双引号将 URI 引起来)返回了一个故障响应,指出它期望请求中的 SOAPAction
头要和 WSDL 文件中定义的 SOAPAction
头一样,并且要用双引号括起来。
接下来,我向 Easy SOAP++ 0.6 发送清单 1、 3和 4 中的请求,它返回正确的响应。不管 SOAPAction
头的值为何,Apache Axis 和 Apache SOAP 2.2 都返回正确的响应。
结论
为了获得最大程度的互操作性,我推荐用引号将 SOAPAction
头的值括起来;这个值应该与 WSDL 文件中给定的一致。
2. XML
XML Schema
这一部分描述了各种 SOAP 服务器对编制 SOAP 请求的过程中所使用的不同的 XML Schema 版本表现出的行为。我将对使用测试客户机测试不同的 SOAP 服务器支持的 XML 模式名称空间 URI 所得到的测试结果进行分析。
清单 1和 清单 5是完全相同的 SOAP 请求,只是所使用的 XML Schema 版本不同。 清单 1使用 2001 XML Schema URI,而 清单 5使用 1999 URI。我对大量服务器进行了名称空间 URI 支持测试,然后发现 IONA XMLBus 不能成功处理 1999 URI,但是却向使用 2001 URI 的 清单 1中的请求返回了一个成功的响应。因此,IONA XMLBus 中的支持被限制为 2001 XML Schema 名称空间 URI。
我可以有把握地说,2001 URI 将对大多数实现起作用,但是诸如 IBM SOAP Toolkit 和 Apache SOAP 之类较老的实现仍然广泛存在,这些实现使用的是 1999 URI。Apache SOAP 2.2 既接收 1999 URI,也接收 2001 URI,但是它在响应消息中缺省情况下使用 1999 URI(尽管它确实允许您将其更改为 2001)。因此,您可以预料到那些仅期待 2001 URI 的客户机(比如 IONA XMLBus)与早期的 SOAP 实现之间将存在互操作性问题。
结论
因为 2001 URI 不久就要成为标准(SOAP 1.2 规范)了,并且它为目前的 SOAP 实现所广泛支持,所以,对于 XML Schema 名称空间 URI 来说,最佳做法可能就是在请求中使用 2001 URI 了。
连接类型相关性与 WSDL 知晓性的比较
SOAP 1.1 允许实现提供有关消息中包含的数据的类型信息。这是对数据的文字描述(例如, int
、 string
等)。一些实现依赖该信息来正确地反序列化消息中的数据。Apache SOAP 2.2 是那些在连接时需要显式输入信息的实现之一(即,数据类型信息被作为包含数据的元素的一个属性值提供);否则它就无法反序列化数据。
我在第 1 部分( 参考资料)中已经讨论了 WSDL 文件的语义。WSDL 文件用于描述 Web 服务。它包含有关 Web 服务所公开的一些方法以及它们的说明的信息。因为 WSDL 文件包含关于哪些参数可以传递给一个方法以及期望返回哪些内容的信息,这些信息可以被用于反序列化一个调用方法的 SOAP 请求及其响应。因此,WSDL 文件知晓性是上述问题的解决方案;即,正在反序列化一条 SOAP 消息的运行时应用程序能够利用 WSDL 文件中提供的数据类型信息。
现在,大多数实现都是 WSDL 知晓的并且不依赖于连接时的类型化。Apache Axis 无需连接时的类型化就可以处理数据,White Mesa 2.7 也可以;但是这里就出现了一个互操作性问题。如果元素名称和 WSDL 文件中指定的不同,White Mesa 2.7 就不能处理这个请求。对于许多其它实现都是如此。但是另一方面,Apache Axis 能够处理这样一个请求而不发出一个故障。所以,如果您为 Apache Axis 编写一个这样的请求,它将不会在 White Mesa 2.7 上运行。为服务编写遵循 WSDL 文件的请求和响应可能是一个更好的做法。这将能处理所有具有 WSDL 知晓性的实现。
3. 数据类型
数据类型兼容性可能是 SOAP 互操作性中最重要的问题。如果两个应用程序不能理解彼此的数据类型,那么它们就不能执行有意义的数据交换,从而也就不能互操作。
在本系列文章的第二篇文章中已经介绍了数据类型,我在那篇文章中讨论了几种简单的数据类型和复杂的数据类型。SOAP 使用 XML Schema 数据类型和结构来标识 SOAP 消息中携带的数据的类型。
使用 SOAP 进行传递的数据首先被序列化;即,数据值被转换成字符串以在 XML 文档中传送。在目的地,这个字符串必须被反序列化,即,被转换成表示原来的值的数据类型。
将 XML Schema 数据类型映射到适当的本机数据类型是由 SOAP 实现负责的。如果两个本机数据类型不一致,即,此时 XML 中的同一种数据类型在不同的实现中有不同的值(因此,也就有不同的含义),就可能产生问题。在序列化和反序列化之后保持数据的一致是很重要的。我将详细讨论这个问题。
Float(浮点)
与 float
有关的常见问题出现在无穷大的表示上。XML Schema 用字符串 INF表示无穷大。清单 6在请求中将 INF 作为 float
无穷大发送,Apache SOAP 2.2 服务器以 Infinity返回它,而 Apache Axis 则返回 INF( 清单 7)。
我还通过发送 清单 6 的 SOAP 请求对 MS SOAP Toolkit 3.0 服务器进行了测试。它返回一个服务器端的故障代码,且不能将 float
无穷大值 INF反序列化,如同故障字符串“SoapMapper:Converting data for SoapMapper failed inside the typemapper”所指出的那样。
另一个问题与 float
精度支持有关。我把 1.23456789E38 作为 float
发送给几台 SOAP 服务器(请参阅 清单 8)。IONA XMLBus 返回 1.23456789E38,White Mesa 2.7 服务器返回 1.234568E38,而 MS SOAP ToolKit 3.0 服务器返回 1.23456786051167E+38。尽管这指出了各个实现正在进行互操作的事实,但是这些实现仍然不能将数据重新生成为它的原始值。
Decimal(十进制)
对于 decimal
,XML Schema 规范要求实现要支持的最少位数是 18 位。因为在规范中没有定义上限,所以各个实现可以随意设置它们自己的上限。Microsoft ASP.NET Web Services 和 WhiteMesa 2.7 给出的精度最多达 28 位,而 Apache Axis 可以精确支持数百位。这种支持上的差异意味着,当一个 Apache Axis 实现向 WhiteMesa 2.7 实现发送一些大小超过 28 位的 decimal
数字时,额外的精度将被截断,从而造成数据不一致。
我发送 清单 9 中的 decimal
数字请求(该请求带有一个很大的 decimal
数字)以了解不同服务器的精度支持。在清单 10、 11和 12中,可以分别看到来自 ASP.NET 服务器、Apache Axis 以及 WhiteMesa 2.7 的响应。4S4C 服务器在对 清单 9的响应中返回的值为 1.235。
DateTime(日期时间)
XML Schema 中用于时间和日期信息的数据类型是 dateTime
。White Mesa 2.7 给出的精度为秒。Apache SOAP 2.2 和 Apache Axis 用java.util.Date
类表示一个特定的时间实例,精度为毫秒。Microsoft ASP.NET Web Services 使用 Date
类型,该类型可以表示精度为纳秒的时间。
现在,如果一个基于 .NET 的 SOAP 客户机端实现向 SOAP 2.2 实现或 White Mesa 2.7 实现发送 dateTime
信息, dateTime
中额外的精度将被丢失,从而导致数据不一致性。请注意:在 XML Schema 中,精度达到秒是强制性的,而秒的小数部分则是可选的且合法的。
我用 清单 13 中的请求进行了 dateTime
测试。在清单 14、 15、 16和 17中分别显示了来自 Microsoft ASP.NET Web Services、Apache Axis、WhiteMesa 2.7 和 SOAP::Lite 的响应。
字节数组(Byte Array)
SOAP 允许您以字节数组的形式交换数据。字节数组在被放入一个 XML 文档中之前,它必须是 base64编码的。许多实现未能通过 SOAPBuilder( 参考资料)的第 2 轮(基本)互操作性测试中的 echoBase64
测试。由于本机数据类型格式的差异,一些实现返回的是不一致的值。一些实现通过对已经进行 base64 编码的值进一步进行 base64 编码来返回值。
清单 18(使用 1999 XML Schema base64Binary
数据类型)和 清单 19(使用 2001 Schema base64Binary
数据类型)中的请求向 SOAP 服务器发送一个简单的 echoBase64
方法调用。
Apache SOAP 2.2 在对 清单 18和 清单 19的响应中都返回故障消息。该服务器未能识别两个例子中的数据类型,因此无法反序列化 base 64 编码的字节数组。
请看一下 清单 20,它指定 base64
作为数据类型编码。与 XML Schema 规范定义的 base64Binary
数据类型相比, base64
编码是由 SOAP 1.1 规范定义的。Apache SOAP 2.2 成功地处理了 清单 20的请求。
IONA XMLBus 成功地处理了 19,但处理 18(请回顾一下讲述 XML Schema 问题的部分,在那部分中,我发现了 IONA XMLBus 只支持 2001 XML Schema URI)时失败了。它也无法识别 清单 20 中的请求中的 SOAP-ENC:base64
数据类型实例,然后返回一个故障字符串。
从上面的测试中能明显看出,当 Apache SOAP 2.2 和 IONAXMLBus 交换 base64 编码的字节数组时,它们之间有互操作性问题。
数组(Array)
数组形式的数据对实现来说一直是一个困难的测试,尤其是当情形复杂,满是使用嵌套的数组、多维数组以及嵌套结构(struct)的情况时。
struct
是一种复杂的、用户定义的数据类型,它可以包含简单的或更复杂的数据类型。具有 C 语言编程经验的读者可能会想在 C struct
和 XML Schema struct
之间做一个类比。
有无数种方法可以把一维数组和多维数组与其它的数据类型结合在 structs
中。因此,我设计了大量 SOAP 请求来测试不同 SOAP 服务器的行为。这些测试遵循 SOAPBuilders 的第 2 轮(B 组)测试套件。您可以在 SOAPBuilders 的第 2 轮 Web 站点上得到 B 组测试的 WSDL 文件。
- 清单 21 包含了一个简单的
strings
数组。 - 清单 22 包含了一个
structs
数组。该 struct 包含了一个string
、一个float
和一个int
数据类型。 - 清单 23 包含一个二维的
strings
数组。 - 清单 24为二维数组定义了一个偏移量(这个值定义了应该从哪个位置开始处理数组)。
- 清单 25 包含了一个
struct
,该struct
带有一个嵌套的strings
数组。 - 清单 26包含一个二维数组,未指定最里面一维的大小。
我所测试的所有 SOAP 实现对于简单类型和复杂类型的数组(即 清单 21和 清单 22)都没有问题。
用清单 21、 22、 23、 24、 25和 26对 WhiteMesa 2.7 服务器进行了测试。尽管 只是当指定了偏移量(大于零)时,WhiteMesa 2.7 服务器未能成功处理 清单 25,但它还是成功地处理了所有请求。White Mesa 2.7 就已经显示了在最里面一维的大小未被指定( 清单 26)时能够处理二维数组。
我向 SOAP::Lite 发送 清单 23中的请求,SOAP::Lite 无法处理该请求,它返回一个带有故障字符串 “Not implemented, because SOAP::Lite does not generate multidimensional arrays (yet accepts ;))”的故障响应。 清单 26中的请求能被 WhiteMesa 成功地处理,却不能被许多其它的实现成功处理;SOAP::Lite 和 Apache Axis 返回故障消息。
结论
包括数组以及数组的不同组合的交换的数据交换,对于大多数 SOAP 实现可能是可以的,除了上面我已经指出的几个实现外。为了确保最大程度的互操作性和数据一致性,Web 服务开发者应该编写全面的数据测试,这些测试由期望的数据模式的所有可能变体组成,因为那样做可以找出可以解决的问题并确认应用程序和数据一致性。
杂项
在 SOAP 中,还有其它可能引发互操作性问题的地方。这些问题可能会因引擎无法处理 mustUnderstand
SOAP 头而显露出来。可以通过定制头来扩展 SOAP 功能。这个可扩展性还为最终可能会导致互操作性问题的专有的、非标准的解决方案打开了解决渠道。SOAP 允许使用一些实现(例如,Apache SOAP 2.2)所不支持的多个返回参数。编码模式描述了将数据序列化到 XML 以及将数据从 XML 反序列化时所遵循的规则。遗憾的是,尽管 SOAP 1.1 确实提议了一个 SOAP 消息的编码,但是它并没有为 SOAP 消息指定一个缺省编码。SOAP 实现者并没有被该规范所束缚,不会为了遵循规范而实现规范定义的编码。缺少缺省编码模式可能会导致互操作性问题。
结束语
对于那些正在计划在现在的 SOAP 实现上构建 Web 服务的开发者,或者那些正在编写他们自己的 SOAP 服务器和客户机的开发者,现在我可以提供几点建议。
- 如果您正在计划使用 SOAP 1.1 实现,请在您的请求中用引号把
SOAPAction
头括起来,并且要确保它与服务的 WSDL 文件中的SOAPAction
头一致。 - 请采用 XML Schema 的 2001 名称空间 URI,因为它现在是事实上的标准。
- 请遵照 SOAP 1.1 定义的编码,并请确保您发送和接收的数据确实是以它应该的格式进行的。
- 您的方法元素名称应该遵循 WSDL 描述。
- 请在 SOAP 消息中提供连接时的数据类型信息。
清单 1. SOAPAction 值为 "http://soapinterop.org/" 的 SOAP 请求。
POST /endpoint HTTP/1.1 Host:host-URL Content-Type: "text/xml"; Charset="utf-8" SOAPAction: "http://soapinterop.org/" <?xml version="1.0" encoding="UTF-8"?> <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <SOAP-ENV:Body> <ns1:echoString xmlns:ns1="http://soapinterop.org/"> <inputString xsi:type="xsd:string"> A Test String </inputString> </ns1:echoString> </SOAP-ENV:Body> </SOAP-ENV:Envelope>
清单 2. SOAPAction 值(未加引号的)为 http://soapinterop.org/ 的 SOAP 请求。
POST /endpoint HTTP/1.1 Host:host-URL Content-Type: "text/xml"; Charset="utf-8" SOAPAction: http://soapinterop.org/ <?xml version="1.0" encoding="UTF-8"?> <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <SOAP-ENV:Body> <ns1:echoString xmlns:ns1="http://soapinterop.org/"> <inputString xsi:type="xsd:string"> A Test String </inputString> </ns1:echoString> </SOAP-ENV:Body> </SOAP-ENV:Envelope>
清单 3. SOAPAction 值为 "http://differentfromwsdl.org/" 的 SOAP 请求。
POST /endpoint HTTP/1.1 Host:host-URL Content-Type: "text/xml"; Charset="utf-8" SOAPAction: "http://differentfromwsdl.org/" <?xml version="1.0" encoding="UTF-8"?> <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <SOAP-ENV:Body> <ns1:echoString xmlns:ns1="http://soapinterop.org/"> <inputString xsi:type="xsd:string"> A Test String </inputString> </ns1:echoString> </SOAP-ENV:Body> </SOAP-ENV:Envelope>
清单 4. SOAPAction 值为空的 SOAP 请求。
POST /endpoint HTTP/1.1 Host:host-URL Content-Type: "text/xml"; Charset="utf-8" SOAPAction: <?xml version="1.0" encoding="UTF-8"?> <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <SOAP-ENV:Body> <ns1:echoString xmlns:ns1="http://soapinterop.org/"> <inputString xsi:type="xsd:string"> A Test String </inputString> </ns1:echoString> </SOAP-ENV:Body> </SOAP-ENV:Envelope>
清单 5. 带有 XML Schema 的 1999 名称空间 URI 的 SOAP 请求。
<?xml version="1.0" encoding="UTF-8"?> <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance" xmlns:xsd="http://www.w3.org/1999/XMLSchema"> <SOAP-ENV:Body> <ns1:echoString xmlns:ns1="http://soapinterop.org/"> <inputString xsi:type="xsd:string"> A Test String </inputString> </ns1:echoString> </SOAP-ENV:Body> </SOAP-ENV:Envelope>
清单 6. “INF”作为 float 无穷大的 SOAP 请求。
<?xml version="1.0" encoding="UTF-8"?> <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance" xmlns:xsd="http://www.w3.org/1999/XMLSchema"> <SOAP-ENV:Body> <ns1:echoFloat xmlns:ns1="http://soapinterop.org/"> <inputFloat xsi:type="xsd:float">INF</inputFloat> </ns1:echoFloat> </SOAP-ENV:Body> </SOAP-ENV:Envelope>
清单 7. Apache Axis 服务器对清单 6 中的请求的响应。
<?xml version="1.0" encoding="UTF-8"?> <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <SOAP-ENV:Body> <ns1:echoFloatResponse SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:ns1="http://soapinterop.org/"> <echoFloatReturn xsi:type="xsd:float">INF</echoFloatReturn> </ns1:echoFloatResponse> </SOAP-ENV:Body> </SOAP-ENV:Envelope>
清单 8. 用于对 SOAP 服务器进行 float 值测试的 SOAP 请求。
<?xml version="1.0" encoding="UTF-8"?> <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <SOAP-ENV:Body> <ns1:echoFloat xmlns:ns1="http://soapinterop.org/"> <inputFloat xsi:type="xsd:float">1.23456789E38</inputFloat> </ns1:echoFloat> </SOAP-ENV:Body> </SOAP-ENV:Envelope>
清单 9. 很大的十进制数的 SOAP 请求。
<?xml version="1.0" encoding="UTF-8"?> <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <SOAP-ENV:Body> <ns1:echoDecimal xmlns:ns1="http://soapinterop.org/"> <inputDecimal xsi:type="xsd:decimal"> 0.123456789123456789123456789123456789 </inputDecimal> </ns1:echoDecimal> </SOAP-ENV:Body> </SOAP-ENV:Envelope>
清单 10. 来自 Microsoft 的 ASP.NET Web Services 对清单 9 中的请求的 SOAP 响应。
HTTP/1.0 200 OK Server: Microsoft-IIS/5.0 Date: Sat, 29 Jun 2002 09:05:39 GMT X-Powered-By: ASP.NET X-AspNet-Version: 1.0.4221 Cache-Control: private, max-age=0 Content-Type: text/xml; charset=utf-8 Content-Length: 568 X-Cache: MISS from cache-L7.wol.net.pk Connection: keep-alive <?xml version="1.0" encoding="UTF-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:tns="http://soapinterop.org/" xmlns:types="http://soapinterop.org/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <soap:Body soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"> <types:echoDecimalResponse> <return xsi:type="xsd:decimal"> 0.1234567891234567891234567891 </return> </types:echoDecimalResponse> </soap:Body> </soap:Envelope>
清单 11. 来自 Apache Axis 的对清单 9 中的请求的 SOAP 响应。
HTTP/1.1 200 OK Content-Type: text/xml; charset=utf-8 Date: Sat, 29 Jun 2002 09:09:07 GMT Transfer-Encoding: chunked Server: Apache Tomcat/4.0.3 (HTTP/1.1 Connector) 1fc <?xml version="1.0" encoding="UTF-8"?> <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <soapenv:Body> <ns1:echoDecimalResponse soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:ns1="http://soapinterop.org/"> <return xsi:type="xsd:decimal"> 0.123456789123456789123456789123456789 </return> </ns1:echoDecimalResponse> </soapenv:Body> </soapenv:Envelope> 0
清单 12. 来自 WhiteMesa 2.7 的对清单 9 中的请求的 SOAP 响应。
HTTP/1.0 200 OK Date: Sat, 29 Jun 2002 09:36:29 GMT Server: WhiteMesa SOAP Server/2.7 Content-Type: text/xml; charset="utf-8" Content-Length: 362 X-Cache: MISS from cache-L3.wol.net.pk Connection: keep-alive <?xml version="1.0" encoding="UTF-8"?> <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"> <SOAP-ENV:Body> <m:echoDecimalResponse SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:m="http://soapinterop.org/"> <return> 0.1234567891234567891234567891 </return> </m:echoDecimalResponse> </SOAP-ENV:Body> </SOAP-ENV:Envelope>
清单 13. SOAP dataTime 数据类型请求。
<?xml version="1.0" encoding="UTF-8"?> <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <SOAP-ENV:Body> <ns1:echoDate xmlns:ns1="http://soapinterop.org/"> <inputDate xsi:type="xsd:dateTime"> 1956-10-18T22:20:00.1234567 </inputDate> </ns1:echoDate> </SOAP-ENV:Body> </SOAP-ENV:Envelope>
清单 14. 来自 Microsoft ASP.NET Web Services 的对清单 13 中的请求的响应。
HTTP/1.0 200 OK Server: Microsoft-IIS/5.0 Date: Sat, 29 Jun 2002 07:50:58 GMT X-Powered-By: ASP.NET X-AspNet-Version: 1.0.4221 Cache-Control: private, max-age=0 Content-Type: text/xml; charset=utf-8 Content-Length: 566 X-Cache: MISS from malhitest Connection: keep-alive <?xml version="1.0" encoding="utf-8"?> <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <SOAP-ENV:Body> <ns1:echoDate xmlns:ns1="http://soapinterop.org/"> <inputDate xsi:type="xsd:dateTime"> 1956-10-18T22:20:00.1234567 </inputDate> </ns1:echoDate> </SOAP-ENV:Body> </SOAP-ENV:Envelope>
清单 15. 来自 Apache Axis 的对清单 13 中的请求的响应。
HTTP/1.1 200 OK Content-Type: text/xml; charset=utf-8 Date: Sat, 29 Jun 2002 09:09:01 GMT Transfer-Encoding: chunked Server: Apache Tomcat/4.0.3 (HTTP/1.1 Connector) 1e9 <?xml version="1.0" encoding="utf-8"?> <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <soapenv:Body> <ns1:echoDateResponse soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:ns1="http://soapinterop.org/"> <return xsi:type="xsd:dateTime"> 1956-10-18T22:20:00.123Z </return> </ns1:echoDateResponse> </soapenv:Body> </soapenv:Envelope> 0
清单 16. 来自 WhiteMesa 2.7 的对清单 13 中的请求的响应。
HTTP/1.0 200 OK Date: Sat, 29 Jun 2002 09:16:09 GMT Server: WhiteMesa SOAP Server/2.7 Content-Type: text/xml; charset="utf-8" Content-Length: 346 X-Cache: MISS from cache-L4.wol.net.pk Connection: keep-alive <?xml version="1.0" encoding="utf-8"?> <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"> <SOAP-ENV:Body> <m:echoDateResponse SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:m="http://soapinterop.org/"> <return> 1956-10-18T22:20:00Z </return> </m:echoDateResponse> </SOAP-ENV:Body> </SOAP-ENV:Envelope>
清单 17. 来自 SOAP::Lite 的对清单 13 中的请求的响应。
HTTP/1.0 200 OK Date: Sat, 29 Jun 2002 09:17:20 GMT Server: Apache/1.3.26 (Unix) mod_gzip/1.3.19.1a mod_ssl/2.8.1 OpenSSL/0.9.4 PHP/4.2.1 SOAPServer: SOAP::Lite/Perl/0.55 Content-Length: 553 Content-Type: text/xml; charset=utf-8 X-Cache: MISS from cache-L4.wol.net.pk Connection: keep-alive <?xml version="1.0" encoding="utf-8"?> <SOAP-ENV:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"> <SOAP-ENV:Body> <namesp1:echoDateResponse xmlns:namesp1="http://soapinterop.org/"> <return xsi:type="xsd:dateTime"> 1956-10-18T22:20:00.1234567 </return> </namesp1:echoDateResponse> </SOAP-ENV:Body> </SOAP-ENV:Envelope>
清单 18. 带有 1999 XML Schema URI 限定的 base64Binary 数据类型的 SOAP 请求。
<?xml version="1.0" encoding="utf-8"?> <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance" xmlns:xsd="http://www.w3.org/1999/XMLSchema"> <SOAP-ENV:Body> <ns1:echoBase64 xmlns:ns1="http://soapinterop.org/"> <inputBase64 xsi:type="xsi:base64Binary"> VGhpcyBpcyBhIFRlc3QgU3RyaW5n </inputBase64> </ns1:echoBase64> </SOAP-ENV:Body> </SOAP-ENV:Envelope>
清单 19. 带有 2001 XML Schema URI 限定的 base64Binary 数据类型的 SOAP 请求。
<?xml version="1.0" encoding="utf-8"?> <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <SOAP-ENV:Body> <ns1:echoBase64 xmlns:ns1="http://soapinterop.org/"> <inputBase64 xsi:type="xsi:base64Binary"> VGhpcyBpcyBhIFRlc3QgU3RyaW5n </inputBase64> </ns1:echoBase64> </SOAP-ENV:Body> </SOAP-ENV:Envelope>
清单 20. 带有 SOAP-ENC 限定的 base64 数据类型的 SOAP 请求。
<?xml version="1.0" encoding="utf-8"?> <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance" xmlns:xsd="http://www.w3.org/1999/XMLSchema"> <SOAP-ENV:Body> <ns1:echoBase64 xmlns:ns1="http://soapinterop.org/"> <inputBase64 xsi:type="SOAP-ENC:base64"> VGhpcyBpcyBhIFRlc3QgU3RyaW5n </inputBase64> </ns1:echoBase64> </SOAP-ENV:Body> </SOAP-ENV:Envelope>
清单 21. SOAP 请求中的一个字符串数组。
<?xml version="1.0" encoding="utf-8"?> <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance" xmlns:xsd="http://www.w3.org/1999/XMLSchema"> <SOAP-ENV:Body> <ns1:echoStringArray xmlns:ns1="http://soapinterop.org/"> <inputStringArray SOAP-ENC:arrayType="xsd:string[2]" xsi:type="SOAP-ENC:Array"> <item xsi:type="xsd:string"> hello </item> <item xsi:type="xsd:string"> goodbye </item> </inputStringArray> </ns1:echoStringArray> </SOAP-ENV:Body> </SOAP-ENV:Envelope>
清单 22. SOAP 请求中的结构数组。
<?xml version="1.0" encoding="utf-8"?> <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance" xmlns:xsd="http://www.w3.org/1999/XMLSchema" xmlns:ns2="http://soapinterop.org/xsd"> <SOAP-ENV:Body> <ns1:echoStructArray xmlns:ns1="http://soapinterop.org/"> <inputStructArray SOAP-ENC:arrayType="ns2:SOAPStruct[2]" xsi:type="SOAP-ENC:Array"> <inputStruct xsi:type="ns2:SOAPStruct"> <varFloat xsi:type="xsd:float"> 6.2237275295275275295297529752 </varFloat> <varString xsi:type="xsd:string"> test string </varString> <varInt xsi:type="xsd:int"> 5 </varInt> </inputStruct> <inputStruct xsi:type="ns2:SOAPStruct"> <varFloat xsi:type="xsd:float"> 12.4 </varFloat> <varString xsi:type="xsd:string"> another test </varString> <varInt xsi:type="xsd:int"> 10 </varInt> </inputStruct> </inputStructArray> </ns1:echoStructArray> </SOAP-ENV:Body> </SOAP-ENV:Envelope>
清单 23. SOAP 请求中的一个二维字符串数组。
<?xml version="1.0" encoding="utf-8"?> <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"> <SOAP-ENV:Body> <m:echo2DStringArray xmlns:m="http://soapinterop.org/"> <input2DStringArray SOAP-ENC:arrayType="xsd:string[3,2]"> <item>Row-0,Column-0</item> <item>Row-0,Column-1</item> <item>Row-1,Column-0</item> <item>Row-1,Column-1</item> <item>Row-2,Column-0</item> <item>Row-2,Column-1</item> </input2DStringArray> </m:echo2DStringArray> </SOAP-ENV:Body> </SOAP-ENV:Envelope>
清单 24. SOAP 请求中一个带有偏移量的二维字符串数组。
<?xml version="1.0" encoding="utf-8"?> <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"> <SOAP-ENV:Body> <m:echo2DStringArray xmlns:m="http://soapinterop.org/"> <input2DStringArray SOAP-ENC:arrayType="xsd:string[3,2]" SOAP-ENC:offset="[2,0]"> <item>Row-0,Column-0</item> <item>Row-0,Column-1</item> <item>Row-1,Column-0</item> <item>Row-1,Column-1</item> <item>Row-2,Column-0</item> <item>Row-2,Column-1</item> </input2DStringArray> </m:echo2DStringArray> </SOAP-ENV:Body> </SOAP-ENV:Envelope>
清单 25. 结构中带有一个嵌套的字符串数组的 SOAP 请求。
<?xml version="1.0" encoding="utf-8"?> <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"> <SOAP-ENV:Body> <m:echoNestedArray xmlns:m="http://soapinterop.org/"> <inputStruct> <varInt>12345</varInt> <varFloat>1234.5678 </varFloat> <varString> A Test String </varString> <varArray SOAP-ENC:arrayType="xsd:string[4]" SOAP-ENC:offset="[0]"> <item>First Array String</item> <item>Second Array String</item> <item>Third Array String</item> <item>Fourth Array String</item> </varArray> </inputStruct> </m:echoNestedArray> </SOAP-ENV:Body> </SOAP-ENV:Envelope>
清单 26. 带有二维数组的 SOAP 请求,未指定行(最里面一维)大小。
<?xml version="1.0" encoding="utf-8"?> <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"> <SOAP-ENV:Body> <m:echo2DStringArray xmlns:m="http://soapinterop.org/"> <input2DStringArray SOAP-ENC:arrayType="xsd:string[,3]" SOAP-ENC:offset="[2,0]"> <item>2,0</item> <item>2,1</item> <item>2,2</item> <item>3,0</item> <item>3,1</item> <item>3,2</item> <item>4,0</item> <item>4,1</item> <item>4,2</item> </input2DStringArray> </m:echo2DStringArray> </SOAP-ENV:Body> </SOAP-ENV:Envelope>
参考资料
- 您可以参阅本文在 developerWorks 全球站点上的 英文原文.
- 请通过单击本文顶部或底部的 讨论来参加关于本文的 讨论论坛。
- 在本系列的第 1 部分(“使用 WSDL 部署 Web 服务”)“ Bilal Siddiqui 著的对 Web 服务和 WSDL 的介绍”中,我阐述了如何创建、部署和发布 Web 服务。
- 在“ 第 2 部分:简单对象访问协议(Simple Object Access Protocol,SOAP)”中,Bilal 对 SOAP 协议及其语法进行了彻底的讨论。
- 您可以通过阅读入门文章“ Tony Hong 著的 Advancing SOAP Interoperability”来了解 SOAPBuilders 社区成果。
- 在 SOAPBuilders Interoperability Lab可以获得有关 SOAPBuilders 互操作性的完整信息。
- SOAPBuilders 第 2 轮测试是由 WhiteMesa 主办的。
- 请看看 Yahoo 集团的 SOAPBuilders 讨论小组以了解最新的互操作性问题。
- 请 下载SOAP 客户机并亲自尝试这些测试。
- 请看一看 W3C XML Schema Part 2: Datatypes上的完整数据类型列表,该列表可以用于定义 SOAP 消息中的数据的类型。
- 您可以看一看 SOAP 版本 1.1 W3C 纪要和 SOAP Version 1.2 Part 0: Primer,以获得关于 SOAP 协议的语义的详细介绍。