SOAP详解
1.?SOAP簡介
1.1應用背景
對于應用程序開發來說,使程序之間進行因特網通信是很重要的。目前的應用程序通過使用遠程過程調用(RPC)在諸如?DCOM?與?CORBA?等對象之間進行通信,但是?HTTP?不是為此設計的。RPC?會產生兼容性以及安全問題;防火墻和代理服務器通常會阻止此類流量。通過?HTTP?在應用程序間通信是更好的方法,因為?HTTP?得到了所有的因特網瀏覽器及服務器的支持。SOAP?就是被創造出來完成這個任務的。SOAP?提供了一種標準的方法,使得運行在不同的操作系統并使用不同的技術和編程語言的應用程序可以互相進行通信。
?
1.2概念定義
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編碼規則:它定義了一種系列化機制,用于交換應用程序所定義的數據類型的實例。
>?SOAP?RPC表示:它定義了用于表示遠程過程調用和應答協定。
>?SOAP綁定:它定義了一種使用底層傳輸協議來完成在節點間交換SOAP信封的約定。
SOAP消息基本上是從發送端到接收端的單向傳輸,它們常常結合起來執行類似于請求/應答的模式。不需要吧SOAP消息綁定到特定的協議,SOAP可以運行在任何其他傳輸協議(HTTP、SMTP、FTP等)上。另外,SOAP提供了標準的RPC方法來調用Web?Service以請求/響應模式運行。
?
注意:
實際上,SOAP在這里有點用詞不當:它意味著下面的Web?service是以對象的方式表示的,但事實并不一定如此:你完全可以把你的Web?service寫成一系列的C函數,并仍然使用SOAP進行調用
2.?消息交換模型
2.1SOAP接點
SOAP結點表示SOAP消息路徑的邏輯實體,用于進行消息路由或處理。SOAP結點可以是SOAP消息的發送者、接收方、消息中介。
?
在SOAP消息模型中,中間方為一種SOAP結點,負責提供發送消息的應用程序和接收方間的消息交換和協議路由功能。中間方結點駐留在發送結點和接收結點之間,負責處理SOAP消息頭中定義的部分消息。SOAP發送方和接收方之間可以有0個或多個SOAP中間方,它為SOAP接收方提供分布式處理機制。
一般,SOAP消息中間方分為兩種:
1.?轉發中間方:這一類型的中間方通過在所轉發消息的SOAP消息頭塊中描述和構造語義和規則,從而實現消息處理。
2.?活動中間方:這一類型的中間方利用一組功能為接收方結點修改外部綁定消息,從而提供更多的消息處理操作。
在SOAP消息交換路徑中,借助于SOAP中間方,使得分布式處理模型在SOAP消息交換中得以實現。通過使用SOAP中間方,可以向SOAP應用程序中集成各種功能(如轉發、過濾、事務、安全、日志記錄、智能路由等)。
?
2.2沒有消息提供者的客戶端
不使用消息提供者的應用程序只能交換同步消息。也就是說,扮演客戶端角色的應用程序只能發送請求-響應消息。這種類型的客戶端采用SAAJ?API的SOAPConnection方法。下圖演示了在沒有消息提供者的情況下,同步消息如何在發送者和接收者之間交換。
????????????圖1?不使用消息提供者的SOAP消息
不使用消息提供者的客戶端具有以下優點:?
>?可以采用J2SE平臺編寫應用程序。?
>?不需要在servlet或J2EE容器中部署應用程序。?
>?不需要配置消息提供者。?
不使用消息提供者的客戶端具有以下局限性:?
>?客戶端只能發送請求-響應消息?
>?客戶端只能扮演客戶端角色?
?
2.3使用消息提供者的客戶端
如果想要獲得并且保存在任何時間發送給你的請求,你必須使用消息提供者。使用消息提供者的客戶端還能發送異步消息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提供者。
?
3.SOAP消息
3.1SOAP消息的組成部分
所有的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文件。
3.2SOAP消息舉例
先來看一個簡單的例子:
在這個例子中,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處理指令。
?
3.3SOAP?Envelope
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?>
?
3.4SOAP?Header
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)表明它包含身份驗證信息。
?
3.5SOAP?Body
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?>
?
3.6SOAP?Fault
| 子元素 | 描述 |
| <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 | 服務器有問題,因此無法處理進行下去。 |
?
3.7附件
按照SOAP1.1規范的規定,SOAP消息可以包含XML格式的主SOAP信封,以及包含ASCII或二進制等任何數據格式的SOAP附件。如果SOAP消息包含附件,那么SOAP消息將是一個MIME編碼的消息,它包含SOAP內容和一個或多個其他類型的附件。因此SOAP消息實際上分為以下兩種類型:
>?僅包含XML內容的消息
>?MIME編碼的消息,包含初始的XML有效內容以及任何數量的附件。這些附件可以是任何其他類型的數據。
【MIME:Multi-purpose?Internet?Mail?Extensions多用途Internet郵件擴展,是一組技術規范,其目的是使用不同字符集來傳遞文本,也可以在計算機之間傳遞各種各樣的多媒體數據】
?
4.SOAP?HTTP?Binding
4.1HTTP?協議
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
?
4.2SOAP?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
轉載于:https://www.cnblogs.com/IT-TOP/p/10687932.html
總結