对于 Web 应用程序来说,能够通过 Internet 进行通信非常重要。
应用程序之间通信的最佳方式是通过 HTTP,因为所有 Internet 浏览器和服务器都支持 HTTP。 SOAP 的创建就是为了实现这一目标。
SOAP 提供了一种在使用不同技术和编程语言的不同操作系统上运行的应用程序之间进行通信的方法。
SOAP 消息是一个普通的 XML 文档,包含以下元素:
上述所有元素均在 SOAP 信封的默认命名空间中声明:
http://www.w3.org/2003/05/soap-envelope/
SOAP 编码和数据类型的默认命名空间是:
http://www.w3.org/2003/05/soap-encoding
以下是一些重要的语法规则:
<?xml version="1.0"?>
<soap:Envelope
xmlns:soap="http://www.w3.org/2003/05/soap-envelope/"
soap:encodingStyle="http://www.w3.org/2003/05/soap-encoding">
<soap:Header>
...
</soap:Header>
<soap:Body>
...
<soap:Fault>
...
</soap:Fault>
</soap:Body>
</soap:Envelope>
所需的 SOAP Envelope 元素是 SOAP 消息的根元素。该元素将 XML 文档定义为 SOAP 消息。
<?xml version="1.0"?>
<soap:Envelope
xmlns:soap="http://www.w3.org/2003/05/soap-envelope/"
soap:encodingStyle="http://www.w3.org/2003/05/soap-encoding">
...
Message information goes here
...
</soap:Envelope>
请注意上面示例中的 xmlns:soap 命名空间。它的值应始终为:"http://www.w3.org/2003/05/soap-envelope/"。
命名空间将信封定义为 SOAP 信封。
如果使用不同的命名空间,应用程序会生成错误并丢弃该消息。
encodingStyle 属性用于定义文档中使用的数据类型。该属性可以出现在任何 SOAP 元素上,并应用于该元素的内容和所有子元素。
SOAP 消息没有默认编码。
soap:encodingStyle="
URI"
<?xml version="1.0"?>
<soap:Envelope
xmlns:soap="http://www.w3.org/2003/05/soap-envelope/"
soap:encodingStyle="http://www.w3.org/2003/05/soap-encoding">
...
Message information goes here
...
</soap:Envelope>
可选的 SOAP 标头元素包含有关 SOAP 消息的特定于应用程序的信息(如身份验证、支付等)。
如果 Header 元素存在,则它必须是 Envelope 元素的第一个子元素。
笔记:Header 元素的所有直接子元素都必须是命名空间限定的。
<?xml version="1.0"?>
<soap:Envelope
xmlns:soap="http://www.w3.org/2003/05/soap-envelope/"
soap:encodingStyle="http://www.w3.org/2003/05/soap-encoding">
<soap:Header>
<m:Trans xmlns:m="https://www.91xjr.com/transaction/"
soap:mustUnderstand="1">234
</m:Trans>
</soap:Header>
...
...
</soap:Envelope>
上面的示例包含带有 "Trans" 元素的标头、值为 1 的 "mustUnderstand" 属性和值为 234。
SOAP 在默认名称空间中定义了三个属性。这些属性是:mustUnderstand、actor 和encodingStyle。
SOAP 标头中定义的属性定义接收者应如何处理 SOAP 消息。
SOAP MustUnderstand 属性可用于指示接收者处理的标头条目是强制的还是可选的。
如果将 MustUnderstand="1" 添加到 Header 元素的子元素,则表明处理 Header 的接收者必须识别该元素。如果接收方无法识别该元素,则在处理标头时将会失败。
soap:mustUnderstand="0|1"
<?xml version="1.0"?>
<soap:Envelope
xmlns:soap="http://www.w3.org/2003/05/soap-envelope/"
soap:encodingStyle="http://www.w3.org/2003/05/soap-encoding">
<soap:Header>
<m:Trans xmlns:m="https://www.91xjr.com/transaction/"
soap:mustUnderstand="1">234
</m:Trans>
</soap:Header>
...
...
</soap:Envelope>
SOAP 消息可以通过沿消息路径传递不同的端点从发送方传输到接收方。然而,并非 SOAP 消息的所有部分都适用于最终端点,相反,它可能适用于消息路径上的一个或多个端点。
SOAP actor 属性用于将 Header 元素寻址到特定端点。
soap:actor="
URI"
<?xml version="1.0"?>
<soap:Envelope
xmlns:soap="http://www.w3.org/2003/05/soap-envelope/"
soap:encodingStyle="http://www.w3.org/2003/05/soap-encoding">
<soap:Header>
<m:Trans xmlns:m="https://www.91xjr.com/transaction/"
soap:actor="https://www.91xjr.com/code/">234
</m:Trans>
</soap:Header>
...
...
</soap:Envelope>
encodingStyle 属性用于定义文档中使用的数据类型。该属性可以出现在任何 SOAP 元素上,并将应用于该元素的内容和所有子元素。
SOAP 消息没有默认编码。
soap:encodingStyle="
URI"
所需的 SOAP Body 元素包含用于消息最终端点的实际 SOAP 消息。
SOAP Body 元素的直接子元素可以是命名空间限定的。
<?xml version="1.0"?>
<soap:Envelope
xmlns:soap="http://www.w3.org/2003/05/soap-envelope/"
soap:encodingStyle="http://www.w3.org/2003/05/soap-encoding">
<soap:Body>
<m:GetPrice xmlns:m="https://www.91xjr.com/prices">
<m:Item>Apples</m:Item>
</m:GetPrice>
</soap:Body>
</soap:Envelope>
上面的示例请求苹果的价格。请注意,上面的 m:GetPrice 和 Item 元素是特定于应用程序的元素。它们不是 SOAP 名称空间的一部分。
SOAP 响应可能如下所示:
<?xml version="1.0"?>
<soap:Envelope
xmlns:soap="http://www.w3.org/2003/05/soap-envelope/"
soap:encodingStyle="http://www.w3.org/2003/05/soap-encoding">
<soap:Body>
<m:GetPriceResponse xmlns:m="https://www.91xjr.com/prices">
<m:Price>1.90</m:Price>
</m:GetPriceResponse>
</soap:Body>
</soap:Envelope>
可选的 SOAP 错误元素用于指示错误消息。
SOAP Fault 元素保存 SOAP 消息的错误和状态信息。
如果存在Fault 元素,则它必须显示为Body 元素的子元素。故障元素只能在 SOAP 消息中出现一次。
SOAP 错误元素具有以下子元素:
Sub Element | Description |
---|---|
<faultcode> | A code for identifying the fault |
<faultstring> | A human readable explanation of the fault |
<faultactor> | Information about who caused the fault to happen |
<detail> | Holds application specific error information related to the Body element |
描述故障时,必须在故障代码元素中使用下面定义的故障代码值:
Error | Description |
---|---|
VersionMismatch | Found an invalid namespace for the SOAP Envelope element |
MustUnderstand | An immediate child element of the Header element, with the mustUnderstand attribute set to "1", was not understood |
Client | The message was incorrectly formed or contained incorrect information |
Server | There was a problem with the server so the message could not proceed |
HTTP 通过 TCP/IP 进行通信。 HTTP 客户端使用 TCP 连接到 HTTP 服务器。建立连接后,客户端可以向服务器发送HTTP请求消息:
POST /item HTTP/1.1
Host: 189.123.255.239
Content-Type: text/plain
Content-Length: 200
然后服务器处理该请求并将 HTTP 响应发送回客户端。响应包含指示请求状态的状态代码:
200 OK
Content-Type: text/plain
Content-Length: 200
在上面的示例中,服务器返回状态代码 200。这是 HTTP 的标准成功代码。
如果服务器无法解码请求,它可能会返回如下内容:
400 Bad Request
Content-Length: 0
SOAP 规范定义了 SOAP 消息的结构,而不是它们的交换方式。这个空白由所谓的"SOAP Bindings" 来填补。 SOAP 绑定是允许使用传输协议有效交换 SOAP 消息的机制。
大多数 SOAP 实现都提供常见传输协议(例如 HTTP 或 SMTP)的绑定。
HTTP 是同步的并且被广泛使用。 SOAP HTTP 请求至少指定两个 HTTP 标头:Content-Type 和 Content-Length。
SMTP 是异步的,仅在最后手段或特殊情况下使用。
SOAP 的 Java 实现通常为 JMS(Java 消息系统)协议提供特定的绑定。
SOAP 请求和响应的 Content-Type 标头定义消息的 MIME 类型以及用于请求或响应的 XML 正文的字符编码(可选)。
Content-Type: MIMEType; charset=character-encoding
POST /item HTTP/1.1
Content-Type: application/soap+xml; charset=utf-8
SOAP 请求和响应的 Content-Length 标头指定请求或响应正文中的字节数。
Content-Length: bytes
POST /item HTTP/1.1
Content-Type: application/soap+xml; charset=utf-8
Content-Length: 250
在下面的示例中,GetStockPrice 请求被发送到服务器。该请求具有一个 StockName 参数和一个将在响应中返回的 Price 参数。该函数的命名空间在"http://www.example.org/stock" 中定义。
POST /InStock HTTP/1.1
Host: www.example.org
Content-Type: application/soap+xml; charset=utf-8
Content-Length: nnn
<?xml version="1.0"?>
<soap:Envelope
xmlns:soap="http://www.w3.org/2003/05/soap-envelope/"
soap:encodingStyle="http://www.w3.org/2003/05/soap-encoding">
<soap:Body xmlns:m="http://www.example.org/stock">
<m:GetStockPrice>
<m:StockName>IBM</m:StockName>
</m:GetStockPrice>
</soap:Body>
</soap:Envelope>
HTTP/1.1 200 OK
Content-Type: application/soap+xml; charset=utf-8
Content-Length: nnn
<?xml version="1.0"?>
<soap:Envelope
xmlns:soap="http://www.w3.org/2003/05/soap-envelope/"
soap:encodingStyle="http://www.w3.org/2003/05/soap-encoding">
<soap:Body xmlns:m="http://www.example.org/stock">
<m:GetStockPriceResponse>
<m:Price>34.5</m:Price>
</m:GetStockPriceResponse>
</soap:Body>
</soap:Envelope>