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

广告