国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開(kāi)通VIP
理解 SOAP
發(fā)布日期: 4/1/2004 | 更新日期: 4/1/2004
Aaron Skonnard
DevelopMentor
2003 年 3 月
適用于:
全局 XML Web 服務(wù)結(jié)構(gòu) (GXA)
遠(yuǎn)程過(guò)程調(diào)用 (RPC)
SOAP 1.1 和 SOAP 1.2 規(guī)范
傳輸協(xié)議: TCP、HTTP、SMTP 和 MSMQ
Web Services Enhancements 1.0 SP1 for Microsoft .NET
XML 架構(gòu)
摘要: SOAP 提供一種簡(jiǎn)單的、可擴(kuò)展并且功能豐富的 XML 消息處理框架,用于定義高級(jí)別的應(yīng)用程序協(xié)議,從而在分布式異構(gòu)環(huán)境中提供更高的互操作性。(20 頁(yè)打印頁(yè))
本頁(yè)內(nèi)容
簡(jiǎn)介
SOAP 版本
消息處理框架
擴(kuò)展性
處理模型
協(xié)議綁定
HTTP 綁定
RPC 和編碼
SOAP 類型
小結(jié)
簡(jiǎn)介
就在不久以前,SOAP 還不過(guò)是指肥皂而已。 而如今,大多數(shù)開(kāi)發(fā)人員一聽(tīng)到這個(gè)詞眼前就會(huì)浮現(xiàn)出一些尖括號(hào)來(lái)。 SOAP 最初代表“簡(jiǎn)單對(duì)象訪問(wèn)協(xié)議”。 如果在幾年前問(wèn)任何一個(gè)人 SOAP 的含義,他們很可能這樣回答:“SOAP 是用來(lái)使 DCOM 和 Corba(例如,RPC 調(diào)用)在互聯(lián)網(wǎng)上工作”。 原作者們也承認(rèn),在那時(shí)他們注重于“訪問(wèn)對(duì)象”,但隨著時(shí)間的推移,人們希望 SOAP 能夠處理更廣泛的情況。 因此,SOAP 規(guī)范的重心很快從對(duì)象轉(zhuǎn)移到通用的 XML 消息處理框架上。
這種重心的變化給 SOAP 縮寫詞中的 "O" 帶來(lái)了一點(diǎn)小問(wèn)題。 有意思的是,SOAP 1.2 工作組沿用了(到目前為止)SOAP 這個(gè)名稱(為什么不呢?這個(gè)詞太流行了),但決定不再把這個(gè)詞拼出來(lái)以免誤導(dǎo)開(kāi)發(fā)人員。 如今,在最新的 SOAP 1.2 規(guī)范中,其正式的定義并不提及對(duì)象:
SOAP 是一種輕量級(jí)協(xié)議,用于在分散型、分布式環(huán)境中交換結(jié)構(gòu)化信息。 SOAP 利用 XML 技術(shù)定義一種可擴(kuò)展的消息處理框架,它提供了一種可通過(guò)多種底層協(xié)議進(jìn)行交換的消息結(jié)構(gòu)。 這種框架的設(shè)計(jì)思想是要獨(dú)立于任何一種特定的編程模型和其他特定實(shí)現(xiàn)的語(yǔ)義。
這個(gè)定義確實(shí)體現(xiàn)了 SOAP 現(xiàn)在的主旨。 SOAP 定義了一種方法以便將 XML 消息從 A 點(diǎn)傳送到 B 點(diǎn)(參見(jiàn)圖 1)。 為此,它提供了一種基于 XML 且具有以下特性的消息處理框架:1) 可擴(kuò)展,2) 可通過(guò)多種底層網(wǎng)絡(luò)協(xié)議使用,3) 獨(dú)立于編程模型。 以下將分別詳細(xì)討論這三種特性。
圖 1. 簡(jiǎn)單的 SOAP 消息處理
首先,SOAP 可擴(kuò)展性是關(guān)鍵所在。 在這個(gè)縮寫詞還代表某些含義時(shí),"S" 意味著“簡(jiǎn)單”。 如果我們從 Web 中學(xué)到了一樣?xùn)|西,那就是,簡(jiǎn)單性總是比效率和純技術(shù)更重要,因而互操作性成敗的關(guān)鍵,就在于必須絕對(duì)要求簡(jiǎn)單性。 簡(jiǎn)單性仍然是 SOAP 的主要設(shè)計(jì)目標(biāo)之一,這一點(diǎn)的例證就是 SOAP 缺少分布式系統(tǒng)的很多特性(如安全性、路由和可靠性等)。 SOAP 定義了一種通信框架,允許以分層擴(kuò)展的形式隨著時(shí)間推移而加入這些特性。 Microsoft、IBM 和其他軟件廠商正在積極開(kāi)發(fā)一個(gè) SOAP 擴(kuò)展的通用套件,該套件將加入大多數(shù)開(kāi)發(fā)人員期待的特性。 這一計(jì)劃被稱為全局 XML Web 服務(wù)結(jié)構(gòu) (GXA)Microsoft 已經(jīng)發(fā)布了針對(duì)若干 GXA 規(guī)范的一個(gè)參考實(shí)現(xiàn),并將其命名為 Web Services Enhancements 1.0 SP1 for Microsoft .NET (WSE)。
其次,SOAP 可在任何傳輸協(xié)議(諸如 TCP、HTTP、SMTP,甚至是 MSMQ)上使用(參見(jiàn)圖 1)。 然而,為了保持互操作性,需要定義一些標(biāo)準(zhǔn)協(xié)議綁定以便草擬用于每種環(huán)境的規(guī)則。 SOAP 規(guī)范提供了一種用于定義任意協(xié)議綁定的靈活框架,并且由于 HTTP 的使用極為廣泛,它現(xiàn)已為 HTTP 提供了一種顯式綁定。
第三,SOAP 允許任何編程模型,并且不依賴于 RPC。 大多數(shù)開(kāi)發(fā)人員立刻將 SOAP 與對(duì)分布式對(duì)象進(jìn)行的 RPC 調(diào)用等效起來(lái)(因?yàn)?SOAP 最初就是關(guān)于“訪問(wèn)對(duì)象”的),但實(shí)際上,基本的 SOAP 模型更接近于傳統(tǒng)的消息處理系統(tǒng),如 MSMQ。 SOAP 定義了一種模型以便處理個(gè)別的單向消息。 你可以將多條消息組合成一條整體的消息交換。 圖 1 說(shuō)明了一種簡(jiǎn)單的單向消息,其中發(fā)送方不會(huì)收到響應(yīng)。 但是,接收方可以向發(fā)送方發(fā)回一條響應(yīng)(參見(jiàn)圖 2)。 SOAP 允許使用任何數(shù)量的消息交換模式 (MEP),請(qǐng)求/響應(yīng)只是其中一種。 其他示例包括要求/響應(yīng)(與請(qǐng)求/響應(yīng)相對(duì))、通知和長(zhǎng)期運(yùn)行的點(diǎn)對(duì)點(diǎn)對(duì)話等。
圖 2. 請(qǐng)求/響應(yīng)消息交換模式
開(kāi)發(fā)人員經(jīng)常將請(qǐng)求/響應(yīng)與 RPC 混為一談,而實(shí)際上二者之間的差別很大。 RPC 使用請(qǐng)求/響應(yīng),但請(qǐng)求/響應(yīng)不一定就是 RPC。 RPC 是 一種允許開(kāi)發(fā)人員進(jìn)行方法調(diào)用的編程模型。 RPC 需要將方法簽名轉(zhuǎn)換成 SOAP 消息。 鑒于 RPC 的廣泛應(yīng)用,SOAP 草擬了一項(xiàng)協(xié)議,以便將 RPC 用于 SOAP(參見(jiàn)本文稍后的RPC 和編碼一節(jié))。
具備這三種主要特性,SOAP 消息處理框架就促進(jìn)了在異構(gòu)環(huán)境中交換 XML 消息,而在這類環(huán)境中,互操作性長(zhǎng)久以來(lái)都是極大的挑戰(zhàn)。
返回頁(yè)首
SOAP 版本
從第一個(gè)發(fā)布的 SOAP 規(guī)范到如今被廣泛實(shí)施的 SOAP 1.1,很多方面都發(fā)生了改變,從瑣碎的細(xì)節(jié)到思想的重大轉(zhuǎn)變。 SOAP 1.1 被提交給 W3C,并于 2000 年 5 月被發(fā)布為 Note。由于 SOAP 1.1 未能通過(guò) W3C 過(guò)程的嚴(yán)格審核,"W3C Note" 狀態(tài)使其還停留在僅是一個(gè)好主意的層次,但當(dāng)完成時(shí),它將最終達(dá)到“推薦”狀態(tài)。 然而,由于如今 SOAP 1.1 得到了大小廠商如此廣泛的支持,它仍然被認(rèn)為是事實(shí)上的標(biāo)準(zhǔn)。
W3C 使用 SOAP 1.1 Note 作為新 XML 協(xié)議工作組的基礎(chǔ),負(fù)責(zé)產(chǎn)生下一版本的 SOAP,目前命名為SOAP 1.2。 SOAP 1.2 當(dāng)前是一種“候選推薦方案”,意味著它正處在實(shí)施階段且離最后完成為期不遠(yuǎn)。 一旦 SOAP 1.2 成為“推薦方案”,它極有可能很快獲得廠商的支持。
在 SOAP 1.2 發(fā)布之后,為了提供向后兼容性,廠商應(yīng)該繼續(xù)支持 SOAP 1.1。 SOAP 版本控制基于 XML 命名空間。 SOAP 1.1 由 http://schemas.xmlsoap.org/soap/envelope/ 命名空間標(biāo)識(shí),而 SOAP 1.2 由 http://www.w3.org/2002/12/soap-envelope 命名空間標(biāo)識(shí)(盡管當(dāng)其成為推薦方案時(shí),這也將改變)。
有關(guān)每個(gè)版本的命名空間名稱和規(guī)范所在位置,請(qǐng)參見(jiàn)表 1。 在本文的剩余部分中,我們將講述 SOAP 1.1 最重要的一些方面。 要了解兩個(gè)版本之間完整的更改列表,請(qǐng)查看當(dāng)前的 SOAP 1.2 規(guī)范。
表 1. SOAP 版本信息
SOAP 1.1
命名空間名稱
規(guī)范位置
SOAP 1.2
命名空間名稱
規(guī)范位置
http://schemas.xmlsoap.org/soap/envelope/
http://www.w3.org/TR/SOAP/
http://www.w3.org/2002/12/soap-envelope/
http://www.w3.org/TR/soap12-part0/(入門)
http://www.w3.org/TR/soap12-part1/
http://www.w3.org/TR/soap12-part2/
返回頁(yè)首
消息處理框架
SOAP 規(guī)范的核心部分就是消息處理框架。 SOAP 消息處理框架定義了一整套 XML 元素,用以“封裝”任意 XML 消息以便在系統(tǒng)之間傳輸。
該框架包括以下核心 XML 元素: Envelope、Header、Body 和 Fault,所有這些都來(lái)自 SOAP 1.1 中的 http://schemas.xmlsoap.org/soap/envelope/ 命名空間。 以下代碼中提供了 SOAP 1.1 的完整 XML 架構(gòu)定義,以供在閱讀下文時(shí)參考。 我個(gè)人認(rèn)為,每次讓自己熟悉各種 XML 結(jié)構(gòu)時(shí),檢查一下該架構(gòu)是頗有幫助的。
SOAP 1.1 XML 架構(gòu)定義
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"xmlns:tns="http://schemas.xmlsoap.org/soap/envelope/"targetNamespace="http://schemas.xmlsoap.org/soap/envelope/"><!-- Envelope, header and body --><xs:element name="Envelope" type="tns:Envelope" /><xs:complexType name="Envelope" ><xs:sequence><xs:element ref="tns:Header" minOccurs="0" /><xs:element ref="tns:Body" minOccurs="1" /><xs:any namespace="##other" minOccurs="0"maxOccurs="unbounded" processContents="lax" /></xs:sequence><xs:anyAttribute namespace="##other"processContents="lax" /></xs:complexType><xs:element name="Header" type="tns:Header" /><xs:complexType name="Header" ><xs:sequence><xs:any namespace="##other" minOccurs="0"maxOccurs="unbounded" processContents="lax" /></xs:sequence><xs:anyAttribute namespace="##other"processContents="lax" /></xs:complexType><xs:element name="Body" type="tns:Body" /><xs:complexType name="Body" ><xs:sequence><xs:any namespace="##any" minOccurs="0"maxOccurs="unbounded" processContents="lax" /></xs:sequence><xs:anyAttribute namespace="##any"processContents="lax" /></xs:complexType><!-- Global Attributes --><xs:attribute name="mustUnderstand" default="0" ><xs:simpleType><xs:restriction base=‘xs:boolean‘><xs:pattern value=‘0|1‘ /></xs:restriction></xs:simpleType></xs:attribute><xs:attribute name="actor" type="xs:anyURI" /><xs:simpleType name="encodingStyle" ><xs:list itemType="xs:anyURI" /></xs:simpleType><xs:attribute name="encodingStyle"type="tns:encodingStyle" /><xs:attributeGroup name="encodingStyle" ><xs:attribute ref="tns:encodingStyle" /></xs:attributeGroup><xs:element name="Fault" type="tns:Fault" /><xs:complexType name="Fault" final="extension" ><xs:sequence><xs:element name="faultcode" type="xs:QName" /><xs:element name="faultstring" type="xs:string" /><xs:element name="faultactor" type="xs:anyURI"minOccurs="0" /><xs:element name="detail" type="tns:detail"minOccurs="0" /></xs:sequence></xs:complexType><xs:complexType name="detail"><xs:sequence><xs:any namespace="##any" minOccurs="0"maxOccurs="unbounded" processContents="lax" /></xs:sequence><xs:anyAttribute namespace="##any"processContents="lax" /></xs:complexType></xs:schema>
如果檢查一下 Envelope 的 complexType 定義,你很快就能了解這些元素相互之間是如何關(guān)聯(lián)的。 以下消息模板說(shuō)明了 SOAP Envelope 的結(jié)構(gòu):
<soap:Envelopexmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Header> <!-- optional --><!-- header blocks go here... --></soap:Header><soap:Body><!-- payload or Fault element goes here... --></soap:Body></soap:Envelope>
Envelope 元素始終是 SOAP 消息的根元素。 這就便于應(yīng)用程序識(shí)別“SOAP 消息” — 只要檢查一下根元素的名稱即可。 通過(guò)檢查 Envelope 元素的命名空間,應(yīng)用程序也可確定所使用的 SOAP 版本。
Envelope 元素包含一個(gè)可選的 Header 元素(有關(guān)詳細(xì)信息,參見(jiàn)可擴(kuò)展性一節(jié)),后跟一個(gè)必要的 Body 元素。 Body 元素代表了該消息的有效內(nèi)容。 它是一種通用容器,因?yàn)樗砂瑏?lái)自任何命名空間的任意數(shù)量的元素。 這就是試圖發(fā)送數(shù)據(jù)的最終目的地。
例如,以下的 SOAP 消息代表了一個(gè)在銀行帳戶之間轉(zhuǎn)帳的請(qǐng)求:
<soap:Envelopexmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><x:TransferFunds xmlns:x="urn:examples-org:banking"><from>22-342439</from><to>98-283843</to><amount>100.00</amount></x:TransferFunds></soap:Body></soap:Envelope>
如果接收方支持請(qǐng)求/響應(yīng),且能夠成功地處理該消息,它應(yīng)向最初的發(fā)送方返回另一條 SOAP 消息。 在這種情況下,響應(yīng)信息也應(yīng)包含在 Body 元素中,如下例所示:
<soap:Envelopexmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><x:TransferFundsResponsexmlns:x="urn:examples-org:banking"><balances><account><id>22-342439</id><balance>33.45</balance></account><account><id>98-283843</id><balance>932.73</balance></account></balances></x:TransferFundsResponse></soap:Body></soap:Envelope>
該消息處理框架還定義了一個(gè)名為Fault 的元素,用于在發(fā)生錯(cuò)誤時(shí)在 Body 元素中表示錯(cuò)誤。 這是不可缺少的,因?yàn)槿绻麤](méi)有一種標(biāo)準(zhǔn)的錯(cuò)誤表示方法,每個(gè)應(yīng)用程序?qū)⒉坏貌蛔约簞?chuàng)建,從而使得通用基礎(chǔ)結(jié)構(gòu)不可能區(qū)分成功和失敗。 以下示例 SOAP 消息中包含了一個(gè) Fault 元素,指明在處理該請(qǐng)求時(shí)發(fā)生了“Insufficient Funds(資金不足)”錯(cuò)誤:
<soap:Envelopexmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><soap:Fault><faultcode>soap:Server</faultcode><faultstring>Insufficient funds</faultstring><detail><x:TransferError xmlns:x="urn:examples-org:banking"><sourceAccount>22-342439</sourceAccount><transferAmount>100.00</transferAmount><currentBalance>89.23</currentBalance></x:TransferError></detail></x:TransferFunds></soap:Body></soap:Envelope>
Fault 元素必須包含一個(gè) faultcode,后跟一個(gè) faultstring 元素。 faultcode 元素使用一種符合命名空間的名稱對(duì)錯(cuò)誤進(jìn)行分類,而 faultstring 元素提供一種對(duì)錯(cuò)誤可讀的解釋(類似于 HTTP 的工作方式)。 表 2 簡(jiǎn)要地說(shuō)明了 SOAP 1.1 所定義的各種錯(cuò)誤碼(所有這些代碼都包含在 http://schemas.xmlsoap.org/soap/envelope/ 命名空間中)。
Fault 元素也可能包含一個(gè) detail 元素,以便提供該錯(cuò)誤的細(xì)節(jié),這樣可以幫助客戶端診斷問(wèn)題,特別是在 Client 和 Server 錯(cuò)誤碼的情況下。
表 2. SOAP 1.1 錯(cuò)誤碼
名稱
VersionMismatch
MustUnderstand
Client
Server
含義
處理方發(fā)現(xiàn) SOAP Envelope 元素的命名空間是無(wú)效的。
處理方?jīng)]有理解或服從 SOAP Header 元素的某個(gè)直接子元素,而該子元素包含一個(gè)值為 "1" 的 SOAP mustUnderstand 屬性。
Client 類的錯(cuò)誤表明消息的格式錯(cuò)誤或者不包含適當(dāng)?shù)男畔?,因而不能成功?這通常表明,如果不對(duì)該消息做出更改,就不應(yīng)該重發(fā)該消息。
Server 類的錯(cuò)誤表明該消息未能得到處理的原因與消息的內(nèi)容并沒(méi)有直接關(guān)系,而是跟該消息的處理有關(guān)。 例如,處理過(guò)程可能包括與某個(gè)上游處理器的通信,但該處理器沒(méi)有響應(yīng)。 如果在稍后重發(fā),該消息可能會(huì)成功。
現(xiàn)在,假設(shè)你想在初始的消息中增加一些驗(yàn)證信息,以便接收方能夠確定發(fā)送方是否有足夠的權(quán)限來(lái)執(zhí)行傳輸。 要達(dá)到這一目的,一種方法就是在主體中添加憑證信息,如下所示:
<soap:Envelopexmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><x:TransferFunds xmlns:x="urn:examples-org:banking"><from>22-342439</from><to>98-283843</to><amount>100.00</amount><!-- security credentials --><credentials><username>dave</username><password>evad</password></credentials></x:TransferFunds></soap:Body></soap:Envelope>
如果使用這種方法,每項(xiàng)需要驗(yàn)證的操作都必須處理這些憑證。 這也意味著其他需要安全性的應(yīng)用程序必須開(kāi)發(fā)自己的解決方案以解決這個(gè)問(wèn)題;歸根結(jié)底,這將損害互操作性。 對(duì)于諸如安全性等公共需要,定義各方都同意的標(biāo)準(zhǔn) SOAP 標(biāo)頭將更有意義。 然后,各廠商可以在其通用的 SOAP 基礎(chǔ)結(jié)構(gòu)中建立對(duì)擴(kuò)展功能的支持,這樣各方皆贏。 這種方法可提高開(kāi)發(fā)人員的生產(chǎn)力,同時(shí)有助于確保更高級(jí)別的互操作性。 而這正是 SOAP 擴(kuò)展性模型設(shè)計(jì)要實(shí)現(xiàn)的目標(biāo)。
返回頁(yè)首
擴(kuò)展性
大多數(shù)現(xiàn)有的協(xié)議都區(qū)分控制信息(例如,標(biāo)頭)和消息有效負(fù)載。 在這方面,SOAP 也不例外。 SOAP Header 和 Body 元素在易于處理的 XML 世界中也進(jìn)行同樣的區(qū)分。 除了易用性之外,可擴(kuò)展 Envelope 的關(guān)鍵優(yōu)勢(shì)在于它可用于任何通訊協(xié)議。
在各種應(yīng)用程序協(xié)議中(如 HTTP、SMTP 等)標(biāo)頭總是具有重要的意義,因?yàn)闃?biāo)頭允許連網(wǎng)兩端的應(yīng)用程序就所支持命令的具體行為進(jìn)行協(xié)商。 盡管 SOAP 規(guī)范本身并不定義任何內(nèi)置的標(biāo)頭,標(biāo)頭將逐漸在 SOAP 中扮演同等重要的角色。 隨著 GXA 日趨成熟及 SOAP 標(biāo)頭的標(biāo)準(zhǔn)化,開(kāi)發(fā)人員能夠更方便地定義豐富的應(yīng)用程序協(xié)議,而不必每次都重新開(kāi)始。
與 Body 元素類似,Header 元素是控制信息的通用容器。 其中可包含來(lái)自任何命名空間(除 SOAP 命名空間之外)的任意數(shù)量的元素。 放置在 Header 元素中的各個(gè)元素被稱為標(biāo)頭塊。 如同其他協(xié)議一樣,標(biāo)頭塊中包含的信息應(yīng)該能夠影響有效負(fù)載的處理。 因此,這里正適于放置諸如憑證一類的元素,以幫助控制對(duì)操作的訪問(wèn):
<soap:Envelopexmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Header><!-- security credentials --><s:credentials xmlns:s="urn:examples-org:security"><username>dave</username><password>evad</password></s:credentials></soap:Header><soap:Body><x:TransferFunds xmlns:x="urn:examples-org:banking"><from>22-342439</from><to>98-283843</to><amount>100.00</amount></x:TransferFunds></soap:Body></soap:Envelope>
我們也可以利用一個(gè)名為 mustUnderstand 的全局 SOAP 屬性對(duì)標(biāo)頭塊進(jìn)行標(biāo)注,以指明接收方在處理該消息之前是否需要理解標(biāo)頭。 以下示例說(shuō)明了如何要求對(duì)憑證標(biāo)頭進(jìn)行處理:
<soap:Envelopexmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Header><!-- security credentials --><s:credentials xmlns:s="urn:examples-org:security"soap:mustUnderstand="1"><username>dave</username><password>evad</password></s:credentials></soap:Header>...
如果某個(gè)標(biāo)頭塊被標(biāo)注為 mustUnderstand="1",而接收方未設(shè)計(jì)為支持給定的標(biāo)頭,則不應(yīng)處理該消息,而應(yīng)該向發(fā)送方返回一條 Fault (帶有 soap:MustUnderstand 狀態(tài)碼)。 如果 mustUnderstand="0" 或者沒(méi)有提供 mustUnderstand 屬性,則接收方可以忽略相應(yīng)的標(biāo)頭塊并繼續(xù)進(jìn)行處理。 在整個(gè) SOAP 處理模塊中,mustUnderstand 屬性起著核心作用。
返回頁(yè)首
處理模型
SOAP 定義了一種處理模型,它大致規(guī)定了從 SOAP 發(fā)送方傳輸?shù)?SOAP 接收方的過(guò)程中對(duì) SOAP 消息的處理規(guī)則。 圖 1說(shuō)明了最簡(jiǎn)單的 SOAP 消息處理方案,其中一個(gè)應(yīng)用程序(SOAP 發(fā)送方)向另一個(gè)應(yīng)用程序(SOAP 接收方)發(fā)送一條 SOAP 消息。
但是,處理模型允許使用一些更有趣的結(jié)構(gòu)(如圖 3 中的結(jié)構(gòu)),這類結(jié)構(gòu)中包含多個(gè)中間 節(jié)點(diǎn)。 在下文中,將使用 SOAP 節(jié)點(diǎn) 這個(gè)術(shù)語(yǔ)指代任何要處理 SOAP 消息的應(yīng)用程序,不管是最初的發(fā)送方、中間節(jié)點(diǎn)還是最終的接收方;否則,我將明確指出并使用相應(yīng)的準(zhǔn)確術(shù)語(yǔ)。
圖 3. 高級(jí) SOAP 消息處理
中間節(jié)點(diǎn)位于最初的發(fā)送方和最終的接收方之間,并截獲 SOAP 消息。 中間節(jié)點(diǎn)可同時(shí)作為 SOAP 發(fā)送方和 SOAP 接收方。 中間節(jié)點(diǎn)使得有可能設(shè)計(jì)一些有趣且靈活的網(wǎng)絡(luò)體系結(jié)構(gòu),而這些網(wǎng)絡(luò)結(jié)構(gòu)能受到的消息內(nèi)容影響。 SOAP 路由就是一個(gè)很好的示例,它很大程度上利用了 SOAP 中間節(jié)點(diǎn)(有關(guān) SOAP 路由的詳細(xì)信息,請(qǐng)查看 Routing SOAP Messages with Web Services Enhancements 1.0)。
在處理消息時(shí),SOAP 節(jié)點(diǎn)承擔(dān)一個(gè)或者多個(gè)角色 (role),這些角色會(huì)影響如何處理 SOAP 標(biāo)頭。 各個(gè)角色被賦予獨(dú)特的名稱(以 URI 的形式),以便在處理過(guò)程中能夠識(shí)別這些角色。 當(dāng) SOAP 節(jié)點(diǎn)接收到一條要處理的消息時(shí),它首先必須確定要假定哪些角色。 它可以檢查該 SOAP 消息以幫助確定。
一旦 SOAP 節(jié)點(diǎn)確定了要扮演的角色,它隨后必須處理針對(duì)其角色之一的所有必要標(biāo)頭(標(biāo)記為mustUnderstand="1" )。 SOAP 節(jié)點(diǎn)也可選擇處理針對(duì)其角色之一的任何可選標(biāo)頭(標(biāo)記為 mustUnderstand="0")。
SOAP 1.1 只定義了一個(gè)名為 http://schemas.xmlsoap.org/soap/actor/next 的角色(簡(jiǎn)寫為 next)。 每個(gè) SOAP 節(jié)點(diǎn)都必須承擔(dān) next 角色。 因此,當(dāng) SOAP 消息到達(dá)任一給定的 SOAP 節(jié)點(diǎn)時(shí),該節(jié)點(diǎn)必須處理針對(duì) next 角色的所有必要標(biāo)頭,它可以選擇處理針對(duì)該 next 角色的可選標(biāo)頭。 除 next 外,SOAP 1.2 定義了另外一些角色(參見(jiàn)表 3),且應(yīng)用程序也可以定義自定義角色。
SOAP 標(biāo)頭通過(guò)全局 actor 屬性(在 SOAP 1.2 中該屬性名為 role )來(lái)指定具體的角色。 如果不存在 actor 屬性,則標(biāo)頭默認(rèn)地指向最終的接收方。 以下 SOAP 消息說(shuō)明了如何使用 actor:
<soap:Envelopexmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Header><wsrp:path xmlns:wsrp="http://schemas.xmlsoap.org/rp"soap:actor="http://schemas.xmlsoap.org/soap/actor/next"soap:mustUnderstand="1">...
由于 wsrp:path 標(biāo)頭被指定為 next 角色且被標(biāo)記為必要的 (mustUnderstand="1"),因此接收到此消息的第一個(gè) SOAP 節(jié)點(diǎn)必須根據(jù)該標(biāo)頭塊的規(guī)范來(lái)處理此消息,在這種情況下為 WS-Routing。 如果 SOAP 節(jié)點(diǎn)不理解針對(duì)其角色之一的某個(gè)必要的標(biāo)頭,則它必須產(chǎn)生一個(gè)帶 soap:MustUnderstand 狀態(tài)碼的 SOAP 錯(cuò)誤,并停止處理。 SOAP Fault 元素提供了faultactor 子元素,以指定在消息路徑中哪個(gè)節(jié)點(diǎn)導(dǎo)致了該錯(cuò)誤的發(fā)生。faultactor 屬性的值是一個(gè) URI,用以標(biāo)識(shí)導(dǎo)致該錯(cuò)誤的 SOAP 節(jié)點(diǎn)。
如果 SOAP 節(jié)點(diǎn)成功地處理了一個(gè)標(biāo)頭,則它必須從消息中刪除該標(biāo)頭。 SOAP 節(jié)點(diǎn)可以再插入標(biāo)頭,但是這樣做會(huì)改變合同方 — 它現(xiàn)在處于當(dāng)前節(jié)點(diǎn)與該標(biāo)頭所指向的下一節(jié)點(diǎn)之間。 如果 SOAP 節(jié)點(diǎn)恰好是最終的接收方,則它還必須處理 SOAP 主體。
表 3. SOAP 1.2 角色
SOAP 角色名稱
http://www.w3.org/2002/06/soap-envelope/role/next
http://www.w3.org/2002/06/soap-envelope/role/none
http://www.w3.org/2002/06/soap-envelope/role/ultimateReceiver
說(shuō)明
每個(gè) SOAP 中間節(jié)點(diǎn)和最終的 SOAP 接收方必須 (MUST) 扮演此角色,并可以 (MAY) 另外承擔(dān)零個(gè)或多個(gè)其他 SOAP 角色。
SOAP 節(jié)點(diǎn)絕不可以 (MUST NOT) 扮演此角色。
要將某個(gè) SOAP 節(jié)點(diǎn)確立為最終的接收方,該 SOAP 節(jié)點(diǎn)必須 (MUST) 扮演此角色。 SOAP 中間節(jié)點(diǎn)絕不能 (MUST NOT) 扮演此角色。
返回頁(yè)首
協(xié)議綁定
圖 3中一個(gè)有趣之處是 SOAP 允許通過(guò)多種底層協(xié)議進(jìn)行消息交換。 由于 SOAP 消息處理框架獨(dú)立于底層協(xié)議,每個(gè)中間節(jié)點(diǎn)可以選擇使用不同的通信協(xié)議而不會(huì)影響 SOAP 消息。 然而,為了確保各種 SOAP 應(yīng)用程序和基礎(chǔ)結(jié)構(gòu)之間高級(jí)別的互操作性,標(biāo)準(zhǔn)的協(xié)議綁定是必要的。
一種具體的協(xié)議綁定準(zhǔn)確地定義了應(yīng)該如何利用給定的協(xié)議來(lái)傳輸 SOAP 消息。 換言之,它詳細(xì)定義了 SOAP 如何適用于另一協(xié)議的范圍,該協(xié)議很可能具有自己的消息處理框架以及多種標(biāo)頭。 協(xié)議綁定實(shí)際所定義的內(nèi)容很大程度上取決于該協(xié)議的功能和選項(xiàng)。 例如,針對(duì) TCP 的協(xié)議綁定應(yīng)很大程度不同于針對(duì) MSMQ 或針對(duì) SMTP 的協(xié)議綁定。
SOAP 1.1 規(guī)范僅規(guī)范化了一種用于 HTTP 的協(xié)議綁定(由于 HTTP 的廣泛使用)。 SOAP 已經(jīng)用于 HTTP 之外的很多協(xié)議,但是其實(shí)現(xiàn)并未遵循標(biāo)準(zhǔn)化的綁定。 當(dāng)你嘗試與利用相同協(xié)議的其他 SOAP 實(shí)施進(jìn)行集成時(shí),只要準(zhǔn)備好處理各種互操作性方面的問(wèn)題,超前一點(diǎn)而不使用標(biāo)準(zhǔn)的協(xié)議綁定也未嘗不可。
返回頁(yè)首
HTTP 綁定
HTTP 協(xié)議綁定定義了在 HTTP 上使用 SOAP 的規(guī)則。 SOAP 請(qǐng)求/響應(yīng)自然地映射到 HTTP 請(qǐng)求/協(xié)議模型。 圖 4 說(shuō)明了 SOAP HTTP 綁定的很多細(xì)節(jié)。
圖 4. SOAP HTTP 綁定
HTTP 請(qǐng)求和響應(yīng)消息的 Content-Type 標(biāo)頭都必須設(shè)為 text/xml (在 SOAP 1.2 中是 application/soap+xml)。 對(duì)于請(qǐng)求消息,它必須使用 POST 作為動(dòng)詞,而 URI 應(yīng)該識(shí)別 SOAP 處理器。 SOAP 規(guī)范還定義了一個(gè)名為 SOAPAction 的新 HTTP 標(biāo)頭,所有 SOAP HTTP 請(qǐng)求(即使是空的)都必須包含該標(biāo)頭。 SOAPAction 標(biāo)頭旨在表明該消息的意圖。 對(duì)于 HTTP 響應(yīng),如果沒(méi)有發(fā)生任何錯(cuò)誤,它應(yīng)該使用 200 狀態(tài)碼,如果包含 SOAP 錯(cuò)誤,則應(yīng)使用 500。
返回頁(yè)首
RPC 和編碼
盡管 SOAP 規(guī)范已日漸遠(yuǎn)離對(duì)象,它仍然定義了一種約定,以便利用上述的消息處理框架來(lái)封裝并交換 RPC 調(diào)用。 定義一種標(biāo)準(zhǔn)的方法將 RPC 調(diào)用映射到 SOAP 消息,這使得在運(yùn)行時(shí)基礎(chǔ)結(jié)構(gòu)可以在方法調(diào)用和 SOAP 消息之間自動(dòng)轉(zhuǎn)換,而不用圍繞 Web 服務(wù)平臺(tái)重新設(shè)計(jì)代碼。
要利用 SOAP 進(jìn)行方法調(diào)用,基礎(chǔ)結(jié)構(gòu)需要以下信息:
1.終結(jié)點(diǎn)位置 (URI)
2.方法名稱
3.參數(shù)名稱/值
4.可選的方法簽名
5.可選的標(biāo)頭數(shù)據(jù)
這些信息可以通過(guò)多種方法來(lái)傳輸,包括類型庫(kù)、IDL 文件,或者,更好的是 WSDL 文件。 SOAP RPC 綁定定義了如何在 SOAP 主體中封裝并表示這些信息。 為此,RPC 綁定首先定義如何將方法簽名映射到簡(jiǎn)單的請(qǐng)求/響應(yīng)結(jié)構(gòu),然后將這些結(jié)構(gòu)以 XML 進(jìn)行編碼。 RPC 綁定規(guī)定將以一個(gè)按照方法命名的 struct 來(lái)模擬該方法調(diào)用。 該結(jié)構(gòu)將包含對(duì)應(yīng)于每個(gè) [in] 或 [in/out] 參數(shù)的一個(gè)訪問(wèn)器,訪問(wèn)器的名稱與參數(shù)名相同,其次序由消息簽名確定。 方法響應(yīng)也將作為一個(gè)結(jié)構(gòu)來(lái)建模。 結(jié)構(gòu)的名稱無(wú)關(guān)緊要,盡管約定是使用方法名后跟 "Response"(例如,對(duì)于 add 操作,方法響應(yīng)名應(yīng)該相應(yīng)為 addResponse)。 響應(yīng)結(jié)構(gòu)包含一個(gè)用于返回值的訪問(wèn)器(其名稱在 SOAP 1.1 中無(wú)關(guān)緊要,但在 SOAP 1.2 必須是 rpc:result),其后是針對(duì)每個(gè) [out] 或 [in/out] 參數(shù)的訪問(wèn)器。
讓我們來(lái)看一個(gè)示例。 假設(shè) add 操作具有以下的 C# 方法簽名:
double add(ref double x, double y)
根據(jù)剛才所說(shuō)明的 RPC 綁定規(guī)則,代表該方法調(diào)用的請(qǐng)求結(jié)構(gòu)應(yīng)如下建模:
struct add {double x;double y;}
而響應(yīng)結(jié)構(gòu)如下:
struct addResponse {double result;double x;}
現(xiàn)在的問(wèn)題是: 應(yīng)該如何將這些結(jié)構(gòu)映射到 XML(R) SOAP 規(guī)范定義了一組編碼規(guī)則,專門用于此用途。 SOAP 編碼規(guī)則大致闡述了如何將當(dāng)今最常用的數(shù)據(jù)結(jié)構(gòu)(如結(jié)構(gòu)和數(shù)組)映射到普通的 XML 格式。 根據(jù) SOAP 編碼規(guī)則,以上的請(qǐng)求結(jié)構(gòu)應(yīng)映射到以下 XML 消息(這將放在 SOAP 主體中):
<add><x>33</x><y>44</y></add>
且上述請(qǐng)求的響應(yīng)消息將映射到以下 XML 消息(這個(gè)消息將進(jìn)入響應(yīng)消息的主體):
<addResponse><result>77</result><x>33</x></addResponse>
XML 架構(gòu)的相關(guān)工作剛剛開(kāi)始,SOAP 編碼規(guī)則即已創(chuàng)立。 既然 XML 架構(gòu)已經(jīng)完成,開(kāi)發(fā)人員可以簡(jiǎn)單地提供文字的 XML 架構(gòu)定義,從而準(zhǔn)確指定應(yīng)該如何以 XML 來(lái)格式化請(qǐng)求/響應(yīng)消息。 由于利用 XML 架構(gòu)定義更易于獲得互操作性,因此大多數(shù)開(kāi)發(fā)人員已經(jīng)決定完全摒棄 SOAP 編碼規(guī)則。 實(shí)際上,自 SOAP 1.2 起,SOAP 規(guī)范不再正式要求支持 SOAP 編碼規(guī)則。 從現(xiàn)在起,最好避免使用 SOAP 編碼規(guī)則,有關(guān)此中原由的全面討論,請(qǐng)查看關(guān)于 SOAP 編碼的討論一文。
盡管 SOAP RPC 綁定和編碼規(guī)則為那些不愿意涉及諸如 XML 架構(gòu)和 WSDL 等的應(yīng)用程序提供了一個(gè)很好的 SOAP 集成層,因?yàn)?RPC 綁定和編碼規(guī)則易于導(dǎo)致互操作性方面的問(wèn)題,它們基本上已經(jīng)失寵于 Web 服務(wù)社區(qū)。
返回頁(yè)首
SOAP 類型
要重申的是,如今有兩種基本類型的 SOAP 消息處理: 文檔和 RPC。 文檔類型指出主體只是包含一個(gè) XML 文檔,而發(fā)送方和接收方都必須遵循該文檔的格式。 另一方面,RPC 類型指出主體中包含某個(gè)方法調(diào)用的 XML 表示,正如剛才所述。
兩種方法可用于確定如何將數(shù)據(jù)序列化到主體中: 使用文字的 XML 架構(gòu)定義和使用 SOAP 編碼規(guī)則。 利用前一種方法,架構(gòu)定義逐字確定了主體的 XML 格式,不具有二義性。 然而,利用后一種方法,SOAP 處理器必須在運(yùn)行時(shí)遍歷各種 SOAP 編碼規(guī)則以確定主體正確的序列化。 很顯然,這種方法更易于導(dǎo)致錯(cuò)誤和互操作性方面的問(wèn)題。
最常見(jiàn)的情形是在使用文檔類型時(shí)也使用文字架構(gòu)定義(稱為文檔/文字),以及在使用 SOAP 編碼規(guī)則時(shí)使用 RPC 類型(稱為 rpc/編碼)。 文檔/編碼和 rpc/文字也是可能的,但并不常見(jiàn),也沒(méi)有太大意義。 大多數(shù) Web 服務(wù)平臺(tái)都集中于文檔/文字類型,將其作為發(fā)展的主要用例,且是現(xiàn)今 Microsoft ASP.NET WebMethod 框架的默認(rèn)設(shè)置。
返回頁(yè)首
小結(jié)
SOAP 定義了一種簡(jiǎn)單而可擴(kuò)展的 XML 消息處理框架,它可以通過(guò)多種協(xié)議用于各種不同的編程模型,盡管此規(guī)范中規(guī)范化了如何將 SOAP 用于 HTTP 和 RPC 調(diào)用。 SOAP 還定義了一個(gè)完整的處理模型,大致規(guī)定了當(dāng)消息沿路徑傳送時(shí)如何對(duì)其進(jìn)行處理。 總的來(lái)說(shuō),SOAP 提供了一個(gè)功能豐富而靈活的框架以便定義高級(jí)應(yīng)用程序協(xié)議,這些協(xié)議可在分布式異構(gòu)環(huán)境中提供更好的互操作性。
本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)。
打開(kāi)APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
SOAP協(xié)議是什么
SOAP Header 元素
WebService工作原理
SOAP凈化有線協(xié)議(一):SOAP基礎(chǔ)知識(shí)
中華網(wǎng)校-WSDL文件詳解(上)
使用Soap消息調(diào)用Web Services
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服