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 注释。