簡單對象訪問協(xié)議(Simple Object Access Protocol,SOAP)是一種基于 XML 的協(xié)議,可以和現(xiàn)存的許多因特網(wǎng)協(xié)議和格式結(jié)合使用,包括超文本傳輸協(xié)議(HTTP),簡單郵件傳輸協(xié)議(SMTP),多用途網(wǎng)際郵件擴(kuò)充協(xié)議(MIME),基于“通用”傳輸協(xié)議是 SOAP的一個(gè)優(yōu)點(diǎn)。它還支持從消息系統(tǒng)到遠(yuǎn)程過程調(diào)用(Remote Procedure Call,RPC)等大量的應(yīng)用程序。SOAP提供了一系列的標(biāo)準(zhǔn),如WSRM(WS-Reliable Messaging)形式化契約確保可靠性與安全性,確保異步處理與調(diào)用;WS-Security、WS-Transactions和WS-Coordination等標(biāo)準(zhǔn)提供了上下文信息與對話狀態(tài)管理。 相對而言,SOAP協(xié)議屬于復(fù)雜的、重量級的協(xié)議,當(dāng)前隨著Web2.0的興起,表述性狀態(tài)轉(zhuǎn)移(Representational State Transfer,REST)逐步成為一個(gè)流行的架構(gòu)風(fēng)格。REST是一種輕量級的Web Service架構(gòu)風(fēng)格,其實(shí)現(xiàn)和操作比SOAP和XML-RPC更為簡潔,可以完全通過HTTP協(xié)議實(shí)現(xiàn),還可以利用緩存Cache來提高響應(yīng)速度,性能、效率和易用性上都優(yōu)于SOAP協(xié)議。REST架構(gòu)對資源的操作包括獲取、創(chuàng)建、修改和刪除資源的操作正好對應(yīng)HTTP協(xié)議提供的GET、POST、PUT和DELETE方法,這種針對網(wǎng)絡(luò)應(yīng)用的設(shè)計(jì)和開發(fā)方式,可以降低開發(fā)的復(fù)雜性,提高系統(tǒng)的可伸縮性。REST架構(gòu)尤其適用于完全無狀態(tài)的CRUD(Create、Read、Update、Delete,創(chuàng)建、讀取、更新、刪除)操作。 基于REST的軟件體系結(jié)構(gòu)風(fēng)格(Software Architecture Style)稱之為面向資源體系架構(gòu)(Resource-oriented Architecture,ROA)。按照REST原則設(shè)計(jì)的軟件、體系結(jié)構(gòu),通常被稱為“REST式的”(RESTful),在本文中以下稱之為RESTful Web服務(wù),以便于和基于SOAP的Web服務(wù)區(qū)別。 服務(wù)器端采用J2EE,客戶端采用JSP、Flex、JavaFX、AIR等可以直接調(diào)用Servlet,其他的實(shí)現(xiàn)技術(shù)基本上不能直接調(diào)用,但是無論是那種客戶端,對于基于SOAP的Web服務(wù)或者基于RESTful Web服務(wù)務(wù)都是支持的,如AJAX的 XMLHttpRequest、Flex的HTTPService等。如下圖所示: 客戶端和服務(wù)器端的通訊方式
![]() HTTP 的 GET、HEAD 請求本質(zhì)上應(yīng)該是安全的調(diào)用,即:GET、HEAD 調(diào)用不會有任何的副作用,不會造成服務(wù)器端狀態(tài)的改變。對于服務(wù)器來說,客戶端對某一 URI 做 n 次的 GET、HAED 調(diào)用,其狀態(tài)與沒有做調(diào)用是一樣的,不會發(fā)生任何的改變。 HTTP 的 PUT、DELTE 調(diào)用,具有冪指相等特性 , 即:客戶端對某一 URI 做 n 次的 PUT、DELTE 調(diào)用,其效果與做一次的調(diào)用是一樣的。HTTP 的 GET、HEAD 方法也具有冪指相等特性。 HTTP 這些標(biāo)準(zhǔn)方法在原則上保證你的分布式系統(tǒng)具有這些特性,以幫助構(gòu)建更加健壯的分布式系統(tǒng)。 為了說明問題,基于上面的在線用戶管理系統(tǒng),我們給定以下場景: 參考一開始我們給出的用例圖,對于客戶端 Client2,我們只希望它能以只讀的方式訪問 User 和 User List 資源,而 Client1 具有訪問所有資源的所有權(quán)限。 如何做這樣的安全控制? 通行的做法是:所有從客戶端 Client2 發(fā)出的 HTTP 請求都經(jīng)過代理服務(wù)器 (Proxy Server)。代理服務(wù)器制定安全策略:所有經(jīng)過該代理的訪問 User 和 User List 資源的請求只具有讀取權(quán)限,即:允許 GET/HEAD 操作,而像具有寫權(quán)限的 PUT/DELTE 是不被允許的。 如果對于 REST,我們看看這樣的安全策略是如何部署的。如下圖所示: 圖 4. REST 與代理服務(wù)器 (Proxy Servers) ![]() 一般代理服務(wù)器的實(shí)現(xiàn)根據(jù) (URI, HTTP Method) 兩元組來決定 HTTP 請求的安全合法性。 當(dāng)發(fā)現(xiàn)類似于(http://localhost:8182/v1/users/{username},DELETE)這樣的請求時(shí),予以拒絕。 對于 SOAP,如果我們想借助于既有的代理服務(wù)器進(jìn)行安全控制,會比較尷尬,如下圖: 圖 5. SOAP 與代理服務(wù)器 (Proxy Servers) ![]() 所有的 SOAP 消息經(jīng)過代理服務(wù)器,只能看到( 眾所周知,對于基于網(wǎng)絡(luò)的分布式應(yīng)用,網(wǎng)絡(luò)傳輸是一個(gè)影響應(yīng)用性能的重要因素。如何使用緩存來節(jié)省網(wǎng)絡(luò)傳輸帶來的開銷,這是每一個(gè)構(gòu)建分布式網(wǎng)絡(luò)應(yīng)用的開發(fā)人員必須考慮的問題。 HTTP 協(xié)議帶條件的 HTTP GET 請求 (Conditional GET) 被設(shè)計(jì)用來節(jié)省客戶端與服務(wù)器之間網(wǎng)絡(luò)傳輸帶來的開銷,這也給客戶端實(shí)現(xiàn) Cache 機(jī)制 ( 包括在客戶端與服務(wù)器之間的任何代理 ) 提供了可能。HTTP 協(xié)議通過 HTTP HEADER 域:If-Modified-Since/Last- Modified,If-None-Match/ETag 實(shí)現(xiàn)帶條件的 GET 請求。 REST 的應(yīng)用可以充分地挖掘 HTTP 協(xié)議對緩存支持的能力。當(dāng)客戶端第一次發(fā)送 HTTP GET 請求給服務(wù)器獲得內(nèi)容后,該內(nèi)容可能被緩存服務(wù)器 (Cache Server) 緩存。當(dāng)下一次客戶端請求同樣的資源時(shí),緩存可以直接給出響應(yīng),而不需要請求遠(yuǎn)程的服務(wù)器獲得。而這一切對客戶端來說都是透明的。 圖 6. REST 與緩存服務(wù)器 (Cache Server) ![]() 而對于 SOAP,情況又是怎樣的呢? 使用 HTTP 協(xié)議的 SOAP,由于其設(shè)計(jì)原則上并不像 REST 那樣強(qiáng)調(diào)與 Web 的工作方式相一致,所以,基于 SOAP 應(yīng)用很難充分發(fā)揮 HTTP 本身的緩存能力,圖 7. SOAP 與緩存服務(wù)器 (Cache Server) 兩個(gè)因素決定了基于 SOAP 應(yīng)用的緩存機(jī)制要遠(yuǎn)比 REST 復(fù)雜: 其一、所有經(jīng)過緩存服務(wù)器的 SOAP 消息總是 HTTP POST,緩存服務(wù)器如果不解碼 SOAP 消息體,沒法知道該 HTTP 請求是否是想從服務(wù)器獲得數(shù)據(jù)。 其二、SOAP 消息所使用的 URI 總是指向 SOAP 的服務(wù)器,如本文例子中的 在一個(gè)純的 SOAP 應(yīng)用中,URI 本質(zhì)上除了用來指示 SOAP 服務(wù)器外,本身沒有任何意義。與 REST 的不同的是,無法通過 URI 驅(qū)動(dòng) SOAP 方法調(diào)用。例如在我們的例子中,當(dāng)我們通過 getUserList SOAP 消息獲得所有的用戶列表后,仍然無法通過既有的信息得到某個(gè)具體的用戶信息。唯一的方法只有通過 WSDL 的指示,通過調(diào)用 getUserByName 獲得,getUserList 與 getUserByName 是彼此孤立的。 而對于 REST,情況是完全不同的:通過 REST 構(gòu)建的系統(tǒng)其系統(tǒng)的擴(kuò)展能力要強(qiáng)于 SOAP,這可以體現(xiàn)在它的統(tǒng)一接口抽象、代理服務(wù)器支持、緩存服務(wù)器支持等諸多方面, 而SOAP的成熟性可以給需要提供給多開發(fā)語言的,多傳輸方式的,對于安全性要求較高的接口設(shè)計(jì)帶來便利。 |
|