XML 肥皂
- SOAP 代表 **S**imple **O**bject **A**ccess **P**rotocol
- SOAP 是一个应用通信协议
- SOAP 是发送和接收消息的格式
- SOAP 是平台无关的
- SOAP 基于 XML
- SOAP 是 W3C 推荐
为什么使用 SOAP?
对于 Web 应用来说,能够通过互联网进行通信非常重要。
应用之间最好的通信方式是通过 HTTP,因为 HTTP 被所有互联网浏览器和服务器支持。SOAP 的创建就是为了实现这一点。
SOAP 提供了一种在不同操作系统、不同技术和不同编程语言上运行的应用之间进行通信的方式。
SOAP 构建块
SOAP 消息是一个普通的 XML 文档,包含以下元素
- 一个 Envelope 元素,标识 XML 文档为 SOAP 消息
- 一个 Header 元素,包含头信息
- 一个 Body 元素,包含调用和响应信息
- 一个 Fault 元素,包含错误和状态信息
以上所有元素都在 SOAP 信封的默认命名空间中声明
http://www.w3.org/2003/05/soap-envelope
SOAP 编码和数据类型的默认命名空间是
http://www.w3.org/2003/05/soap-encoding
语法规则
以下是一些重要的语法规则
- SOAP 消息必须使用 XML 进行编码
- SOAP 消息必须使用 SOAP 信封命名空间
- SOAP 消息不能包含 DTD 引用
- 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">
<soap:Header>
...
</soap:Header>
<soap:Body>
...
<soap:Fault>
...
</soap:Fault>
</soap:Body>
</soap:Envelope>
SOAP 信封元素
必需的 SOAP 信封元素是 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">
...
消息信息在此处
...
</soap:Envelope>
xmlns:soap 命名空间
请注意上面示例中的 xmlns:soap 命名空间。它始终应具有以下值:“http://www.w3.org/2003/05/soap-envelope”。
命名空间将 Envelope 定义为 SOAP 信封。
如果使用不同的命名空间,应用程序会生成错误并丢弃消息。
encodingStyle 属性
encodingStyle 属性用于定义文档中使用的 datatypes。此属性可以出现在任何 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">
...
消息信息在此处
...
</soap:Envelope>
SOAP Header 元素
可选的 SOAP Header 元素包含关于 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://w3schools.org.cn/transaction/"
soap:mustUnderstand="1">234
</m:Trans>
</soap:Header>
...
...
</soap:Envelope>
上面的示例包含一个带有“Trans”元素的 header、一个值为 1 的“mustUnderstand”属性和一个值为 234 的值。
SOAP 在默认命名空间中定义了三个属性。这些属性是:mustUnderstand、actor 和 encodingStyle。
SOAP Header 中定义的属性定义了接收方如何处理 SOAP 消息。
mustUnderstand 属性
SOAP mustUnderstand 属性可用于指示接收方处理 header 条目是必须的还是可选的。
如果在 Header 元素的子元素中添加 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://w3schools.org.cn/transaction/"
soap:mustUnderstand="1">234
</m:Trans>
</soap:Header>
...
...
</soap:Envelope>
actor 属性
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://w3schools.org.cn/transaction/"
soap:actor="https://w3schools.org.cn/code/">234
</m:Trans>
</soap:Header>
...
...
</soap:Envelope>
encodingStyle 属性
encodingStyle 属性用于定义文档中使用的 datatypes。此属性可以出现在任何 SOAP 元素上,并将应用于该元素的内容和所有子元素。
SOAP 消息没有默认编码。
语法
soap:encodingStyle="URI"
SOAP Body 元素
必需的 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://w3schools.org.cn/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://w3schools.org.cn/prices">
<m:Price>1.90</m:Price>
</m:GetPriceResponse>
</soap:Body>
</soap:Envelope>
SOAP 错误元素
可选的 SOAP 错误元素用于指示错误消息。
SOAP 错误元素包含 SOAP 消息的错误和状态信息。
如果存在错误元素,它必须作为 Body 元素的子元素出现。SOAP 消息中只能出现一次错误元素。
SOAP 错误元素具有以下子元素:
子元素 | 描述 |
---|---|
<faultcode> | 用于识别错误的代码 |
<faultstring> | 对错误的人类可读解释 |
<faultactor> | 有关谁导致错误发生的信息 |
<detail> |
包含与 Body 元素相关的应用程序特定错误信息 |
SOAP 错误代码
描述错误时,必须在 faultcode 元素中使用以下定义的 faultcode 值。
错误 | 描述 |
---|---|
VersionMismatch | 在 SOAP Envelope 元素中找到无效的命名空间 |
MustUnderstand | Header 元素的直接子元素,其中 mustUnderstand 属性设置为“1”,没有被理解 |
Client | 消息格式错误或包含错误信息 |
Server | 服务器存在问题,因此消息无法继续处理 |
HTTP 协议
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 消息的结构,而不是它们如何交换。这个差距由所谓的“SOAP 绑定”来填补。SOAP 绑定是允许 SOAP 消息使用传输协议有效交换的机制。
大多数 SOAP 实现都为常见的传输协议提供绑定,例如 HTTP 或 SMTP。
HTTP 是同步的,并且被广泛使用。SOAP HTTP 请求至少指定两个 HTTP 标头:Content-Type 和 Content-Length。
SMTP 是异步的,并且在最后手段或特定情况下使用。
SOAP 的 Java 实现通常为 JMS(Java 消息系统)协议提供特定的绑定。
Content-Type
SOAP 请求和响应的 Content-Type 标头定义了消息的 MIME 类型以及请求或响应的 XML 主体的字符编码(可选)。
语法
Content-Type: MIMEType; charset=character-encoding
示例
POST /item HTTP/1.1
Content-Type: application/soap+xml; charset=utf-8
Content-Length
SOAP 请求和响应的 Content-Length 标头指定了请求或响应主体的字节数。
语法
Content-Length: bytes
示例
POST /item HTTP/1.1
Content-Type: application/soap+xml; charset=utf-8
Content-Length: 250
SOAP 示例
在以下示例中,GetStockPrice 请求被发送到服务器。请求包含一个 StockName 参数,以及一个 Price 参数,该参数将在响应中返回。函数的命名空间定义在“http://www.example.org/stock”中。
SOAP 请求
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>
SOAP 响应
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>