(轉載自http://www.w3school.com.cn/soap/soap_intro.asp)
SOAP 是基於 XML 的簡易協議,可使應用程序在 HTTP 之上進行信息交換。
或者更簡單地說:SOAP 是用於訪問網絡服務的協議
什麼是 SOAP?
- SOAP 指簡易對象訪問協議
- SOAP 是一種通信協議
- SOAP 用於應用程序之間的通信
- SOAP 是一種用於發送消息的格式
- SOAP 被設計用來通過因特網進行通信
- SOAP 獨立於平臺
- SOAP 獨立於語言
- SOAP 基於 XML
- SOAP 很簡單並可擴展
- SOAP 允許您繞過防火牆
- SOAP 將被作爲 W3C 標準來發展
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 消息必須使用 SOAP Envelope 命名空間
- SOAP 消息必須使用 SOAP Encoding 命名空間
- SOAP 消息不能包含 DTD 引用
- SOAP 消息不能包含 XML 處理指令
SOAP 消息的基本結構
<?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>
強制使用的 SOAP 的 Envelope 元素是 SOAP 消息的根元素。
SOAP Envelope 元素
必需的 SOAP 的 Envelope 元素是 SOAP 消息的根元素。它可把 XML 文檔定義爲 SOAP 消息。
請注意 xmlns:soap 命名空間的使用。它的值應當始終是:
http://www.w3.org/2001/12/soap-envelope
並且它可把封裝定義爲 SOAP 封裝:
<?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>
xmlns:soap 命名空間
SOAP 消息必須擁有與命名空間 "http://www.w3.org/2001/12/soap-envelope" 相關聯的一個 Envelope 元素。
如果使用了不同的命名空間,應用程序會發生錯誤,並拋棄此消息。
encodingStyle 屬性
SOAP 的 encodingStyle 屬性用於定義在文檔中使用的數據類型。此屬性可出現在任何 SOAP 元素中,並會被應用到元素的內容及元素的所有子元素上。SOAP 消息沒有默認的編碼方式。
語法
soap:encodingStyle="URI"
實例
<?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>
可選的 SOAP Header 元素包含頭部信息。
SOAP Header 元素
可選的 SOAP Header 元素可包含有關 SOAP 消息的應用程序專用信息(比如認證、支付等)。如果 Header 元素被提供,則它必須是 Envelope 元素的第一個子元素。
註釋:所有 Header 元素的直接子元素必須是合格的命名空間。
<?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.w3school.com.cn/transaction/" soap:mustUnderstand="1">234</m:Trans> </soap:Header> ... ... </soap:Envelope>
上面的例子包含了一個帶有一個 "Trans" 元素的頭部,它的值是 234,此元素的 "mustUnderstand" 屬性的值是 "1"。
SOAP 在默認的命名空間中 ("http://www.w3.org/2001/12/soap-envelope") 定義了三個屬性。這三個屬性是:actor、 mustUnderstand 以及 encodingStyle。這些被定義在 SOAP 頭部的屬性可定義容器如何對 SOAP 消息進行處理。
actor 屬性
通過沿着消息路徑經過不同的端點,SOAP 消息可從某個發送者傳播到某個接收者。並非 SOAP 消息的所有部分均打算傳送到 SOAP 消息的最終端點,不過,另一個方面,也許打算傳送給消息路徑上的一個或多個端點。
SOAP 的 actor 屬性可被用於將 Header 元素尋址到一個特定的端點。
語法
soap:actor="URI"
實例
<?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.w3school.com.cn/transaction/" soap:actor="http://www.w3school.com.cn/appml/"> 234 </m:Trans> </soap:Header> ... ... </soap:Envelope>
mustUnderstand 屬性
SOAP 的 mustUnderstand 屬性可用於標識標題項對於要對其進行處理的接收者來說是強制的還是可選的。
假如您向 Header 元素的某個子元素添加了 "mustUnderstand="1",則它可指示處理此頭部的接收者必須認可此元素。假如此接收者無法認可此元素,則在處理此頭部時必須失效。
語法
soap:mustUnderstand="0|1"
實例
<?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.w3school.com.cn/transaction/" soap:mustUnderstand="1"> 234 </m:Trans> </soap:Header> ... ... </soap:Envelope>
encodingStyle 屬性
SOAP 的 encodingStyle 屬性在上一節中已解釋過了。
強制使用的 SOAP Body 元素包含實際的 SOAP 消息。
SOAP Body 元素
必需的 SOAP Body 元素可包含打算傳送到消息最終端點的實際 SOAP 消息。
SOAP Body 元素的直接子元素可以是合格的命名空間。SOAP 在默認的命名空間中("http://www.w3.org/2001/12/soap-envelope")定義了 Body 元素內部的一個元素。即 SOAP 的 Fault 元素,用於指示錯誤消息。
<?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:Body> <m:GetPrice xmlns:m="http://www.w3school.com.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/2001/12/soap-envelope" soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding"> <soap:Body> <m:GetPriceResponse xmlns:m="http://www.w3school.com.cn/prices"> <m:Price>1.90</m:Price> </m:GetPriceResponse> </soap:Body> </soap:Envelope>
SOAP Fault 元素用於存留 SOAP 消息的錯誤和狀態信息。
SOAP Fault 元素
可選的 SOAP Fault 元素用於指示錯誤消息。
如果已提供了 Fault 元素,則它必須是 Body 元素的子元素。在一條 SOAP 消息中,Fault 元素只能出現一次。
SOAP 的 Fault 元素擁有下列子元素:
子元素 | 描述 |
---|---|
<faultcode> | 供識別故障的代碼 |
<faultstring> | 可供人閱讀的有關故障的說明 |
<faultactor> | 有關是誰引發故障的信息 |
<detail> | 存留涉及 Body 元素的應用程序專用錯誤信息 |
SOAP Fault 代碼
在下面定義的 faultcode 值必須用於描述錯誤時的 faultcode 元素中:
錯誤 | 描述 |
---|---|
VersionMismatch | SOAP Envelope 元素的無效命名空間被發現 |
MustUnderstand | Header 元素的一個直接子元素(帶有設置爲 "1" 的 mustUnderstand 屬性)無法被理解。 |
Client | 消息被不正確地構成,或包含了不正確的信息。 |
Server | 服務器有問題,因此無法處理進行下去。 |
HTTP 協議
HTTP 在 TCP/IP 之上進行通信。HTTP 客戶機使用 TCP 連接到 HTTP 服務器。在建立連接之後,客戶機可向服務器發送 HTTP 請求消息:
POST /item HTTP/1.1 Host: 189.123.345.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 HTTP Binding
SOAP 方法指的是遵守 SOAP 編碼規則的 HTTP 請求/響應。
HTTP + XML = SOAP
SOAP 請求可能是 HTTP POST 或 HTTP GET 請求。
HTTP POST 請求規定至少兩個 HTTP 頭:Content-Type 和 Content-Length。
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/2001/12/soap-envelope" soap:encodingStyle="http://www.w3.org/2001/12/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/2001/12/soap-envelope" soap:encodingStyle="http://www.w3.org/2001/12/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>