對於應用程序開發來講,使程序之間進行因特網通訊是很重要的。目前的應用程序經過使用遠程過程調用(RPC)在諸如 DCOM 與 CORBA 等對象之間進行通訊,可是 HTTP 不是爲此設計的。RPC 會產生兼容性以及安全問題;防火牆和代理服務器一般會阻止此類流量。經過 HTTP 在應用程序間通訊是更好的方法,由於 HTTP 獲得了全部的因特網瀏覽器及服務器的支持。SOAP 就是被創造出來完成這個任務的。SOAP 提供了一種標準的方法,使得運行在不一樣的操做系統並使用不一樣的技術和編程語言的應用程序能夠互相進行通訊。web
SOAP 是基於 XML 的簡易協議,是用在分散或分佈的環境中交換信息的簡單的協議,可以使應用程序在 HTTP 之上進行信息交換。或者更簡單地說:SOAP 是用於訪問網絡服務的協議。包括三個部分:封裝定義了一個描述消息中包含什麼內容以及如何處理它們的框架,編碼規則用於表示應用程序定義的數據類型的實例,另外還有一個表示遠程過程調用和應答的協定。SOAP被設計爲能夠與各類其它協議結合使用;這裏僅描述如何將SOAP和HTTP及HTTP擴展框架相結合。 編程
SOAP以XML形式提供了一個簡單、輕量的用於在分散或分佈環境中交換結構化和類型化信息的機制。SOAP自己並無定義任何應用程序語義,如編程模型或特定語義的實現;實際上它經過提供一個有標準組件的包模型和在模塊中編碼數據的機制,定義了一個簡單的表示應用程序語義的機制。這使SOAP可以被用於從消息傳遞到RPC的各類系統。 目前最新版本的SOAP1.2是Sun Microsystems、IBM、BEA、Microsoft和Oracle等供應商領導的W3C XML工做組推出並維護的。瀏覽器
SOAP的兩個目標是簡單性和可擴展性,這就意味着有一些傳統的消息系統或分佈式對象系統中的某些性質將不是SOAP規範的一部分。SOAP是一種分佈式計算中的技術,它被有意的設計爲輕量級的協議,它的某些功能和其餘一些機制(如RMI)共有的,但也存在許多不一樣的功能,如不支持經過引用傳遞對象、對象激活、消息批處理等。SOAP也被設計成可擴展的,而簡單性和可擴展性意味着SOAP的使用不包含任何特定的編程模式,給定實現的語義是極爲靈活的。安全
SOAP基於XML語言和XSD標準,其定義了一套編碼規則,該規則定義如何將數據表示爲消息,以及怎樣經過HTTP協議來傳輸SOAP消息,它由如下四部分組成:服務器
> SOAP信封(Envelope):定義了一個框架,該框架描述了消息中的內容是什麼,包括消息的內容、發送者、接收者、處理者以及如何處理這些消息。網絡
> SOAP編碼規則:它定義了一種系列化機制,用於交換應用程序所定義的數據類型的實例。app
> SOAP RPC表示:它定義了用於表示遠程過程調用和應答協定。框架
> SOAP綁定:它定義了一種使用底層傳輸協議來完成在節點間交換SOAP信封的約定。異步
SOAP消息基本上是從發送端到接收端的單向傳輸,它們經常結合起來執行相似於請求/應答的模式。不須要吧SOAP消息綁定到特定的協議,SOAP能夠運行在任何其餘傳輸協議(HTTP、SMTP、FTP等)上。另外,SOAP提供了標準的RPC方法來調用Web Service以請求/響應模式運行。編程語言
注意:
實際上,SOAP在這裏有點用詞不當:它意味着下面的Web service是以對象的方式表示的,但事實並不必定如此:你徹底能夠把你的Web service寫成一系列的C函數,並仍然使用SOAP進行調用
SOAP結點表示SOAP消息路徑的邏輯實體,用於進行消息路由或處理。SOAP結點能夠是SOAP消息的發送者、接收方、消息中介。
在SOAP消息模型中,中間方爲一種SOAP結點,負責提供發送消息的應用程序和接收方間的消息交換和協議路由功能。中間方結點駐留在發送結點和接收結點之間,負責處理SOAP消息頭中定義的部分消息。SOAP發送方和接收方之間能夠有0個或多個SOAP中間方,它爲SOAP接收方提供分佈式處理機制。
通常,SOAP消息中間方分爲兩種:
1. 轉發中間方:這一類型的中間方經過在所轉發消息的SOAP消息頭塊中描述和構造語義和規則,從而實現消息處理。
2. 活動中間方:這一類型的中間方利用一組功能爲接收方結點修改外部綁定消息,從而提供更多的消息處理操做。
在SOAP消息交換路徑中,藉助於SOAP中間方,使得分佈式處理模型在SOAP消息交換中得以實現。經過使用SOAP中間方,能夠向SOAP應用程序中集成各類功能(如轉發、過濾、事務、安全、日誌記錄、智能路由等)。
不使用消息提供者的應用程序只能交換同步消息。也就是說,扮演客戶端角色的應用程序只能發送請求-響應消息。這種類型的客戶端採用SAAJ API的SOAPConnection方法。下圖演示了在沒有消息提供者的狀況下,同步消息如何在發送者和接收者之間交換。
圖1 不使用消息提供者的SOAP消息
不使用消息提供者的客戶端具備如下優勢:
> 能夠採用J2SE平臺編寫應用程序。
> 不須要在servlet或J2EE容器中部署應用程序。
> 不須要配置消息提供者。
不使用消息提供者的客戶端具備如下侷限性:
> 客戶端只能發送請求-響應消息
> 客戶端只能扮演客戶端角色
若是想要得到而且保存在任什麼時候間發送給你的請求,你必須使用消息提供者。使用消息提供者的客戶端還能發送異步消息JAXM API提供了使用消息提供者發送和接收消息的框架。你須要在容器中運行客戶端,容器提供了消息基礎結構讓提供者使用。下圖演示了在使用消息提供者的狀況下,異步消息如何在發送者和接收者之間交換。
圖2使用消息提供者的SOAP消息
使用消息提供者的客戶端具備如下優勢:
> 客戶端可以扮演客戶端或者服務角色
> 客戶端可以切換消息傳遞給提供者
> 在客戶端傳遞消息到最終接收者以前,它可以發送消息到一個或多個目的地。這些中間的消息接收者被稱爲actor,它們在消息的SOAPHeader對象中被指定。
> 客戶端可以利用任何提供者支持的SOAP消息協議和影響消息類型與可靠性的‘服務質量’,以及消息傳遞服務的質量。
注意
Sun Java System Application Server包含了一個示例JAXM提供者,它演示瞭如何使用提供者爲發送客戶端激活「發後不理(fire and forget)」消息。請察看示例文檔獲取關於如何激活、部署和使用它的全面信息。示例應用程序能夠從如下位置獲得:
install_dir/samples/webservices/jaxm/jaxm-provider/
Sun Java System Application Server的將來版本將會包括支持可靠SOAP消息和ebXML消息的JAXM提供者。
全部的SOAP消息都使用XML編碼,一條SOAP消息就是一個普通的XML文檔,該文檔包括下列元素。
> Envelope(信封)元素,必選,可把此XML文檔標識爲一條SOAP消息。
> Header(報頭)元素,可選,包含頭部信息(包含了使消息在到達最終目的地以前,可以被路由到一個或多箇中間節點的信息)。
> Body(主體)元素,必選,包含全部的調用和響應信息。
> Fault元素,位於Body內,可選,提供有關處理此消息所發生錯誤的信息。
> Attachment(附件)元素,可選,可經過添加一個或多個附件擴展SOAP消息。
圖3 SOAP消息的結構和組成部分
SOAPMessage對象包括:
一個SOAPPart對象,其中包括
一個SOAPEnvelope對象,其中包括
一個空的SOAPHeader對象 – 可選,包括它是爲了方便,由於大多數消息都要用到它, SOAP頭提供了向SOAP消息中添加關於這條SOAP消息的某些要素(feature)的機制。SOAP定義了少許的屬性用來代表這項要素(feature)是否可選以及由誰來處理。
一個空的SOAPBody對象 -包含消息的最終接收者想要的信息的容器,能夠容納消息的內容,還能容納包含了狀態信息或者消息故障明細的錯誤消息。
AttachmentPart可能容納普通文本或者圖像文件。
SOAPEnvelope是表明消息的XML文件的根元素。它爲消息如何處理、由誰處理定義了框架。XML內容從SOAPEnvelope開始。
SOAPHeader是添加特性到SOAP消息的基本機制。它能夠容納任意數目的擴展了基礎協議的子元素。例如,header子元素可能會定義認證信息、事務信息、本地信息、等等。處理消息的軟件能夠在沒有事先約定的狀況下,使用這個機制定義誰應該處理某個特性,以及該特性是強制的仍是可選的。
SOAPBody是發給消息最終接收者的強制信息的容器。SOAP消息還能夠容納一個附件,它不必定非得是XML文件。
先來看一個簡單的例子:
在這個例子中,GetLastTradePrice SOAP 請求被髮往 StockQuote服務。這個請求攜帶一個字符串參數ticker符號,在SOAP應答中返回一個浮點數。XML名域用來區分SOAP標誌符和應用程序特定的標誌符。這個例子說明了在第6節中定義的HTTP綁定。若是SOAP中管理XML負載的規則徹底獨立於HTTP是沒有意義的,由於事實上該負載是由HTTP攜帶的。
例1 在HTTP請求中嵌入SOAP消息
POST /StockQuote HTTP/1.1
Host:
www.stockquoteserver.com
Content-Type: text/xml;
charset="utf-8"
Content-Length: nnnn
SOAPAction:
"Some-URI"
<SOAP-ENV:Envelope
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<SOAP-ENV:Body>
<m:GetLastTradePrice xmlns:m="Some-URI">
<symbol>DIS</symbol>
</m:GetLastTradePrice>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
下面是一條應答消息,包括HTTP消息,SOAP消息是其具體內容:
例2 在HTTP應答中嵌入SOAP消息
HTTP/1.1 200 OK
Content-Type: text/xml;
charset="utf-8"
Content-Length:
nnnn
<SOAP-ENV:Envelope
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
<SOAP-ENV:Body>
<m:GetLastTradePriceResponse xmlns:m="Some-URI">
<Price>34.5</Price>
</m:GetLastTradePriceResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
SOAP雖然是XML文檔,但其編寫須要知足以下語法規則:
> SOAP消息必須用XML來編碼。
> SOAP消息必須用SOAP Envelope命名空間。
> SOAP消息必須用SOAP Encoding命名空間。
> SOAP消息不能包含DTD引用。
> SOAP消息不能包含XML處理指令。
SOAP Envelope 是SOAP消息結構的主要容器,也是SOAP消息的根元素,它必須出如今每一個SOAP消息中,用於把此XML文檔標示爲一條SOAP消息。
在SOAP中,使用XML命名空間將SOAP標示符與應用程序特定的標示符區分開,將SOAP消息的元素的做用域限制在一個特定的領域。
<soap-env:Envelope xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/"
Soap-env:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
</ soap-env:Envelope >
以上命名空間都是按照SOAP1.1規範書寫,SOAP消息中全部元素必須由第一個命名空間進行限定,SOAP的encodingStyle屬性用於定義在文檔中使用的數據類型。此屬性可出如今任何SOAP元素中,並會被應用到元素的內容及元素的全部子元素上。
對於SOAP1.2規範,對應的命名空間及空信封以下:
<soap:Envelope xmlns:soap="http://www.w3.org/2001/12/soap-envelope"
soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding」>
</ soap:Envelope >
SOAP Header元素應看成爲SOAPEnvelope的第一個直接子元素,它必須使用有效的命名空間。Header還能夠包含0個或多個可選的子元素,這些子元素稱爲Header項,全部的Header項都必須是完整修飾的,即必須由一個命名空間URI和局部名組成,不容許沒有命名空間修飾的Header項存在。
Header元素用於與消息一塊兒傳輸附加消息,如身份驗證或事務信息。Header元素也能夠包含某些屬性。SOAP在默認的命名空間中定義了三個屬性:actor,mustUnderstand以及encodingStyle。這些被定義在SOAP頭部的屬性可通知容器如何對SOAP消息進行處理。
<soap-env:Envelope xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/"
Soap-env:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<soap-env:Header>
<auth:UserID xmlns:auth=」some-URI」>
Admin
</auth:UserID>
</soap-env:Header>
</ soap-env:Envelope >
定義了新命名空間的附加元素,元素名(UserID)代表它包含身份驗證信息。
SOAP消息的Body塊能夠包含如下任何元素:
> RPC方法及其參數
> 目標應用程序(消息接收者)專用數據
> 報告故障和狀態消息的SOAP Fault
全部Body元素的直接子元素都稱爲Body項,Body項必須由命名空間修飾。
以下,該主體表示用於從「www.fruit.com」獲取Apples的價格信息的RPC調用。
<soap-env:Envelope xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/"
Soap-env:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<soap-env:Body>
<m:GetPrice xmlns:m=」http://www.fruit.com/prices」>
<m:Item>Apples</m:Item>
</ m:GetPrice >
</soap-env:Body>
</ soap-env:Envelope >
命名空間http://www.fruit.com/prices是應用程序專用的元素,它們並非SOAP標準的一部分。下面是對上述請求的響應:
<soap-env:Envelope xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/"
Soap-env:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<soap-env:Body>
<m:GetPriceResponse xmlns:m=」http://www.fruit.com/prices」>
<m:Price>3.2</m:Price>
</ m:GetPriceResponse >
</soap-env:Body>
</ soap-env:Envelope >
子元素 |
描述 |
<faultcode> |
供識別故障的代碼 |
<faultstring> |
可供人閱讀的有關故障的說明 |
<faultactor> |
有關是誰引起故障的信息 |
<detail> |
存留涉及 Body 元素的應用程序專用錯誤信息 |
SOAP Fault元素用於在SOAP消息中傳輸錯誤及狀態信息。若是SOAP消息須要包括SOAP Fault元素,它必須做爲一個Body項出現,並且至多出現一次。SOAP Fault包括如下子元素:faultcode,faultstring,faultactor,detail.
在下面定義的 faultcode 值必須用於描述錯誤時的 faultcode 元素中
錯誤 |
描述 |
VersionMismatch |
SOAP Envelope 元素的無效命名空間被發現 |
MustUnderstand |
Header 元素的一個直接子元素 (帶有設置爲 "1" 的 mustUnderstand 屬性)沒法被理解。 |
Client |
消息被不正確地構成,或包含了不正確的信息。 |
Server |
服務器有問題,所以沒法處理進行下去。 |
按照SOAP1.1規範的規定,SOAP消息能夠包含XML格式的主SOAP信封,以及包含ASCII或二進制等任何數據格式的SOAP附件。若是SOAP消息包含附件,那麼SOAP消息將是一個MIME編碼的消息,它包含SOAP內容和一個或多個其餘類型的附件。所以SOAP消息實際上分爲如下兩種類型:
> 僅包含XML內容的消息
> MIME編碼的消息,包含初始的XML有效內容以及任何數量的附件。這些附件能夠是任何其餘類型的數據。
【MIME:Multi-purpose Internet Mail Extensions多用途Internet郵件擴展,是一組技術規範,其目的是使用不一樣字符集來傳遞文本,也能夠在計算機之間傳遞各類各樣的多媒體數據】
HTTP 在 TCP/IP 之上進行通訊。HTTP 客戶機使用 TCP 鏈接到 HTTP 服務器。在創建鏈接以後,客戶機可向服務器發送 HTTP 請求消息:
POST /item HTTP/1.1
Host: 189.123.145.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 編碼規則的 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