當今最為常見的兩種 Web 服務型別分別是: REST 和 SOAP 。不過,從趨勢來看,越來越多人已經開始使用 REST 風格的 Web 服務。而 SOAP 大多也開始或已經轉型 REST,應該說 REST 會慢慢成為主流。這篇文章不會對 REST 介紹太多,主要的重點還是介紹一下 SOAP 風格的 Web 服務。
Web Service 三要素
實際上,現在說 “Web Service 三要素”應該是不算很準確了,不過這個概念一直這樣沿用,而且本文我們為了更能清楚闡釋 SOAP Web 服務,那麼就這樣定義。
Web Service 的三個要素分別是:
SOAP(Simple Object Access Protoco) 簡單物件訪問協議;
WSDL(Web Services Description Language) 網路服務描述語言;
UDDI(Universal Description Discovery and Integration)一個用來發布和搜尋 WEB 服務的協議(非必須);
SOAP 用來描述傳遞資訊的格式規範, WSDL 用來描述如何訪問具體的介面(比如它會告訴你該服務有哪些介面可以使用,引數是什麼等等), UDDI 用來管理、分發和查詢 Web Service。下面我們將逐一詳細介紹這三個要素,並通過結合例項來進行闡釋。
為了把這三個要素說得更清楚,我們將會使用一個免費的 SOAP Web 服務作為例子進行闡述。該服務只提供一個介面即:根據 QQ 號,獲取 QQ 線上狀態。檢視該服務
SOAP
它是一個協議,可以簡單的理解為:它定義了一個基於 XML 的可擴充套件訊息信封格式。因為客戶端與伺服器進行互動,由於大家的平臺和應用程式都不一樣,所以大家約定都採用 SOAP 這個協議來規範互動時的需要傳遞的訊息。
請求介面時,傳送的訊息例子:
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="">
<soap:Body>
<qqCheckOnline xmlns="">
<qqCode>8698053</qqCode>
</qqCheckOnline>
</soap:Body>
</soap:Envelope>
介面響應時,返回的訊息例子:
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="">
<soap:Body>
<qqCheckOnlineResponse xmlns="">
<qqCheckOnlineResult>Y</qqCheckOnlineResult>
</qqCheckOnlineResponse>
</soap:Body>
</soap:Envelope>
注:以上例子是使用 SOAP 1.1 傳送的訊息,SOAP 1.2 傳送的訊息格式其實大同小異,具體自己檢視介面文件。
下面對它結構進行詳細說明。
XML 宣告
<?xml version="1.0" encoding="utf-8"?>
該行是 XML 宣告。它定義 XML 的版本 (1.0) 和所使用的編碼(utf-8)。
Envelope 元素
<soap:Envelope
xmlns:soap=""
xmlns:xsi=""
xmlns:xsd="">
....
</soap:Envelope>
Envelope 元素是 SOAP 訊息的固定根元素,SOAP 協議規定的,不能變,其中 xmlns 是 XML Namespace 的縮寫,表示 XML 名稱空間。xmlns:soap="" 是 Envelope的一個屬性,它表示定義個以soap 為字首的名稱空間 ,即名稱空間的名字是:,而它的`字首是 soap,這樣子就把 soap 字首與該名稱空間進行了繫結。即任何用 soap 為字首的元素都屬於該名稱空間的,包括根元素 Envelope 。舉個例子:
<soap:Envelope xmlns:soap="">
<soap:Body>
<qqCheckOnline xmlns="">
<qqCode>8698053</qqCode>
</qqCheckOnline>
</soap:Body>
</soap:Envelope>
其中,Envelope 和 Body 元素就是以 soap 為字首的,那麼 Envelope 和 Body 元素都是屬於 這個名稱空間的。
同時,SOAP 協議中規定,SOAP 訊息必須使用 SOAP Envelope 名稱空間,所以 這個名稱空間是固定的不能變(注意:這裡只針對 SOAP 1.1 版本,SOAP 1.2 會有所不同)。所有 SOAP 訊息元素,比如:Envelope、Header、Body、Fault 也都必須屬於該名稱空間。
Body 元素
<soap:Body>
<qqCheckOnline xmlns="">
<qqCode>8698053</qqCode>
</qqCheckOnline>
</soap:Body>
Body 元素裡面,一般都是放一些請求和響應的內容。qqCheckOnline 表示要呼叫的介面方法,而 qqCode 就是呼叫該方法時,傳入的引數,當然引數可以有多個。
其中,qqCheckOnline 元素上也定義了一個名稱空間 。值得注意的是,這裡在定義名稱空間時,並沒有設定名稱空間字首(namespace prefix)。這種設定方式,會把當前元素及其所有子元素,都歸屬於該名稱空間。瞭解 XML 名稱空間。
我們看到,SOAP 訊息元素和應用程式本身的元素是屬於不同的名稱空間,這樣有利於把 SOAP 訊息元素與其他元素區分開來,當然也防止了與自定義元素重名的問題。
Header 元素
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="">
<soap:Header>
<AuthenHeader xmlns="">
<sAuthenticate>string</sAuthenticate>
</AuthenHeader>
</soap:Header>
<soap:Body>
......
</soap:Body>
</soap:Envelope>
有些介面需要提供 Header 元素,它和 Body 資訊一起傳送,它一般用於身份驗證等作用。例子中的 AuthenHeader 和sAuthenticate 都是介面自定義的引數。
Fault 元素
當呼叫服務發生錯誤時,錯誤資訊一般會被放置在 Fault 元素內。例如:
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="">
<soap:Body>
<soap:Fault>
<faultcode>soap:Client</faultcode>
<faultstring>Input string was not in a correct format.</faultstring>
<detail/>
</soap:Fault>
</soap:Body>
</soap:Envelope>
Fault 元素內還有 faultcode、faultstring、detail,用於描述錯誤資訊用的。在上一篇文章:《SOAP 介紹》中已經對該知識點進行了比較詳細的說明,有興趣可以看看。
WSDL
一個 XML 格式的文件。它用於描述該服務有哪些可用方法、引數的資料型別、名稱空間等等資訊。它的目的是讓你知道該如何使用該服務,包括呼叫的各種細節資訊。WSDL 文件通常用來輔助生成伺服器和客戶端程式碼及配置資訊。
契約先行與程式碼先行模式
在開發 Web Service 過程中有兩種實現模式:契約先行(Contract first)模式和程式碼先行(Code first)模式。
契約先行模式:首要工作是定義針對這個 Web 服務的介面的 WSDL(Web Services Description Language,Web 服務描述語言 ) 檔案。WSDL 檔案中描述了 Web 服務的位置,可提供的操作集,以及其他一些屬性。WSDL 檔案也就是 Web 服務的 “契約”。“契約” 訂立之後,再據此進行伺服器端和客戶端的應用程式開發。
程式碼先行模式:與契約先行模式不同,程式碼先行模式中,第一步工作是實現 Web 服務端,然後根據服務端的實現,用某種方法(自動生成或手工編寫)生成 WSDL 檔案。
實際上,一個 WSDL 檔案也挺複雜的,一般自己也不會去直接看這個檔案,而是需要用到某個方法時,直接看該方法的呼叫說明就好。比如:獲得騰訊QQ線上狀態
UDDI
UDDI 是一個專門用來管理 Web 服務的地方。Web Service 服務提供商可以通過兩種方式來暴露它的 WSDL 檔案地址:
註冊到 UDDI 伺服器,以便被人查詢;
直接告訴給客戶端呼叫者;
是否需要註冊到 UDDI 實際上是可選的,一般公司內部使用的服務,也不會註冊到 UDDI。只有那些希望所有人都知道該服務的地址,才會註冊到 UDDI。
最後
這篇文章寫得有點亂了,主要還是自己對 SOAP 的瞭解還不夠,最起碼我並沒有真正開發過 SOAP 服務。不過沒關係吧,慢慢來,文章可以隨著知識的增長慢慢潤色。上文其實有一些問題沒有說清楚的,比如說:SOAP 服務的適合用在哪裡,不適合用在哪裡等等。如果你有興趣,可以看看文章最後的幾篇參考文獻。