- SOAP 教程
- SOAP - 首页
- SOAP - 什么是 SOAP?
- SOAP - 消息
- SOAP - 信封 (Envelope)
- SOAP - 头部 (Header)
- SOAP - 主体 (Body)
- SOAP - 故障 (Fault)
- SOAP - 编码
- SOAP - 传输
- SOAP - 示例
- SOAP - 标准
- SOAP 资源
- SOAP 快速指南
- SOAP - 有用资源
- SOAP - 讨论
SOAP 快速指南
什么是 SOAP?
SOAP 是简单对象访问协议 (Simple Object Access Protocol) 的缩写。它是一个基于 XML 的消息协议,用于在计算机之间交换信息。SOAP 是 XML 规范的一个应用。
要点
SOAP 是一种旨在通过互联网进行通信的通信协议。
SOAP 可以扩展 HTTP 用于 XML 消息传递。
SOAP 为 Web 服务提供数据传输。
SOAP 可以交换完整的文档或调用远程过程。
SOAP 可用于广播消息。
SOAP 与平台和语言无关。
SOAP 是定义发送什么信息以及如何发送信息的 XML 方法。
SOAP 使客户端应用程序能够轻松连接到远程服务并调用远程方法。
尽管 SOAP 可用于各种消息系统,并可以通过各种传输协议进行传输,但 SOAP 的最初重点是通过 HTTP 传输的远程过程调用。
包括 CORBA、DCOM 和 Java RMI 在内的其他框架提供与 SOAP 相似的功能,但 SOAP 消息完全是用 XML 编写的,因此具有独特的平台和语言无关性。
SOAP - 消息结构
SOAP 消息是一个普通的 XML 文档,包含以下元素:
信封 (Envelope) - 定义消息的开始和结束。这是一个必填元素。
头部 (Header) - 包含消息的任何可选属性,这些属性用于处理消息,无论是在中间点还是在最终端点。这是一个可选元素。
主体 (Body) - 包含构成正在发送的消息的 XML 数据。这是一个必填元素。
故障 (Fault) - 一个可选的 Fault 元素,提供有关处理消息时发生的错误的信息。
所有这些元素都在 SOAP 信封的默认命名空间中声明 - http://www.w3.org/2001/12/soap-envelope,SOAP 编码和数据类型的默认命名空间是 - http://www.w3.org/2001/12/soap-encoding
注意 - 所有这些规范都可能发生变化。因此,请随时更新 W3 网站上提供的最新规范。
SOAP 消息结构
以下代码块描述了 SOAP 消息的通用结构:
<?xml version = "1.0"?> <SOAP-ENV:Envelope xmlns:SOAP-ENV = "http://www.w3.org/2001/12/soap-envelope" SOAP-ENV:encodingStyle = "http://www.w3.org/2001/12/soap-encoding"> <SOAP-ENV:Header> ... ... </SOAP-ENV:Header> <SOAP-ENV:Body> ... ... <SOAP-ENV:Fault> ... ... </SOAP-ENV:Fault> ... </SOAP-ENV:Body> </SOAP_ENV:Envelope>
SOAP - 信封 (Envelope)
SOAP 信封指示消息的开始和结束,以便接收者知道何时已收到整条消息。SOAP 信封解决了知道何时完成接收消息并准备好处理它的问题。因此,SOAP 信封基本上是一种打包机制。
要点
每个 SOAP 消息都有一个根 Envelope 元素。
Envelope 是 SOAP 消息的必填部分。
每个 Envelope 元素必须包含且只能包含一个 Body 元素。
如果 Envelope 包含 Header 元素,则它最多只能包含一个,并且必须作为 Envelope 的第一个子元素出现在 Body 之前。
当 SOAP 版本更改时,Envelope 也会更改。
SOAP 信封使用 *ENV* 命名空间前缀和 Envelope 元素指定。
可选的 SOAP 编码也使用命名空间名称和可选的 *encodingStyle* 元素指定,该元素也可以指向除 SOAP 编码之外的其他编码样式。
符合 v1.1 的 SOAP 处理器在接收到包含 v1.2 信封命名空间的消息时会生成故障。
符合 v1.2 的 SOAP 处理器如果接收到不包含 v1.2 信封命名空间的消息,则会生成 *VersionMismatch* 故障。
符合 v1.2 的 SOAP 消息
下面是一个符合 v1.2 的 SOAP 消息示例。
<?xml version = "1.0"?> <SOAP-ENV:Envelope xmlns:SOAP-ENV = "http://www.w3.org/2001/12/soap-envelope" SOAP-ENV:encodingStyle = " http://www.w3.org/2001/12/soap-encoding"> ... Message information goes here ... </SOAP-ENV:Envelope>
使用 HTTP POST 的 SOAP
以下示例说明了在 HTTP POST 操作中使用 SOAP 消息的情况,该操作将消息发送到服务器。它显示了信封模式定义和编码规则模式定义的命名空间。HTTP 标头中的 *OrderEntry* 引用是要在 tutorialspoint.com 网站上调用的程序的名称。
POST /OrderEntry HTTP/1.1 Host: www.tutorialspoint.com Content-Type: application/soap; charset = "utf-8" Content-Length: nnnn <?xml version = "1.0"?> <SOAP-ENV:Envelope xmlns:SOAP-ENV = "http://www.w3.org/2001/12/soap-envelope" SOAP-ENV:encodingStyle = " http://www.w3.org/2001/12/soap-encoding"> ... Message information goes here ... </SOAP-ENV:Envelope>
注意 - HTTP 绑定指定服务的地址。
SOAP - 头部 (Header)
可选的 Header 元素提供了一个灵活的框架,用于指定其他应用程序级需求。例如,Header 元素可用于为密码保护的服务指定数字签名。同样,它可用于为按次付费的 SOAP 服务指定帐号。
要点
它是 SOAP 消息的可选部分。
Header 元素可以多次出现。
Header 的目的是添加新的特性和功能。
SOAP 头部包含在命名空间中定义的头部条目。
头部被编码为 SOAP 信封的第一个直接子元素。
当定义多个头部时,SOAP 头部的所有直接子元素都解释为 SOAP 头部块。
SOAP 头部属性
SOAP 头部可以具有以下两个属性:
Actor 属性
SOAP 协议将消息路径定义为 SOAP 服务节点列表。这些中间节点中的每一个都可以执行一些处理,然后将消息转发到链中的下一个节点。通过设置 Actor 属性,客户端可以指定 SOAP 头部的接收者。
MustUnderstand 属性
它指示 Header 元素是可选的还是必须的。如果设置为 true,则接收者必须根据其定义的语义理解和处理 Header 属性,否则返回故障。
以下示例显示如何在 SOAP 消息中使用 Header。
<?xml version = "1.0"?> <SOAP-ENV:Envelope xmlns:SOAP-ENV = " http://www.w3.org/2001/12/soap-envelope" SOAP-ENV:encodingStyle = " http://www.w3.org/2001/12/soap-encoding"> <SOAP-ENV:Header> <t:Transaction xmlns:t = "https://tutorialspoint.com/transaction/" SOAP-ENV:mustUnderstand = "true">5 </t:Transaction> </SOAP-ENV:Header> ... ... </SOAP-ENV:Envelope>
SOAP - 主体 (Body)
SOAP 主体是一个必填元素,它包含在 SOAP 消息中交换的应用程序定义的 XML 数据。主体必须包含在信封中,并且必须遵循为消息定义的任何头部。
主体定义为信封的子元素,主体的语义在关联的 SOAP 模式中定义。
主体包含打算用于消息最终接收者的必填信息。例如:
<?xml version = "1.0"?> <SOAP-ENV:Envelope> ........ <SOAP-ENV:Body> <m:GetQuotation xmlns:m = "http://www.tp.com/Quotation"> <m:Item>Computers</m:Item> </m:GetQuotation> </SOAP-ENV:Body> </SOAP-ENV:Envelope>
上面的示例请求计算机套装的报价。请注意,上面的 m:GetQuotation 和 Item 元素是特定于应用程序的元素。它们不是 SOAP 标准的一部分。
以下是上述查询的响应:
<?xml version = "1.0"?> <SOAP-ENV:Envelope> ........ <SOAP-ENV:Body> <m:GetQuotationResponse xmlns:m = "http://www.tp.com/Quotation"> <m:Quotation>This is Qutation</m:Quotation> </m:GetQuotationResponse> </SOAP-ENV:Body> </SOAP-ENV:Envelope>
通常,应用程序还定义一个模式来包含与请求和响应元素相关的语义。
*Quotation* 服务可以使用在应用程序服务器中运行的 EJB 来实现;如果是这样,SOAP 处理器将负责将主体信息作为参数映射到 *GetQuotationResponse* 服务的 EJB 实现中和从中映射出来。SOAP 处理器还可以将主体信息映射到 .NET 对象、CORBA 对象、COBOL 程序等等。
SOAP - 故障 (Fault)
如果在处理过程中发生错误,则对 SOAP 消息的响应是消息主体中的 SOAP fault 元素,并且 fault 会返回给 SOAP 消息的发送者。
SOAP fault 机制返回有关错误的特定信息,包括预定义的代码、描述和生成 fault 的 SOAP 处理器的地址。
要点
SOAP 消息只能携带一个 fault 块。
Fault 是 SOAP 消息的可选部分。
对于 HTTP 绑定,成功的响应与 200 到 299 范围的状态代码相关联。
SOAP Fault 与 500 到 599 范围的状态代码相关联。
Fault 的子元素
SOAP Fault 具有以下子元素:
序号 | 子元素和描述 |
---|---|
1 | <faultCode> 它是一个文本代码,用于指示一类错误。请参阅下表以获取预定义故障代码的列表。 |
2 | <faultString> 它是一个解释错误的文本消息。 |
3 | <faultActor> 它是一个文本字符串,指示谁导致了故障。如果 SOAP 消息通过 SOAP 消息路径中的多个节点传输,并且客户端需要知道哪个节点导致了错误,这将非常有用。不充当最终目标的节点必须包含 *faultActor* 元素。 |
4 | <detail> 它是一个用于携带特定于应用程序的错误消息的元素。detail 元素可以包含称为 detail 条目的子元素。 |
SOAP 故障代码
在描述故障时,必须在 *faultcode* 元素中使用以下定义的 faultCode 值。
序号 | 错误和描述 |
---|---|
1 | SOAP-ENV:VersionMismatch 找到 SOAP Envelope 元素的无效命名空间。 |
2 | SOAP-ENV:MustUnderstand Header 元素的直接子元素,其 mustUnderstand 属性设置为“1”,未被理解。 |
3 | SOAP-ENV:Client 消息格式不正确或包含不正确的信息。 |
4 | SOAP-ENV:Server 服务器出现问题,因此消息无法继续。 |
SOAP 故障示例
以下代码是一个示例 Fault。客户端请求了一个名为 *ValidateCreditCard* 的方法,但服务不支持此方法。这表示客户端请求错误,服务器返回以下 SOAP 响应:
<?xml version = '1.0' encoding = 'UTF-8'?> <SOAP-ENV:Envelope xmlns:SOAP-ENV = "http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi = "http://www.w3.org/1999/XMLSchema-instance" xmlns:xsd = "http://www.w3.org/1999/XMLSchema"> <SOAP-ENV:Body> <SOAP-ENV:Fault> <faultcode xsi:type = "xsd:string">SOAP-ENV:Client</faultcode> <faultstring xsi:type = "xsd:string"> Failed to locate method (ValidateCreditCard) in class (examplesCreditCard) at /usr/local/ActivePerl-5.6/lib/site_perl/5.6.0/SOAP/Lite.pm line 1555. </faultstring> </SOAP-ENV:Fault> </SOAP-ENV:Body> </SOAP-ENV:Envelope>
SOAP - 编码
SOAP 包含一组内置规则,用于编码数据类型。它使 SOAP 消息能够指示特定数据类型,例如整数、浮点数、双精度数或数组。
SOAP 数据类型分为两大类:标量类型和复合类型。
标量类型恰好包含一个值,例如姓氏、价格或产品描述。
复合类型包含多个值,例如采购订单或股票报价列表。
复合类型进一步细分为数组和结构。
SOAP 消息的编码样式通过 *SOAP-ENV:encodingStyle* 属性设置。
要使用 SOAP 1.1 编码,请使用值 http://schemas.xmlsoap.org/soap/encoding/
要使用 SOAP 1.2 编码,请使用值 http://www.w3.org/2001/12/soap-encoding
最新的SOAP规范采用了XML Schema定义的所有内置类型。但是,SOAP仍然保持其自身约定来定义XML Schema未标准化的结构,例如数组和引用。
标量类型
对于标量类型,SOAP采用XML Schema规范指定的所有内置简单类型。这包括字符串、浮点数、双精度浮点数和整数。
下表列出了主要简单类型,摘自XML Schema Part 0 − Primer http://www.w3.org/TR/2000/WD-xmlschema-0-20000407/
XML Schema内置的简单类型 | ||
---|---|---|
简单类型 | 示例 | |
string | 确认这是电动的。 | |
boolean | true, false, 1, 0。 | |
float | -INF, -1E4, -0, 0, 12.78E-2, 12, INF, NaN。 | |
double | -INF, -1E4, -0, 0, 12.78E-2, 12, INF, NaN。 | |
decimal | -1.23, 0, 123.4, 1000.00. | |
binary | 100010 | |
integer | -126789, -1, 0, 1, 126789. | |
nonPositiveInteger | -126789, -1, 0. | |
negativeInteger | -126789, -1. | |
long | -1, 12678967543233 | |
int | -1, 126789675 | |
short | -1, 12678 | |
byte | -1, 126 | |
nonNegativeInteger | 0, 1, 126789 | |
unsignedLong | 0, 12678967543233 | |
unsignedInt | 0, 1267896754 | |
unsignedShort | 0, 12678 | |
unsignedByte | 0, 126 | |
positiveInteger | 1, 126789. | |
date | 1999-05-31, ---05. | |
time | 13:20:00.000, 13:20:00.000-05:00 |
例如,这是一个带有双精度浮点数数据类型的SOAP响应:
<?xml version = '1.0' encoding = 'UTF-8'?> <SOAP-ENV:Envelope xmlns:SOAP-ENV = "http://www.w3.org/2001/12/soap-envelope" xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd = "http://www.w3.org/2001/XMLSchema"> <SOAP-ENV:Body> <ns1:getPriceResponse xmlns:ns1 = "urn:examples:priceservice" SOAP-ENV:encodingStyle = "http://www.w3.org/2001/12/soap-encoding"> <return xsi:type = "xsd:double">54.99</return> </ns1:getPriceResponse> </SOAP-ENV:Body> </SOAP-ENV:Envelope>
复合类型
SOAP数组有一套非常具体的规则,要求您同时指定元素类型和数组大小。SOAP也支持多维数组,但并非所有SOAP实现都支持多维功能。
要创建数组,必须将其指定为数组的xsi:type。数组还必须包含一个arrayType属性。此属性是必需的,用于指定所包含元素的数据类型和数组的维度。
例如,以下属性指定了一个包含10个双精度浮点数值的数组:
arrayType = "xsd:double[10]"
相反,以下属性指定了一个二维字符串数组:
arrayType = "xsd:string[5,5]"
这是一个包含双精度浮点数数组的SOAP响应示例:
<?xml version = '1.0' encoding = 'UTF-8'?> <SOAP-ENV:Envelope xmlns:SOAP-ENV = "http://www.w3.org/2001/12/soap-envelope" xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd = "http://www.w3.org/2001/XMLSchema"> <SOAP-ENV:Body> <ns1:getPriceListResponse xmlns:ns1 = "urn:examples:pricelistservice" SOAP-ENV:encodingStyle = "http://www.w3.org/2001/12/soap-encoding"> <return xmlns:ns2 = "http://www.w3.org/2001/09/soap-encoding" xsi:type = "ns2:Array" ns2:arrayType = "xsd:double[2]"> <item xsi:type = "xsd:double">54.99</item> <item xsi:type = "xsd:double">19.99</item> </return> </ns1:getPriceListResponse> </SOAP-ENV:Body> </SOAP-ENV:Envelope>
结构体包含多个值,但每个元素都用唯一的访问器元素指定。例如,考虑产品目录中的一个项目。在这种情况下,结构体可能包含产品SKU、产品名称、描述和价格。以下是这种结构体在SOAP消息中的表示方式:
<?xml version = '1.0' encoding = 'UTF-8'?> <SOAP-ENV:Envelope xmlns:SOAP-ENV = "http://www.w3.org/2001/12/soap-envelope" xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd = "http://www.w3.org/2001/XMLSchema"> <SOAP-ENV:Body> <ns1:getProductResponse xmlns:ns1 = "urn:examples:productservice" SOAP-ENV:encodingStyle = "http://www.w3.org/2001/12/soap-encoding"> <return xmlns:ns2 = "urn:examples" xsi:type = "ns2:product"> <name xsi:type = "xsd:string">Red Hat Linux</name> <price xsi:type = "xsd:double">54.99</price> <description xsi:type = "xsd:string"> Red Hat Linux Operating System </description> <SKU xsi:type = "xsd:string">A358185</SKU> </return> </ns1:getProductResponse> </SOAP-ENV:Body> </SOAP-ENV:Envelope>
注意 -编写SOAP代码时,请注意正确的缩进。结构体中的每个元素都用唯一的访问器名称指定。例如,上面的消息包含四个访问器元素:名称、价格、描述和SKU。每个元素可以有自己的数据类型。例如,名称指定为字符串,而价格指定为双精度浮点数。
SOAP - 传输
SOAP不依赖于任何传输协议。SOAP可以通过SMTP、FTP、IBM的MQSeries或Microsoft消息队列(MSMQ)传输。
SOAP规范只包含HTTP的详细信息。HTTP仍然是最流行的SOAP传输协议。
通过HTTP的SOAP
SOAP请求通过HTTP请求发送,SOAP响应在HTTP响应的内容中返回,这是很符合逻辑的。虽然SOAP请求可以通过HTTP GET发送,但规范只包含HTTP POST的详细信息。
此外,HTTP请求和响应都必须将其内容类型设置为text/xml。
SOAP规范要求客户端必须提供一个SOAPAction标头,但SOAPAction标头的实际值取决于SOAP服务器的实现。
例如,要访问由XMethods托管的AltaVista BabelFish翻译服务,必须将以下内容指定为SOAPAction标头。
urn:xmethodsBabelFish#BabelFish
即使服务器不需要完整的SOAPAction标头,客户端也必须指定一个空字符串("")或空值。例如:
SOAPAction: "" SOAPAction:
这是一个通过HTTP发送到XMethods Babelfish翻译服务的请求示例:
POST /perl/soaplite.cgi HTTP/1.0 Host: services.xmethods.com Content-Type: text/xml; charset = utf-8 Content-Length: 538 SOAPAction: "urn:xmethodsBabelFish#BabelFish" <?xml version = '1.0' encoding = 'UTF-8'?> <SOAP-ENV:Envelope xmlns:SOAP-ENV = "http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi = "http://www.w3.org/1999/XMLSchema-instance" xmlns:xsd = "http://www.w3.org/1999/XMLSchema"> <SOAP-ENV:Body> <ns1:BabelFish xmlns:ns1 = "urn:xmethodsBabelFish" SOAP-ENV:encodingStyle = "http://schemas.xmlsoap.org/soap/encoding/"> <translationmode xsi:type = "xsd:string">en_fr</translationmode> <sourcedata xsi:type = "xsd:string">Hello, world!</sourcedata> </ns1:BabelFish> </SOAP-ENV:Body> </SOAP-ENV:Envelope>
请注意内容类型和SOAPAction标头。还要注意,BabelFish方法需要两个字符串参数。翻译模式en_fr将英语翻译成法语。
以下是来自XMethods的响应:
HTTP/1.1 200 OK Date: Sat, 09 Jun 2001 15:01:55 GMT Server: Apache/1.3.14 (Unix) tomcat/1.0 PHP/4.0.1pl2 SOAPServer: SOAP::Lite/Perl/0.50 Cache-Control: s-maxage = 60, proxy-revalidate Content-Length: 539 Content-Type: text/xml <?xml version = "1.0" encoding = "UTF-8"?> <SOAP-ENV:Envelope xmlns:SOAP-ENC = "http://schemas.xmlsoap.org/soap/encoding/" SOAP-ENV:encodingStyle = "http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsi = "http://www.w3.org/1999/XMLSchema-instance" xmlns:SOAP-ENV = "http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd = "http://www.w3.org/1999/XMLSchema"> <SOAP-ENV:Body> <namesp1:BabelFishResponse xmlns:namesp1 = "urn:xmethodsBabelFish"> <return xsi:type = "xsd:string">Bonjour, monde!</return> </namesp1:BabelFishResponse> </SOAP-ENV:Body> </SOAP-ENV:Envelope>
通过HTTP交付的SOAP响应必须遵循相同的HTTP状态代码。例如,状态代码200 OK表示成功响应。状态代码500内部服务器错误表示存在服务器错误,并且SOAP响应包含一个Fault元素。
SOAP - 示例
在下面的示例中,一个GetQuotation请求通过HTTP发送到SOAP服务器。请求具有一个QuotationName参数,响应中将返回一个报价。
函数的命名空间在http://www.xyz.org/quotation地址中定义。
这是SOAP请求:
POST /Quotation HTTP/1.0 Host: www.xyz.org Content-Type: text/xml; charset = utf-8 Content-Length: nnn <?xml version = "1.0"?> <SOAP-ENV:Envelope xmlns:SOAP-ENV = "http://www.w3.org/2001/12/soap-envelope" SOAP-ENV:encodingStyle = "http://www.w3.org/2001/12/soap-encoding"> <SOAP-ENV:Body xmlns:m = "http://www.xyz.org/quotations"> <m:GetQuotation> <m:QuotationsName>MiscroSoft</m:QuotationsName> </m:GetQuotation> </SOAP-ENV:Body> </SOAP-ENV:Envelope>
相应的SOAP响应如下所示:
HTTP/1.0 200 OK Content-Type: text/xml; charset = utf-8 Content-Length: nnn <?xml version = "1.0"?> <SOAP-ENV:Envelope xmlns:SOAP-ENV = "http://www.w3.org/2001/12/soap-envelope" SOAP-ENV:encodingStyle = "http://www.w3.org/2001/12/soap-encoding"> <SOAP-ENV:Body xmlns:m = "http://www.xyz.org/quotation"> <m:GetQuotationResponse> <m:Quotation>Here is the quotation</m:Quotation> </m:GetQuotationResponse> </SOAP-ENV:Body> </SOAP-ENV:Envelope>
SOAP - 标准
SOAP 1.1最初于2000年5月提交给W3C。正式提交者包括微软、IBM和Ariba等大型公司,以及UserLand Software和DevelopMentor等小型公司。
2001年7月,XML协议工作组发布了SOAP 1.2的“工作草案”。在W3C中,此文档正式处于开发中,这意味着在最终确定之前,该文档可能会多次更新。
SOAP 1.1版本可在网上获得:http://www.w3.org/TR/SOAP/
SOAP 1.2版本的工作草案可在以下网址获得:http://www.w3.org/TR/soap12/
请注意,W3C还托管了“带有附件的SOAP消息”的提交内容,该内容与核心SOAP规范分离。此规范使SOAP消息能够包含二进制附件,例如图像和声音文件。有关完整详细信息,请参阅W3C注释:http://www.w3.org/TR/SOAP-attachments。