SOAP基础

引言:

SOAP是一种基于XML的简易协议,用于在应用程序之间进行信息交换,常用于访问网络服务。以下是关于SOAP的重要信息:

  • SOAP全称为简易对象访问协议(Simple Object Access Protocol),是一种通信协议,用于应用程序之间的通信。
  • SOAP通过XML格式来发送消息,被设计用于通过因特网进行通信,独立于平台和语言,且简单并可扩展。
  • 使用SOAP可以绕过防火墙,并将被作为W3C标准来发展。
  • SOAP的出现解决了应用程序开发中的兼容性、安全性和防火墙问题,提供了一种标准的方法,使得运行在不同操作系统和使用不同编程语言的应用程序可以互相进行通信。
  • Microsoft的.NET架构将SOAP作为关键元素,并提交了SOAP 1.1到W3C。
  • 目前,W3C正在发展SOAP 1.2,旨在进一步完善SOAP协议的标准化和功能。

SOAP语法

SOAP消息的构建模块遵循以下语法规则:

  • SOAP消息是一个普通的XML文档,包含以下元素:
    • 必需的Envelope元素,用于标识该XML文档为一条SOAP消息。
    • 可选的Header元素,包含头部信息。
    • 必需的Body元素,包含所有的调用和响应信息。
    • 可选的Fault元素,提供关于处理消息时发生错误的信息。
  • 所有这些元素都声明在SOAP封装的默认命名空间中(http://www.w3.org/2001/12/soap-envelope)和SOAP编码和数据类型的默认命名空间中(http://www.w3.org/2001/12/soap-encoding)。
  • SOAP消息必须使用XML编码,并且必须使用SOAP Envelope命名空间和SOAP Encoding命名空间。
  • SOAP消息不能包含DTD引用或XML处理指令。

以下是SOAP消息的基本结构示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?xml version="1.0"?>
<soap:Envelope
xmlns:soap="http://www.w3.org/2001/12/soap-envelope"
soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding">

<soap:Header>
<!-- 头部信息 -->
</soap:Header>

<soap:Body>
<!-- 调用和响应信息 -->
<soap:Fault>
<!-- 错误信息 -->
</soap:Fault>
</soap:Body>

</soap:Envelope>

这个XML片段是一个SOAP消息的示例,它遵循了SOAP协议的结构和规范。以下是对其中各部分的解释:

  • <soap:Envelope>:SOAP消息的根元素,它声明了SOAP命名空间(xmlns:soap="http://www.w3.org/2001/12/soap-envelope"),以及SOAP编码样式(soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding")。所有的SOAP消息都必须从这个元素开始。

  • <soap:Header>:SOAP消息的头部部分,其中可以包含一些与消息相关的元数据或信息。它是可选的,因此在示例中是注释掉的。

  • <soap:Body>:SOAP消息的主体部分,包含了具体的调用和响应信息。它是必需的,用于承载实际的操作数据。

  • <soap:Fault>:SOAP消息中的错误部分,用于描述在处理消息时发生的错误。它是可选的,只有在发生错误时才会包含在消息中。在示例中,它也是注释掉的。

整个XML片段构成了一个符合SOAP协议规范的消息结构,用于在应用程序之间进行信息交换。

SOAP Envelope 元素

SOAP Envelope元素是SOAP消息的根元素,必须存在于每个SOAP消息中。它将XML文档定义为SOAP消息。

在下面的示例中,SOAP Envelope元素具有名为soap的命名空间,其命名空间URI为"http://www.w3.org/2001/12/soap-envelope"。此命名空间声明告诉解析器这是一个SOAP消息。

1
2
3
4
5
6
7
8
<?xml version="1.0"?>
<soap:Envelope
xmlns:soap="http://www.w3.org/2001/12/soap-envelope"
soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding">
...
Message information goes here
...
</soap:Envelope>
  • <?xml version="1.0"?>: 这是XML声明,指示文档的版本和编码方式。

  • <soap:Envelope xmlns:soap="http://www.w3.org/2001/12/soap-envelope" soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding">: 这是SOAP消息的根元素,名为Envelope,它声明了一个命名空间 soap,其URI为 http://www.w3.org/2001/12/soap-envelope,告诉解析器这是一个SOAP消息。同时,它还包含了一个soap:encodingStyle属性,用于定义消息中所使用的数据编码样式,其URI为 http://www.w3.org/2001/12/soap-encoding

  • ... Message information goes here ...: 这个部分是SOAP消息的内容,具体消息信息应该在这里。SOAP消息的实际内容将包含在<soap:Body>元素中。

  • </soap:Envelope>: 这个标签结束了SOAP消息的Envelope部分。

SOAP Header 元素

SOAP Header元素是SOAP消息的可选部分,用于包含与消息相关的应用程序专用信息,例如身份验证、授权或其他自定义数据。在SOAP消息中,如果存在Header元素,它必须是Envelope元素的第一个子元素。

在提供了一个Header元素后,其直接子元素必须位于正确的命名空间内。下面是一个具体示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
<?xml version="1.0"?>
<soap:Envelope
xmlns:soap="http://www.w3.org/2001/12/soap-envelope"
soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding">

<soap:Header>
<m:Trans xmlns:m="http://www.w3schools.com/transaction/"
soap:mustUnderstand="1">234
</m:Trans>
</soap:Header>
...
...
</soap:Envelope>

在这个示例中,Header元素包含了一个名为"Trans"的子元素,其命名空间为"http://www.w3schools.com/transaction/"。这个子元素的值为"234",并且具有一个名为"mustUnderstand"的属性,其值为"1",表示接收端必须理解并处理这个头部信息。

SOAP定义了三个属性:actor、mustUnderstand和encodingStyle,这些属性可以用于控制SOAP消息的处理方式。其中,mustUnderstand属性用于指示消息接收者是否必须理解和处理相关头部信息。

这些属性包括:

  1. actor属性:用于指定消息的目标接收者。SOAP消息可能要求在消息传递过程中由特定的角色或实体来处理。actor属性指定了接收者的角色或身份。如果未指定actor属性,则消息默认会发送给主要的接收者。

下面是一些示例,演示了SOAP消息中actor属性的用法:

  1. 发送给默认接收者: 如果不指定actor属性,SOAP消息将默认发送给主要的接收者。

    1
    2
    3
    4
    5
    6
    7
    8
    <soap:Envelope xmlns:soap="http://www.w3.org/2001/12/soap-envelope">
    <soap:Header>
    <!-- 没有指定actor属性,默认发送给主要的接收者 -->
    </soap:Header>
    <soap:Body>
    <!-- 消息体内容 -->
    </soap:Body>
    </soap:Envelope>
  2. 指定特定的角色: 可以通过指定actor属性来将消息发送给特定的角色或实体。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    <soap:Envelope xmlns:soap="http://www.w3.org/2001/12/soap-envelope">
    <soap:Header>
    <m:Transaction xmlns:m="http://example.com/transaction" soap:actor="http://example.com/bank">
    <!-- 消息内容 -->
    </m:Transaction>
    </soap:Header>
    <soap:Body>
    <!-- 消息体内容 -->
    </soap:Body>
    </soap:Envelope>

    在这个示例中,消息被发送给了银行角色,因此银行将负责处理这条消息。

  3. 消息的多个接收者: 有时候,消息可能需要发送给多个不同的接收者。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    <soap:Envelope xmlns:soap="http://www.w3.org/2001/12/soap-envelope">
    <soap:Header>
    <m:Transaction xmlns:m="http://example.com/transaction" soap:actor="http://example.com/bank1">
    <!-- 消息内容 -->
    </m:Transaction>
    <m:Transaction xmlns:m="http://example.com/transaction" soap:actor="http://example.com/bank2">
    <!-- 消息内容 -->
    </m:Transaction>
    </soap:Header>
    <soap:Body>
    <!-- 消息体内容 -->
    </soap:Body>
    </soap:Envelope>

    在这个示例中,消息被发送给了两个不同的银行,每个银行都有自己的actor属性。

  1. mustUnderstand属性:这是一个布尔值,用于指示接收者是否必须理解并处理SOAP头部中的相关信息。如果mustUnderstand属性设置为"true"或"1",那么接收者必须能够理解并处理相应的头部信息。如果接收者不能理解或处理这些信息,它必须返回一个SOAP Fault以通知发送者消息无法处理。如果设置为"false"或"0",则接收者可以选择性地忽略这些信息。

以下是一个示例,演示了SOAP消息中mustUnderstand属性的用法:

1
2
3
4
5
6
7
8
9
10
11
<soap:Envelope xmlns:soap="http://www.w3.org/2001/12/soap-envelope">
<soap:Header>
<!-- 包含一个必须理解的头部信息 -->
<m:Transaction xmlns:m="http://example.com/transaction" soap:mustUnderstand="1">
<!-- 消息内容 -->
</m:Transaction>
</soap:Header>
<soap:Body>
<!-- 消息体内容 -->
</soap:Body>
</soap:Envelope>

在这个示例中,Transaction头部信息的mustUnderstand属性被设置为"1",表示接收者必须能够理解和处理此头部信息。如果接收者无法理解或处理这个头部信息,它必须返回一个SOAP Fault以通知发送者消息无法处理。

  1. encodingStyle属性:这个属性用于指定消息体中所使用的数据编码方式。它指定了用于序列化和解析消息体中数据的编码规则。默认情况下,SOAP消息体中的数据使用XML作为编码方式,但也可以指定其他编码方式,例如基于二进制的编码。这个属性对于处理复杂的数据类型和数据结构非常重要。

以下是一个示例,演示了SOAP消息中encodingStyle属性的用法:

1
2
3
4
5
6
7
8
9
<soap:Envelope xmlns:soap="http://www.w3.org/2001/12/soap-envelope"
soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding">
<soap:Header>
<!-- SOAP头部信息 -->
</soap:Header>
<soap:Body>
<!-- 消息体内容,使用了指定的编码方式 -->
</soap:Body>
</soap:Envelope>

在这个示例中,encodingStyle属性被设置为"http://www.w3.org/2001/12/soap-encoding",表示消息体中的数据将使用SOAP编码方式进行编码和解析。这意味着消息体中的数据将按照SOAP规范定义的编码规则进行序列化和解析。

SOAP Body 元素

SOAP Body 元素:

  • SOAP Body 元素是 SOAP 消息的必需部分,用于携带实际的 SOAP 消息内容。
  • 其直接子元素可以使用合法的命名空间。
  • 在 SOAP 请求中,SOAP Body 承载了要发送到消息最终端点的请求信息。
  • 在 SOAP 响应中,SOAP Body 承载了来自服务端的响应信息。

示例:

SOAP 请求示例:

1
2
3
4
5
6
7
8
9
10
<soap:Envelope
xmlns:soap="http://www.w3.org/2001/12/soap-envelope"
soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding">
<soap:Body>
<m:PlaceOrder xmlns:m="http://www.example.com/orders">
<m:Product>Computer</m:Product>
<m:Quantity>2</m:Quantity>
</m:PlaceOrder>
</soap:Body>
</soap:Envelope>

在上述示例中,SOAP Body 中的 <m:PlaceOrder> 元素是一个请求操作,用于向服务端提交订单。<m:Product> 子元素包含了要订购的产品名称,而 <m:Quantity> 子元素包含了产品的数量。

SOAP 响应示例:

1
2
3
4
5
6
7
8
9
10
<soap:Envelope
xmlns:soap="http://www.w3.org/2001/12/soap-envelope"
soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding">
<soap:Body>
<m:OrderConfirmation xmlns:m="http://www.example.com/orders">
<m:OrderID>123456</m:OrderID>
<m:Status>Confirmed</m:Status>
</m:OrderConfirmation>
</soap:Body>
</soap:Envelope>

在上述示例中,SOAP Body 中的 <m:OrderConfirmation> 元素是一个响应操作,用于返回订单确认信息。<m:OrderID> 子元素包含了订单号,而 <m:Status> 子元素包含了订单状态。

SOAP Fault 元素

  • SOAP Fault 元素用于携带 SOAP 消息的错误和状态信息。
  • 它是 SOAP 消息中的可选元素,用于指示错误消息。
  • 在一条 SOAP 消息中,Fault 元素只能出现一次,并且必须是 Body 元素的子元素。
  • SOAP 的 Fault 元素包含以下子元素来描述错误信息:
    • <faultcode>:用于标识故障的代码。
    • <faultstring>:提供人类可读的有关故障的描述。
    • <faultactor>:指示故障发生的位置或是谁引发了故障的信息。
    • <detail>:存放与 Body 元素相关的应用程序专用错误信息。

SOAP Fault 代码:

在 SOAP Fault 中,以下定义的 faultcode 值可用于描述不同类型的错误:

  • VersionMismatch:发现了无效的 SOAP Envelope 元素命名空间。
  • MustUnderstand:无法理解 Header 元素的一个直接子元素,该子元素具有设置为 "1" 的 mustUnderstand 属性。
  • Client:消息的构造方式不正确,或包含了不正确的信息。
  • Server:服务器出现问题,因此无法继续处理请求。

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
<soap:Envelope xmlns:soap="http://www.w3.org/2001/12/soap-envelope">
<soap:Body>
<soap:Fault>
<faultcode>Server</faultcode>
<faultstring>Internal Server Error</faultstring>
<faultactor>http://example.com/service</faultactor>
<detail>
<errorcode>500</errorcode>
<message>Internal Server Error occurred while processing the request.</message>
</detail>
</soap:Fault>
</soap:Body>
</soap:Envelope>

这是一个包含 SOAP 错误信息的示例 XML 文档。让我们逐个解释其中的每个部分:

  • <soap:Envelope>:SOAP 消息的根元素,命名空间为 http://www.w3.org/2001/12/soap-envelope

  • <soap:Body>:SOAP 消息的主体部分,其中包含了实际的 SOAP 消息内容。

  • <soap:Fault>:SOAP 错误信息的容器元素,用于指示出现的错误。

    • <faultcode>:定义了错误的代码或分类。在这里,它被设置为 Server,表示此错误是由服务器引起的。

    • <faultstring>:提供了人类可读的错误描述。在这里,它被设置为 Internal Server Error,说明出现了内部服务器错误。

    • <faultactor>:指示了错误发生的位置或是谁引发了错误。通常用于标识服务的端点。在这里,它被设置为 http://example.com/service,表示错误发生在该服务的端点。

    • <detail>:存放了与错误相关的详细信息。它包含了两个子元素:

      • <errorcode>:定义了错误的代码,这里被设置为 500,表示内部服务器错误。
      • <message>:提供了详细的错误消息,说明了在处理请求时发生了内部服务器错误。

这个示例展示了一个典型的 SOAP 错误消息,包含了有关错误的各种信息,使得客户端能够理解发生的问题并采取适当的措施。

SOAP HTTP 协议

HTTP协议是基于TCP/IP的应用层协议,用于在客户端和服务器之间传输数据。客户端通过TCP连接与HTTP服务器通信,发送HTTP请求消息,服务器处理请求后发送HTTP响应消息。HTTP请求消息包含请求行、请求头和消息体,其中请求行包括请求方法、URI和协议版本;HTTP响应消息包含状态行、响应头和消息体,其中状态行包括状态码和状态消息。

SOAP HTTP绑定是将SOAP消息与HTTP协议进行绑定,实现了在HTTP上传输SOAP消息的规范。SOAP请求可以是HTTP POST或HTTP GET请求。HTTP POST请求是SOAP消息的常见传输方式,其中至少包含两个HTTP头:Content-Type和Content-Length。

  • Content-Type:指定消息的MIME类型和可选的字符编码,用于定义请求或响应的XML主体的格式。例如,Content-Type: application/soap+xml; charset=utf-8表示消息主体是XML格式的SOAP消息,字符编码是UTF-8。

  • Content-Length:指定请求或响应主体的字节数。例如,Content-Length: 250表示消息主体的长度为250字节。

这些HTTP头信息有助于定义SOAP消息的格式和传输方式,确保客户端和服务器之间的通信能够按照预期进行。

例子:

假设我们有一个名为"GetStockPrice"的SOAP方法,用于获取股票价格。下面是一个使用HTTP POST方法传输SOAP消息的示例:

请求:

1
2
3
4
5
6
7
8
9
10
11
12
POST /stockservice HTTP/1.1
Host: example.com
Content-Type: application/soap+xml; charset=utf-8
Content-Length: 320

<soap:Envelope xmlns:soap="http://www.w3.org/2001/12/soap-envelope">
<soap:Body>
<m:GetStockPrice xmlns:m="http://example.com/stockservice">
<m:StockSymbol>ABC</m:StockSymbol>
</m:GetStockPrice>
</soap:Body>
</soap:Envelope>

在这个例子中,客户端向example.com/stockservice端点发送了一个HTTP POST请求,内容类型为application/soap+xml,字符编码为UTF-8。请求主体包含了一个SOAP Envelope,其中包含一个GetStockPrice方法调用,请求的股票符号为"ABC"。

响应:

1
2
3
4
5
6
7
8
9
10
11
12
HTTP/1.1 200 OK
Content-Type: application/soap+xml; charset=utf-8
Content-Length: 250

<soap:Envelope xmlns:soap="http://www.w3.org/2001/12/soap-envelope">
<soap:Body>
<m:GetStockPriceResponse xmlns:m="http://example.com/stockservice">
<m:StockSymbol>ABC</m:StockSymbol>
<m:Price>50.00</m:Price>
</m:GetStockPriceResponse>
</soap:Body>
</soap:Envelope>

在响应中,服务器返回了状态码为200的HTTP响应,内容类型同样为application/soap+xml,字符编码为UTF-8。响应主体包含了一个SOAP Envelope,其中包含了对应于"ABC"股票价格的响应信息。

总结:

  1. SOAP Envelope 元素:定义了整个 SOAP 消息的结构。
  2. SOAP Header 元素:用于包含一些额外的信息,例如身份验证信息。
  3. SOAP Body 元素:包含实际的 SOAP 方法调用信息。
  4. SOAP Fault 元素:用于指示发生的错误,如果调用失败时,将包含错误信息。
  5. SOAP HTTP Binding:定义了如何在 HTTP 上传输 SOAP 消息。