SOAP(Simple Object Accrss Protocol,簡單對象訪問協議)是一種簡單的基於XML的協議,能夠使應用程序在分散或分佈式的環境中經過HTTP來交換信息。編程
SOAP基於XML語言和XSD標準,其定義了一套編碼規則,編碼規則定義如何將數據表示爲消息,以及怎樣經過HTTP協議來傳輸SOAP消息,由四部分組成:數組
(1) SOAP信封(Envelope):定義了一個框架,框架描述了消息中的內容是什麼,包括消息的內容、發送者、接收者、處理者以及如何處理消息。瀏覽器
(2)SOAP編碼規則:定義了一種系列化機制,用於交換應用程序所定義的數據類型的實例。安全
(3) SOAP RPC表示:定義了用於表示遠程過程調用和應答協定。服務器
(4)SOAP綁定:定義了一種使用底層傳輸協議來完成在節點間交換SOAP信封的約定。數據結構
SOAP消息基本上是從發送端到接收端的單向傳輸,經常結合起來執行相似於請求/應答的模式。不須要把SOAP消息綁定到特定的協議,SOAP能夠運行在任何其餘傳輸協議(HTTP、SMTP、FTP等)上。另外,SOAP提供了標準的RPC方法來調用Web Service以請求/響應模式運行。app
SOAP是Web Service的通訊協議。當用戶經過UDDI找到你的WSDL描述文檔後,他經過能夠SOAP調用你創建的Web服務中的一個或多個操做。SOAP是XML文檔形式的調用方法的規範,能夠支持不一樣的底層接口,像HTTP(S)或者SMTP。框架
應用程序經過使用遠程過程調用(RPC)在諸如 DCOM 與 CORBA 等對象之間進行通訊的方式會產生兼容性以及安全問題;防火牆和代理服務器一般會阻止此類流量。經過 HTTP 在應用程序間通訊是更好的方法,由於 HTTP 獲得了全部的因特網瀏覽器及服務器的支持。SOAP 提供了一種標準的方法,使得運行在不一樣的操做系統並使用不一樣的技術和編程語言的應用程序能夠互相進行通訊。異步
SOAP是一種輕量級通訊協議編程語言
SOAP用於應用程序之間的通訊
使用SOAP的應用使用HTTP協議通訊
SOAP獨立於平臺
SOAP獨立於編程語言
SOAP基於XML
SOAP很簡單並可擴展
SOAP容許繞過防火牆
SOAP結點表示SOAP消息路徑的邏輯實體,用於進行消息路由或處理。SOAP結點能夠是SOAP消息的發送者、接收方、消息中介。
在SOAP消息模型中,中間方爲一種SOAP結點,負責提供發送消息的應用程序和接收方間的消息交換和協議路由功能。中間方結點駐留在發送結點和接收結點之間,負責處理SOAP消息頭中定義的部分消息。SOAP發送方和接收方之間能夠有0個或多個SOAP中間方,爲SOAP接收方提供分佈式處理機制。
通常,SOAP消息中間方分爲兩種:
A、轉發中間方:轉發中間方經過在所轉發消息的SOAP消息頭塊中描述和構造語義和規則,從而實現消息處理。
B、活動中間方:活動中間方利用一組功能爲接收方結點修改外部綁定消息,從而提供更多的消息處理操做。
在SOAP消息交換路徑中,藉助於SOAP中間方,使得分佈式處理模型在SOAP消息交換中得以實現。經過使用SOAP中間方,能夠向SOAP應用程序中集成各類功能(如轉發、過濾、事務、安全、日誌記錄、智能路由等)。
不使用消息提供者的應用程序只能交換同步消息,即扮演客戶端角色的應用程序只能發送請求-響應消息。客戶端採用SAAJ API的SOAPConnection方法。下圖演示了在沒有消息提供者的狀況下,同步消息如何在發送者和接收者之間交換。
不使用消息提供者的客戶端具備優勢以下:
A、能夠採用J2SE平臺編寫應用程序。
B、不須要在servlet或J2EE容器中部署應用程序。
C、不須要配置消息提供者。
不使用消息提供者的客戶端的侷限性以下:
A、客戶端只能發送請求-響應消息
B、 客戶端只能扮演客戶端角色
若是想要得到而且保存在任什麼時候間發送給你的請求,必須使用消息提供者。使用消息提供者的客戶端還能發送異步消息。JAXM API提供了使用消息提供者發送和接收消息的框架。須要在容器中運行客戶端,容器提供了消息基礎結構讓提供者使用。下圖演示了在使用消息提供者的狀況下,異步消息如何在發送者和接收者之間交換。
使用消息提供者的客戶端具備優勢以下:
A、客戶端可以扮演客戶端或者服務角色
B、客戶端可以切換消息傳遞給提供者
C、在客戶端傳遞消息到最終接收者以前,它可以發送消息到一個或多個目的地。這些中間的消息接收者被稱爲actor,它們在消息的SOAPHeader對象中被指定。
D、客戶端可以利用任何提供者支持的SOAP消息協議和影響消息類型與可靠性的‘服務質量’,以及消息傳遞服務的質量。
全部的SOAP消息都使用XML編碼,一條SOAP消息就是一個普通的XML文檔,文檔包括下列元素:
A、Envelope(信封)元素,必選,可把此XML文檔標識爲一條SOAP消息。
B、Header(報頭)元素,可選,包含頭部信息(包含了使消息在到達最終目的地以前,可以被路由到一個或多箇中間節點的信息)。
C、Body(主體)元素,必選,包含全部的調用和響應信息。
D、Fault元素,位於Body內,可選,提供有關處理此消息所發生錯誤的信息。
E、Attachment(附件)元素,可選,可經過添加一個或多個附件擴展SOAP消息。
SOAP消息對象包括:
SOAP Envelope是表明消息的XML文件的根元素。它爲消息如何處理、由誰處理定義了框架。XML內容從SOAP Envelope開始。
SOAP Header是添加特性到SOAP消息的基本機制。它能夠容納任意數目的擴展了基礎協議的子元素。例如,header子元素可能會定義認證信息、事務信息、本地信息等等。處理消息的軟件能夠在沒有事先約定的狀況下,使用這個機制定義誰應該處理某個特性,以及該特性是強制的仍是可選的。
SOAP Body是發給消息最終接收者的強制信息的容器。SOAP消息還能夠容納一個附件,它不必定非得是XML文件。
全部以上的元素均被聲明於針對SOAP封裝的默認命名空間中:
http://www.w3.org/2001/12/soap-envelope
以及針對 SOAP 編碼和數據類型的默認命名空間:
http://www.w3.org/2001/12/soap-encoding
A、SOAP消息必須用XML來編碼
B、SOAP消息必須使用SOAP Envelope命名空間
C、SOAP消息必須使用SOAP Encoding命名空間
D、SOAP消息不能包含DTD引用
E、SOAP消息不能包含XML處理指令
<?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消息的根元素,必須出如今每一個SOAP消息中,用於把此XML文檔標示爲一條SOAP消息。
A、命名空間
在SOAP中,使用XML命名空間將SOAP標示符與應用程序特定的標示符區分開,將SOAP消息的元素的做用域限制在一個特定的領域。若是使用了不一樣的命名空間,應用程序會發生錯誤,並拋棄此消息。
SOAP消息必須擁有與命名空間相關聯的一個Envelope元素,SOAP消息中全部元素必須由第一個命名空間進行限定。
SOAP 1.1規範以下:
<soap-env:Envelope xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/"
</soap-env:Envelope >
SOAP 1.2規範以下:
<soap:Envelope xmlns:soap="http://www.w3.org/2001/12/soap-envelope"
</soap:Envelope>
B、encodingStyle屬性
SOAP的encodingStyle屬性用於定義在文檔中使用的數據類型,encodingStyle屬性可出如今任何SOAP元素中,並會被應用到元素的內容及元素的全部子元素上。SOAP消息沒有默認的編碼方式。
語法
soap:encodingStyle="URI"
SOAP 1.1規範以下:
<soap-env:Envelope xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/"
Soap-env>
</ soap-env:Envelope >
SOAP 1.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元素應看成爲SOAP Envelope的第一個直接子元素,必須使用有效的命名空間。Header還能夠包含0個或多個可選的子元素,子元素稱爲Header項,全部的Header項都必須是完整修飾的,即必須由一個命名空間URI和局部名組成,不容許沒有命名空間修飾的Header項存在。
Header元素用於與消息一塊兒傳輸附加消息,如身份驗證或事務信息。Header元素也能夠包含某些屬性。SOAP在默認的命名空間中定義了三個屬性:actor,mustUnderstand以及encodingStyle。這些被定義在SOAP頭部的屬性可通知容器如何對SOAP消息進行處理。
<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"。
A、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>
B、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>
C、encodingStyle屬性
SOAP的encodingStyle屬性與Envelope元素中相同。
SOAP消息的Body塊能夠包含如下任何元素:
A、RPC方法及其參數
B、目標應用程序(消息接收者)專用數據
C、報告故障和狀態消息的SOAP Fault
全部Body元素的直接子元素都稱爲Body項,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消息須要包括SOAP Fault元素,SOAP Fault元素必須做爲一個Body項出現,並且至多出現一次。SOAP Fault包括如下子元素:faultcode、faultstring、faultactor、detail。
子元素 |
描述 |
<faultcode> |
供識別故障的代碼 |
<faultstring> |
可供人閱讀的有關故障的說明 |
<faultactor> |
有關是誰引起故障的信息 |
<detail> |
存留涉及 Body 元素的應用程序專用錯誤信息 |
SOAP的Fault元素擁有下列子元素:
在下面定義的 faultcode 值必須用於描述錯誤時的 faultcode 元素中:
VersionMismatch |
SOAP Envelope 元素的無效命名空間被發現 |
MustUnderstand |
Header 元素的一個直接子元素(帶有設置爲 "1" 的 mustUnderstand 屬性)沒法被理解。 |
Client |
消息被不正確地構成,或包含了不正確的信息。 |
Server |
服務器有問題,所以沒法處理進行下去。 |
按照SOAP1.1規範的規定,SOAP消息能夠包含XML格式的主SOAP信封,以及包含ASCII或二進制等任何數據格式的SOAP附件。若是SOAP消息包含附件,那麼SOAP消息將是一個MIME編碼的消息,包含SOAP內容和一個或多個其餘類型的附件。所以SOAP消息實際上分爲如下兩種類型:
A、僅包含XML內容的消息
B、MIME編碼的消息,包含初始的XML有效內容以及任何數量的附件。附件能夠是任何其餘類型的數據。
【MIME:Multi-purpose Internet Mail Extensions多用途Internet郵件擴展,是一組技術規範,其目的是使用不一樣字符集來傳遞文本,也能夠在計算機之間傳遞各類各樣的多媒體數據】
Web服務的有效負載一般包裝在SOAP消息中,而SOAP消息結構由WSDL文檔中的SOAP綁定定義肯定。不一樣的調用方式和編碼方式經過組合能夠產生多種綁定樣式,而每種樣式的應用場景和對應的SOAP消息結構並不相同。若是沒有正確的構造SOAP消息,則沒法正確交換服務的有效負載。
SOAP Body提供了一種消息交換的機制,是SOAP消息的實際負載,可包含任意內容。SOAP消息體(SOAP Body)經過綁定服務調用方式(RPC或者Document)封裝操做,綁定編碼方式(Encoded或者Literal)序列化參數。SOAP消息的綁定樣式由style、use和encodingStyle三個屬性共同設置。style屬性指定服務的調用方式,是採用RPC方式仍是Document方式;use屬性指定消息的編碼方式,是採用Encoded方式仍是採用Literal方式;而encodingStyle屬性指定具體編碼規則,例如能夠指定SOAP編碼規則、XML Schema編碼規則等等,一般狀況下都是採用XML Schema。
style屬性描述了服務的調用方式,取值爲」rpc」或者」document」,默認值爲」document」。適用於SOAP Body元素的子元素(也多是孫級元素)。此選項指定爲WSDL文檔中的soap:binding元素(一般狀況下)或者soap:operation 的style屬性。
A、RPC
RPC: 採用客戶端/服務器方式(請求/響應),發送請求到服務器端,服務端執行方法後返回結果。優勢是跨語言跨平臺,缺點是編譯時沒法排錯,只能在運行時檢查。
SOAP消息本質上是一種從發送方到接收方的單向傳輸,可是SOAP常常組合到實現請求/響應機制中。要讓RPC使用SOAP,必須遵循幾條規則。首先,請求和響應消息必須被編碼成結構類型。其次,對一個操做的每個輸入參數,都必須有一個同名元素(或輸入結構的成員)做爲參數。最後,對每個輸出參數,都必須有一個名稱匹配的元素(或輸出結構的成員)。
style=」rpc」指明聽從SOAP標準,在SOAP Body中封裝RPC調用的請求和返回操做。對該類消息的約束是必須把操做的名稱做爲封裝了對操做的請求和響應消息負載的根元素名稱。對於SOAP請求消息,請求操做的名稱是根據WSDL文檔中的wsdl:operation元素命名,後者對應Web服務方法。對於SOAP響應消息,響應操做的名稱是請求操做的名稱後面追加"Response"構成。操做元素中的每一個子元素表示一個參數,根據WSDL文檔中的wsdl:part元素命名。RPC請求/響應消息的格式(省略了名稱空間限定)以下:
RPC請求消息格式:
<SOAP信封>
<SOAP頭部>
……
</SOAP頭部>
<SOAP消息體>
<請求操做名稱>
<參數名1>值</參數名1>
<參數名2>值</參數名2>
......
</請求操做名稱>
</SOAP消息體>
</SOAP信封>
RPC響應消息格式:
<SOAP信封>
<SOAP頭部>
……
</SOAP頭部>
<SOAP消息體>
<響應操做名稱>
<參數名1>值</參數名1>
<參數名2>值</參數名2>
......
</響應操做名稱>
</SOAP消息體>
</SOAP信封>
B、Document
與RPC相比較Document方式在XML文件中不是作遠程方法的映射,而是一份完整的自包含的業務文檔。當服務器端收到這份文檔後,先進行預處理(好比詞彙的翻譯和映射),而後再構造出返回消息。構造返回消息的過程當中,每每再也不是簡簡單單的一個方法調用,而是多個對象協同完成一個事務的處理,再將結果返回。
採用Document方式構造消息,SOAP Body元素中的內容徹底由WSDL 中的 XML Schema定義,因而可使用XML Schema驗證SOAP Body元素中的內容。SOAP Body的子元素指定爲消息部分在WSDL文檔中定義的 wsdl:part 元素,該元素指向 XML Schema元素聲明。一般wsdl:message不會包含多個wsdl:part 元素,因此SOAP Body 內容是真正的 XML 文檔,儘管 WSDL 自己不由止包含多個wsdl:part元素。Document請求/響應消息的格式(省略了名稱空間限定)以下:
Document請求消息格式:
<SOAP信封>
<SOAP頭部>
……
</SOAP頭部>
<SOAP消息體>
<輸入消息>
….
</輸入消息>
….
</SOAP消息體>
</SOAP信封>
Document響應消息格式:
<SOAP信封>
<SOAP頭部>
……
</SOAP頭部>
<SOAP消息體>
<輸出消息>
….
</輸出消息>
….
</SOAP消息體>
</SOAP信封>
use屬性描述了消息序列化的方式,取值爲」encoded」或者」literal」,默認值是」literal」。 若是use=」encoded」,設置encodingStyle屬性的值指定編碼規則。若是use=」literal」,能夠不用設置encodingStyle屬性的值,一般狀況都是使用默認的XML Schema。適用於出如今下一個級別的 Web 服務方法參數(或返回值)。此選項指定爲WSDL文檔中的 soap:body、soap:header、soap:fault和soap:headerfault元素的 use 屬性。
A、Encoded
SOAP編碼使用XML Schema的一個子集在XML文檔與其所表示的數據之間進行綁定。SOAP 編碼還使用href屬性對文檔中屢次出現的元素的引用。SOAP編碼和XML Schema編碼徹底不一樣的地方是數組。SOAP規範的5.4.2節指定了一種特別的機制來表示 XML 中的編程語言數組,它使用一種特殊的SOAP-ENC:Array類型。而XML Schema是經過設置element的minOccurs和maxOccurs屬性值表示數組。例如使用這兩種編碼方式對×××數組的定義以下:
SOAP編碼定義數組
<complexType name="ArrayOfInt"> <complexContent> <restriction base="SOAP-ENC:Array"> <sequence> <element name=」item」 type=」xsd:int」 minOccurs=」0」 maxOccurs=」unbounded」/> </sequence> <attribute ref=" SOAP-ENC:arrayType" wsdl:arrayType="xsd:ArrayOfInt[]"/> </restriction> </complexContent> </complexType> XML Schema定義數組 <complexType name="ArrayOfInt"> <sequence> <element name=」item」 type=」xsd:int」 minOccurs=」0」 maxOccurs=」unbounded」/> </sequence> </complexContent> </complexType>
B、Literal
與Encoded相比,Literal採用XML Schema編碼,而不是SOAP編碼;Literal編碼不須要數據類型屬性。數據根據 WSDL 文檔中指定的 XML Schema定義或導入 WSDL 文檔的 XML Schema定義逐字進行格式設置。使用Literal方式編碼add方法的消息格式以下:
<op:add xmlns:op=」http://act.buaa.edu.cn/add」> <a> <item>45</item> <item>36</item> </a> <b> <item>235</item> <item>67</item> </b> </op:bdd>
WSDL規範中的encodingStyle屬性和SOAP規範中的encodingStyle 屬性定義是同樣的。encodingStyle屬性的值是一個URIs列表,由單個空格隔開,每一個URI表明着一種消息的編碼規則,它們按照編碼的限制從強到弱排序。encodingStyle屬性是用來指定SOAP消息的編碼規則,也就是序列化的格式和類型系統。若是use=」encoded」,encodingStyle屬性的值爲」http://schemas.xmlsoap.org/soap/encoding/」,則表示使用SOAP規範的第5節的編碼,這一節定義了將編程語言的類型映射到 XML 的基本機制。若是use=」literal」則使用外部提供的類型系統,也能夠經過encodingStyle屬性來指定Schema,可是一般狀況下使用XML Schema來編碼SOAP消息。
這其中的緣故是由於SOAP規範是在採用XML Schema規範以前編寫的。所以,原始的SOAP規範必須提供一種方法來指明編碼類型信息。然而,自從採用XML Schema以後,大多數語言使用本身的從XML Schema到編程語言類型之間的映射(或序列化規則),這使得SOAP編碼變得過期。所以,推薦不要採用SOAP編碼,而是採用使用Literal編碼,在Literal映射中由 XML Schema 文檔(一般是WSDL文檔的形式)從外部指定映射。
style和use屬性都有兩個值,經過它們之間的不一樣組合,就能夠產生四種綁定樣式,分別是rpc-literal、rpc-encoded、document-literal和document-encoded。爲了使Document綁定樣式可以支持RPC綁定樣式的調用,增長了一種包裝(Wrapped)樣式,它只不過是對Document樣式的使用進行了約束。這樣就又增長了兩種綁定樣式, document-literal-wrapped和document-encoded-wrapped,一共合起來就有6種綁定樣式。下面經過一個加法服務爲例來講明在不一樣綁定樣式下的SOAP消息構造,服務的定義以下:
從服務的定義能夠看出,輸入操做的操做名爲add,有a和b兩個整數類型的輸入參數。根據WSDL規範返回操做的操做名應該爲addResponse,有一個整數類型的輸出參數,假設命名爲return。
操做的序列化是須要名稱空間限定的。若是是RPC調用方式,則名稱空間是soap :body的namespace屬性值;若是是Document調用方式,名稱空間則是輸入消息引用的Schema的targetNamespace屬性值。參數的序列化是否須要名稱空間限定取決於Schema定義時elementFormDefault屬性的值。若是值爲」qualified」則表示須要限定,名稱空間爲Schema的targetNamespace屬性值;若是值爲」unqualified」表示不用限定,默認值爲」unqualified」。操做序列化後的元素做爲SOAP消息體的子元素,而每一個參數序列化後的元素都是做爲操做元素的子元素,排列的順序和操做的參數定義順序同樣。
假定如下全部SOAP消息都是在以下條件下構造:
A、若是use= 」encoded」則encodingStyle的值爲」http://schemas.xmlsoap.org/soap/encoding/」,若是use= 」literal」則使用」 http://www.w3.org/2001/XMLSchema」編碼。
B、若是style=」rpc」則wsdl:part 部分的類型引用使用type屬性,若是style=」document」則使用element屬性。
WSDL描述:
<wsdl:definitions xmlns:wsdl= " http://schemas.xmlsoap.org/wsdl/" xmlns:ns="http://act.buaa.edu.cn/add" xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="http://act.buaa.edu.cn/add"> <wsdl:message name=」addRequest」> <wsdl:part name=」a」 type=」xsd:int」/> <wsdl:part name=」b」 type=」xsd:int 」/> </wsdl:message> <wsdl:message name=」addReponse」> <wsdl:part name=」return」 type=」xsd:int」/> </wsdl:message> <!--Just assume it's rpc-literal. --> ……
SOAP請求消息:
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"> <env:Body> <op: add xmlns:op=「http://act.buaa.edu.cn/add」> <a>12</a> <b>45</b> </op: add > </env:Body> </env:Envelope>
優勢:WSDL 描述和SOAP消息基本達到了儘量地簡單易懂的要求;服務的操做名出如今SOAP消息的Body中,這樣接收者就能夠很輕鬆地把消息發送到方法的實現;沒有類型編碼,提升了吞吐量,減小了處理的性能開銷。
缺點:在RPC模型中XML僅僅被用於描述方法的信息,不能充分利用XML的功能去描述和驗證一份業務文檔 ;不能使用Schema簡單地檢驗此消息的有效性,由於只有參數a和b是Schema 中定義的內容,其他的 env:body 內容(例如add元素)都來自 WSDL 定義;沒法直接從消息中得到參數的類型信息;RPC樣式對請求/響應消息的模式捆綁,使得服務與客戶端之間耦合性增長,一旦方法發生變化,客戶端就須要作相應的改動;相對異步調用方式而言,RPC樣式下服務調用一般是同步的。
SOAP請求消息:
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi=」 http://www.w3.org/2001/XMLSchema-instance」 > <env:Body> <op: add xmlns:op=「http://act.buaa.edu.cn/add」> < a xsi:type=」xsd:int」>12</a> <b xsi:type=」xsd:int」>45</b> </op: add > </env:Body> </env:Envelope>
與rpc-literal綁定樣式惟一的區別就是請求消息的參數部分編碼方式不同。消息中的每一個參數都有類型編碼(好比 <a xsi:type=」int」>12</a>),直接從消息就能夠知道參數的數據類型。可是這些類型信息下降了吞吐量和消息處理的性能。尤爲是在大數據的狀況下,性能開銷明顯。
rpc-encoded綁定樣式主要在重載、數據圖形和多態的狀況下使用。WSDL 容許重載的操做,可是當參數個數相同的狀況下,由於Literal編碼方式沒有類型信息,沒法定位方法,因此rpc-literal就不支持這樣的重載。數據圖形的標準方式是使用href 標記,它是 rpc-encoded的樣式。多態所生成的 SOAP 消息必須包含類型編碼信息,這樣接收終端才能知道它所接收的是父類的哪個擴展。
WSDL 描述:
<wsdl:definitions xmlns:wsdl= " http://schemas.xmlsoap.org/wsdl/" xmlns:ns="http://act.buaa.edu.cn/add" targetNamespace=" http://act.buaa.edu.cn/add "> <wsdl :types> <xs:schema elementFormDefault="qualified" targetNamespace="http://act.buaa.edu.cn/add" xmlns:xs="http://www.w3.org/2001/XMLSchema" > <xs:element name="a" type="xs:int " /> <xs:element name="b" type="xs:int " /> <xs:element name="return" type="xs:int " /> </xs :schema> </wsdl :types> <wsdl:message name=」addRequest」> <wsdl:part name=」parameter1」 element=」ns:a」/> <wsdl:part name=」parameter2」 element=」ns:b」/> </wsdl:message> <wsdl:message name=」addReponse」> <wsdl:part name=」parameter」 element=」ns:return」/> </wsdl:message> <!--Just assume it's document-literal. --> ……
SOAP 請求消息:
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:op=「http://act.buaa.edu.cn/add」> <env:Body> <op:a>12</op:a> <op:b>45</op:b> </env:Body> </env:Envelope>
請求消息的參數元素添加了名稱空間限定,這是由於輸入消息在WSDL文檔的Schema中定義,並且Schema的elementFormDefault=」qualified」。也就是說參數元素必須使用Schema的名稱空間"http://act.buaa.edu.cn/add"進行限定。
優勢:沒有操做和類型編碼信息,減小了消息的數據量,提升了消息處理性能;env:Body中每項內容都定義在Schema中,能夠用任何XML檢驗器檢驗此消息的有效性。
缺點:WSDL文檔變得比較複雜,這不過是一個很是小的缺點,由於 WSDL 並無打算由人來讀取;SOAP消息中沒有提供服務操做的名稱,一些特定的程序代碼在分發消息時可能會變得複雜,而且有時變得不可能。若是使用HTTP做爲底層傳輸協議,可使用SOAPAction屬性綁定操做的名稱來解決消息分發的問題。雖然大多數狀況下都是使用HTTP協議來傳輸SOAP消息,可是這種方法綁定了底層傳輸協議,限制了其餘傳輸協議的使用。
SOAP 請求消息:
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi=」 http://www.w3.org/2001/XMLSchema-instance」 xmlns:op=「http://act.buaa.edu.cn/add」> <env:Body> <op:a xsi:type=」xsd:int」>12</op:a> <op:b xsi:type=」xsd:int」>45</op:b> </env:Body> </env:Envelope>
與document-literal綁定樣式惟一的區別就是請求消息的參數部分編碼方式不同。引入了類型編碼,下降了吞吐量和消息處理的性能。這種綁定樣式不被大多數Web服務實現平臺支持。
WSDL描述:
<wsdl:definitions xmlns:wsdl= " http://schemas.xmlsoap.org/wsdl/" xmlns:ns="http://act.buaa.edu.cn/add" targetNamespace=" http://act.buaa.edu.cn/add "> <wsdl :types> <xs:schema elementFormDefault="qualified" targetNamespace="http://act.buaa.edu.cn/xsd" xmlns:xs="http://www.w3.org/2001/XMLSchema" > <xs:element name="add"> <xs:complexType> <xs:sequence> <xs:element name="a" type="xs:int " /> <xs:element name="b" type="xs:int " /> </xs:sequence> </xs:complexType> </xs:element> <xs:element name="addResponse"> <xs:complexType> <xs:sequence> <xs:element name="return" type="xs:int " /> </xs:sequence> </xs:complexType> </xs:element> </xs :schema> </wsdl :types> <wsdl:message name=」addRequest」> <wsdl:part name=」parameter」 element=」ns:add」/> </wsdl:message> <wsdl:message name=」addReponse」> <wsdl:part name=」parameter」 element=」ns:addResponse」/> </wsdl:message> <!--Just assume it's document-literal-wrapped. --> ……
SOAP請求消息:
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"> <env:Body> <op: add xmlns:op=「http://act.buaa.edu.cn/add」> <op:a>12</op:a> <op:b>45</op:b> </op: add > </env:Body> </env:Envelope>
此時SOAP Body中第一個元素的名稱並非操做的名稱,而是Schema中的元素的名稱。Schema中的元素的名稱能夠與操做名相同,也能夠不一樣。若是取相同則是一種將操做名放入SOAP消息的巧妙方式。
雖然此SOAP 消息看起來與 rpc-literal的 SOAP 消息是徹底同樣的(若是不考慮名稱空間限定),可是這兩種消息之間存在着微妙的區別。在 rpc-literal的 SOAP 消息中,<env:Body>下的<op:add>根元素是操做的名稱。在document-literal-wrapped的SOAP 消息中,<op:add>元素是單個輸入消息的組成部分引用的元素的名稱。
document-literal-wrapped樣式規定Document綁定操做的輸入消息和輸出消息都只有一個wsdl:part部分;該部分使用element屬性引用一個元素;該元素是複雜類型而且沒有屬性;該元素的名稱和操做的名稱必須同樣。
優勢:包裝行爲吸收了RPC樣式的一個重要優勢,即RPC樣式中SOAP消息體能夠直接經過與之關聯的服務操做名稱來命名,同時又摒棄了RPC樣式的不足之處;能夠利用WSDL文檔類型部分的Schema文檔直接來驗證SOAP消息體;只要在Schema中定義了明確的數據結構,如何構建SOAP消息體具備很大的靈活性;因爲業務數據是自包含的,顯然文檔模型更利於採用異步處理。
缺點:WSDL 較爲複雜, 可是這仍然是一個很是小的缺點。使得服務調用的複雜度有所增長,尤爲是在API級別。針對程序開發人員來講,基於包裝的document綁定樣式的服務編寫客戶端代碼也許就變成了一項極具挑戰性的工做。在SOAP消息體的XML包裝元素中必須擁有一個服務操做的名稱,所以包裝版本不支持重載的服務操做。實際上,針對一個既定的元素名稱也只可以有一個服務操做。
SOAP請求報文
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi=」 http://www.w3.org/2001/XMLSchema-instance」 > <env:Body> <op: add xmlns:op=「http://act.buaa.edu.cn/add」> <op:a xsi:type=」xsd:int」>12</op:a> <op:b xsi:type=」xsd:int」>45</op:b> </op: add > </env:Body> </env:Envelope>
與document -literal-wrapped綁定樣式惟一的區別就是請求消息的參數部分編碼方式不同。引入了類型編碼,下降了吞吐量和消息處理的性能。
實際應用中須要和各類附件(如圖像、圖畫、xml 文檔等)一塊兒發送SOAP消息。附件數據一般是特殊的二進制格式。 帶附件的SOAP規範詳細說明了使用「MIME multipart/related」 媒體類型和URI模式引用MIME部件。並非全部的Web服務工具箱都提供SOAP附件支持。Microsoft提出了另外一個基於DIME的附件解決方案
帶附件的SOAP消息包以下:
SOAP消息包包含XML格式的主SOAP消息以及SOAP信封中未定義但與消息有關的任意數據格式(例如 gif、jpg 和 xml 等)的其它實體。
SOAP消息包是用MIME的Multipart/related 媒體類型構建的,每一個部件都嵌入MIME邊界(在Context-Type報頭中定義)。每一個 MIME部件都有報頭信息好比Context-Type 它指定嵌入這MIME部件的數據的類型)、Content Transfer-encoding(指定用於這個MIME部件的編碼)、 Content-ID或Content-Location(做爲從MIME包的任何地方引用這些內容的標識符)。MIME消息的根部件包含SOAP信封,Content-Type被設置爲text/xml。
SOAP報頭和SOAP消息的主體均可以引用消息包中的其它實體。根據 SOAP 1.1 編碼規則,SOAP的「href」屬性可用於引用任何資源。
任何資源均可以使用Content-ID或者Content-Location引用。若是使用Content-ID做爲標識符,那麼模式屬性(例如href)必須使用URL模式CID。若是使用Content-Location做爲標識符,那麼必須根據 帶附件的 SOAP規範中指定的規則進行解析,其中解析是基於下列要素之一:
絕對URI引用 ― 絕對URI是SOAP信封中的Content-Location和「href」屬性中指定的。
相對URI引用― MIME消息主報頭的Content-Location中指定了一個基礎(base)URI,對全部的相對URL都是使用這個基礎URL進行引用。
不帶基礎URI的相對URI ― 主報頭的Content-Location中沒指定基礎URI,但使用消息的基礎URL,而且對全部的相對URL都是使用這個基礎URL進行引用。
一般由SOAP處理器決定是否須要解析URI。並且,消息包中可能有在SOAP信封中沒有URI引用的附件。
若是HTTP綁定被SOAP用來發送附件,就須要修改HTTP報頭使其包含來自SOAP MIME包報頭的Content-Type信息。HTTP報頭中不包含來自MIME包報頭的其它報頭信息。Apache忽略了報頭信息好比Content-Transfer-Encoding和MIME Version 。全部的MIME部件都包含SOAP信封部件和其它附件,構成HTTP主體。另外一方面,對於 SMTP綁定來講,全部的多部件MIME報頭都會被做爲SMTP報頭的一部分存儲。這樣,SOAP處理器和應用程序就應該知道這些報頭與不一樣種類的 SOAP 綁定的不兼容性。
WSDL支持描述帶附件的Web服務。
<binding name="DocManagementService_Binding" ... /> <operation name="SubmitArrayOfDocuments"> <soap:operation soapAction="http://www.DocManagementService.com/SubmitArrayOfData"/> <input> <mime:multipartRelated> <mime:part> <soap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="urn:DocManagement-service" parts="SubmitArrayOfDocuments_inType1 SubmitArrayOfDocuments_inType2" use="encoded"/> </mime:part> <mime:part> <mime:content part="SubmitArrayOfDocuments_inType3" type="*/*"/> </mime:part> </mime:multipartRelated> </input> <output> <soap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="urn:DocManagement-service" use="encoded"/> </output> </operation> </binding>
binding元素的input和output元素被擴展,而且包含了帶有不一樣MIME部件的MIME:multipart-related,其中一個MIME部件用於 SOAP主體,其它的用於附件。每一個帶附件的MIME部件也均可以指定其內容類型。
在下面的例子中,一個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>
SOAP 1.1協議:
請求的協議體:
POST /weather HTTP/1.1 Accept: text/xml, multipart/related Content-Type: text/xml; charset=utf-8 SOAPAction: "http://weather.itheima.com/WeatherInterface/getWeatherByCityNameRequest" User-Agent: JAX-WS RI 2.2.4-b01 Host: 127.0.0.1:54321 Connection: keep-alive Content-Length: 235 <?xml version="1.0" ?> <S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/"> <S:Body> <ns2:getWeatherByCityName xmlns:ns2="http://weather.itheima.com"> <cityName>北京</cityName> </ns2:getWeatherByCityName> </S:Body> </S:Envelope>
響應的協議體:
HTTP/1.1 200 OK Transfer-encoding: chunked Content-type: text/xml; charset=utf-8 Date: Fri, 09 Oct 2015 07:23:29 GMT <?xml version="1.0" ?> <S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/"> <S:Body> <ns2:getWeatherByCityNameResponse xmlns:ns2="http://weather.itheima.com"> <WeatherInfo>今天風很大</WeatherInfo> </ns2:getWeatherByCityNameResponse> </S:Body> </S:Envelope>
SOAP 1.2協議:
請求的協議體:
POST /weather HTTP/1.1 Accept: application/soap+xml, multipart/related Content-Type: application/soap+xml; charset=utf-8; action="http://weather.itheima.com/WeatherInterface/getWeatherByCityNameRequest" User-Agent: JAX-WS RI 2.2.4-b01 Host: 127.0.0.1:54321 Connection: keep-alive Content-Length: 233 <?xml version="1.0" ?> <S:Envelope xmlns:S="http://www.w3.org/2003/05/soap-envelope"> <S:Body> <ns2:getWeatherByCityName xmlns:ns2="http://weather.itheima.com"> <cityName>北京</cityName> </ns2:getWeatherByCityName> </S:Body> </S:Envelope>
響應的協議體:
HTTP/1.1 200 OK Transfer-encoding: chunked Content-type: application/soap+xml; charset=utf-8 Date: Fri, 09 Oct 2015 07:54:53 GMT <?xml version='1.0' encoding='UTF-8'?> <S:Envelope xmlns:S="http://www.w3.org/2003/05/soap-envelope"> <S:Body> <ns2:getWeatherByCityNameResponse xmlns:ns2="http://weather.itheima.com"> <WeatherInfo>今天風很大</WeatherInfo> </ns2:getWeatherByCityNameResponse> </S:Body> </S:Envelope>