SOAP - 快速指南
什么是 SOAP?
SOAP 是简单对象访问协议的缩写。它是一种基于 XML 的消息传递协议,用于在计算机之间交换信息。SOAP 是XML 规范的一个应用。
注意事项
- SOAP 是一种旨在通过 Internet 进行通信的通信协议。 
- SOAP 可以扩展 HTTP 以进行 XML 消息传递。 
- SOAP 为 Web 服务提供数据传输。 
- SOAP 可以交换完整的文档或调用远程过程。 
- SOAP 可用于广播消息。 
- SOAP 与平台和语言无关。 
- SOAP 是定义发送什么信息以及如何发送信息的 XML 方式。 
- SOAP 使客户端应用程序能够轻松连接到远程服务并调用远程方法。 
尽管 SOAP 可以用于各种消息传递系统,并且可以通过各种传输协议进行传递,但 SOAP 最初的重点是通过 HTTP 传输的远程过程调用。
其他框架(包括 CORBA、DCOM 和 Java RMI)提供与 SOAP 类似的功能,但 SOAP 消息完全用 XML 编写,因此具有独特的平台和语言无关性。
SOAP - 消息结构
SOAP 消息是一个普通的 XML 文档,包含以下元素 -
- 信封- 定义消息的开始和结束。它是一个强制性要素。 
- 标头- 包含在中间点或最终端点处理消息时使用的消息的任何可选属性。它是一个可选元素。 
- 正文- 包含包含正在发送的消息的 XML 数据。它是一个强制性要素。 
- 故障- 可选的故障元素,提供有关处理消息时发生的错误的信息。 
所有这些元素都在 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 信封指示消息的开始和结束,以便接收者知道何时接收到整个消息。SOAP 信封解决了了解何时完成消息接收并准备好处理它的问题。因此,SOAP 信封基本上是一种打包机制。
注意事项
- 每个 SOAP 消息都有一个根 Envelope 元素。 
- 信封是 SOAP 消息的必需部分。 
- 每个 Envelope 元素必须恰好包含一个 Body 元素。 
- 如果 Envelope 包含 Header 元素,则它只能包含一个 Header 元素,并且它必须作为 Envelope 的第一个子元素出现在 Body 之前。 
- 当 SOAP 版本更改时,信封也会更改。 
- 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 元素可用于指定受密码保护的服务的数字签名。同样,它可用于指定按次付费 SOAP 服务的帐号。
注意事项
- 它是 SOAP 消息的可选部分。 
- 标头元素可以出现多次。 
- 标头旨在添加新特性和功能。 
- SOAP 标头包含命名空间中定义的标头条目。 
- 标头被编码为 SOAP 信封的第一个直接子元素。 
- 当定义多个标头时,SOAP 标头的所有直接子元素都被解释为 SOAP 标头块。 
SOAP 标头属性
SOAP 标头可以具有以下两个属性 -
演员属性
SOAP 协议将消息路径定义为 SOAP 服务节点的列表。每个中间节点都可以执行一些处理,然后将消息转发到链中的下一个节点。通过设置Actor属性,客户端可以指定SOAP标头的接收者。
必须理解的属性
它指示 Header 元素是可选的还是强制的。如果设置为 true,则接收方必须根据其定义的语义理解并处理 Header 属性,否则返回错误。
以下示例显示如何在 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>
      <t:Transaction 
         xmlns:t = "http://www.tutorialspoint.com/transaction/" 
         SOAP-ENV:mustUnderstand = "true">5
      </t:Transaction>
   </SOAP-ENV:Header>
   ...
   ...
</SOAP-ENV:Envelope>
肥皂 - 主体
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>
通常,应用程序还定义一个模式来包含与请求和响应元素关联的语义。
报价服务可以使用运行在应用程序服务器中的EJB 来实现;如果是这样,SOAP 处理器将负责将主体信息作为参数映射到GetQuotationResponse服务的 EJB 实现中或从中映射出来。SOAP 处理器还可以将主体信息映射到 .NET 对象、CORBA 对象、COBOL 程序等。
SOAP - 故障
如果在处理过程中发生错误,则对 SOAP 消息的响应是消息正文中的 SOAP 错误元素,并将错误返回给 SOAP 消息的发送者。
SOAP 错误机制返回有关错误的特定信息,包括预定义代码、描述以及生成错误的 SOAP 处理器的地址。
注意事项
- 一条 SOAP 消息只能携带一个故障块。 
- 错误是 SOAP 消息的可选部分。 
- 对于 HTTP 绑定,成功的响应链接到 200 到 299 范围的状态代码。 
- SOAP 错误与 500 到 599 范围的状态代码相关联。 
故障的子要素
SOAP 错误有以下子元素 -
| 先生编号 | 子元素和描述 | 
|---|---|
| 1 | <故障代码> 它是用于指示一类错误的文本代码。请参阅下表了解预定义故障代码的列表。 | 
| 2 | <故障字符串> 这是一条解释错误的短信。 | 
| 3 | <故障参与者> 它是一个文本字符串,指示谁造成了故障。如果 SOAP 消息经过 SOAP 消息路径中的多个节点,并且客户端需要知道哪个节点导致了错误,则此功能非常有用。不充当最终目的地的节点必须包含故障Actor元素。 | 
| 4 | <详细> 它是用于携带特定于应用程序的错误消息的元素。详细信息元素可以包含称为详细信息条目的子元素。 | 
SOAP 故障代码
描述故障时,必须在故障代码元素中使用下面定义的故障代码值。
| 先生编号 | 错误及描述 | 
|---|---|
| 1 | SOAP-ENV:版本不匹配 发现 SOAP Envelope 元素的命名空间无效。 | 
| 2 | SOAP-ENV:必须了解 无法理解 Header 元素的直接子元素(mustUnderstand 属性设置为“1”)。 | 
| 3 | SOAP-ENV:客户端 该消息的格式不正确或包含不正确的信息。 | 
| 4 | SOAP-ENV:服务器 服务器出现问题,因此消息无法继续发送。 | 
SOAP 错误示例
以下代码是示例故障。客户端请求了名为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 模式未标准化的构造,例如数组和引用。 
标量类型
对于标量类型,SOAP 采用 XML Schema 规范指定的所有内置简单类型。这包括字符串、浮点数、双精度数和整数。
下表列出了主要的简单类型,摘自 XML 架构第 0 部分 - 入门http://www.w3.org/TR/2000/WD-xmlschema-0-20000407/
| XML 架构中内置的简单类型 | ||
|---|---|---|
| 简单型 | 例子) | |
| 细绳 | 确认这是电动的。 | |
| 布尔值 | 真、假、1、0。 | |
| 漂浮 | -INF、-1E4、-0、0、12.78E-2、12、INF、NaN。 | |
| 双倍的 | -INF、-1E4、-0、0、12.78E-2、12、INF、NaN。 | |
| 小数 | -1.23、0、123.4、1000.00。 | |
| 二进制 | 100010 | |
| 整数 | -126789, -1, 0, 1, 126789。 | |
| 非正整数 | -126789, -1, 0。 | |
| 负整数 | -126789,-1。 | |
| 长的 | -1, 12678967543233 | |
| 整数 | -1, 126789675 | |
| 短的 | -1, 12678 | |
| 字节 | -1, 126 | |
| 非负整数 | 0, 1, 126789 | |
| 无符号长整型 | 0, 12678967543233 | |
| 无符号整数 | 0, 1267896754 | |
| 无符号短整型 | 0, 12678 | |
| 无符号字节 | 0, 126 | |
| 正整数 | 1、126789。 | |
| 日期 | 1999-05-31, ---05. | |
| 时间 | 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 Translation 服务,您必须将以下内容指定为 SOAPAction 标头。
urn:xmethodsBabelFish#BabelFish
即使服务器不需要完整的 SOAPAction 标头,客户端也必须指定空字符串 ("") 或 null 值。例如 -
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 方法需要两个 String 参数。翻译模式 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 响应包含错误元素。
SOAP - 示例
在下面的示例中,GetQuotation请求通过 HTTP 发送到 SOAP 服务器。请求有一个QuotationName参数,响应中会返回一个Quotation。
该函数的命名空间在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。官方提交者包括 Microsoft、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 消息能够包含二进制附件,例如图像和声音文件。有关完整详细信息,请参阅http://www.w3.org/TR/SOAP-attachments上的 W3C 注释。
