SOAP 快速指南



什麼是 SOAP?

SOAP 是簡單物件訪問協議 (Simple Object Access Protocol) 的縮寫。它是一個基於 XML 的訊息協議,用於在計算機之間交換資訊。SOAP 是 XML 規範的一個應用。

要點

  • SOAP 是一種旨在透過網際網路進行通訊的通訊協議。

  • SOAP 可以擴充套件 HTTP 用於 XML 訊息傳遞。

  • SOAP 為 Web 服務提供資料傳輸。

  • SOAP 可以交換完整的文件或呼叫遠端過程。

  • SOAP 可用於廣播訊息。

  • SOAP 與平臺和語言無關。

  • SOAP 是定義傳送什麼資訊以及如何傳送資訊的 XML 方法。

  • SOAP 使客戶端應用程式能夠輕鬆連線到遠端服務並呼叫遠端方法。

儘管 SOAP 可用於各種訊息系統,並可以透過各種傳輸協議進行傳輸,但 SOAP 的最初重點是透過 HTTP 傳輸的遠端過程呼叫。

包括 CORBA、DCOM 和 Java RMI 在內的其他框架提供與 SOAP 相似的功能,但 SOAP 訊息完全是用 XML 編寫的,因此具有獨特的平臺和語言無關性。

SOAP - 訊息結構

SOAP 訊息是一個普通的 XML 文件,包含以下元素:

  • 信封 (Envelope) - 定義訊息的開始和結束。這是一個必填元素。

  • 頭部 (Header) - 包含訊息的任何可選屬性,這些屬性用於處理訊息,無論是在中間點還是在最終端點。這是一個可選元素。

  • 主體 (Body) - 包含構成正在傳送的訊息的 XML 資料。這是一個必填元素。

  • 故障 (Fault) - 一個可選的 Fault 元素,提供有關處理訊息時發生的錯誤的資訊。

所有這些元素都在 SOAP 信封的預設名稱空間中宣告 - http://www.w3.org/2001/12/soap-envelope,SOAP 編碼和資料型別的預設名稱空間是 - http://www.w3.org/2001/12/soap-encoding

注意 - 所有這些規範都可能發生變化。因此,請隨時更新 W3 網站上提供的最新規範。

SOAP 訊息結構

以下程式碼塊描述了 SOAP 訊息的通用結構:

<?xml version = "1.0"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV = "http://www.w3.org/2001/12/soap-envelope" 
   SOAP-ENV:encodingStyle = "http://www.w3.org/2001/12/soap-encoding">

   <SOAP-ENV:Header>
      ...
      ...
   </SOAP-ENV:Header>
   <SOAP-ENV:Body>
      ...
      ...
      <SOAP-ENV:Fault>
         ...
         ...
      </SOAP-ENV:Fault>
      ...
   </SOAP-ENV:Body>
</SOAP_ENV:Envelope>

SOAP - 信封 (Envelope)

SOAP 信封指示訊息的開始和結束,以便接收者知道何時已收到整條訊息。SOAP 信封解決了知道何時完成接收訊息並準備好處理它的問題。因此,SOAP 信封基本上是一種打包機制。

要點

  • 每個 SOAP 訊息都有一個根 Envelope 元素。

  • Envelope 是 SOAP 訊息的必填部分。

  • 每個 Envelope 元素必須包含且只能包含一個 Body 元素。

  • 如果 Envelope 包含 Header 元素,則它最多隻能包含一個,並且必須作為 Envelope 的第一個子元素出現在 Body 之前。

  • 當 SOAP 版本更改時,Envelope 也會更改。

  • SOAP 信封使用 *ENV* 名稱空間字首和 Envelope 元素指定。

  • 可選的 SOAP 編碼也使用名稱空間名稱和可選的 *encodingStyle* 元素指定,該元素也可以指向除 SOAP 編碼之外的其他編碼樣式。

  • 符合 v1.1 的 SOAP 處理器在接收到包含 v1.2 信封名稱空間的訊息時會生成故障。

  • 符合 v1.2 的 SOAP 處理器如果接收到不包含 v1.2 信封名稱空間的訊息,則會生成 *VersionMismatch* 故障。

符合 v1.2 的 SOAP 訊息

下面是一個符合 v1.2 的 SOAP 訊息示例。

<?xml version = "1.0"?>
<SOAP-ENV:Envelope 
   xmlns:SOAP-ENV = "http://www.w3.org/2001/12/soap-envelope" 
   SOAP-ENV:encodingStyle = " http://www.w3.org/2001/12/soap-encoding">
   ...
   Message information goes here
   ...
</SOAP-ENV:Envelope>

使用 HTTP POST 的 SOAP

以下示例說明了在 HTTP POST 操作中使用 SOAP 訊息的情況,該操作將訊息傳送到伺服器。它顯示了信封模式定義和編碼規則模式定義的名稱空間。HTTP 標頭中的 *OrderEntry* 引用是要在 tutorialspoint.com 網站上呼叫的程式的名稱。

POST /OrderEntry HTTP/1.1
Host: www.tutorialspoint.com
Content-Type: application/soap; charset = "utf-8"
Content-Length: nnnn

<?xml version = "1.0"?>
<SOAP-ENV:Envelope 
   xmlns:SOAP-ENV = "http://www.w3.org/2001/12/soap-envelope" 
   SOAP-ENV:encodingStyle = " http://www.w3.org/2001/12/soap-encoding">
   ...
   Message information goes here
   ...
</SOAP-ENV:Envelope>

注意 - HTTP 繫結指定服務的地址。

SOAP - 頭部 (Header)

可選的 Header 元素提供了一個靈活的框架,用於指定其他應用程式級需求。例如,Header 元素可用於為密碼保護的服務指定數字簽名。同樣,它可用於為按次付費的 SOAP 服務指定帳號。

要點

  • 它是 SOAP 訊息的可選部分。

  • Header 元素可以多次出現。

  • Header 的目的是新增新的特性和功能。

  • SOAP 頭部包含在名稱空間中定義的頭部條目。

  • 頭部被編碼為 SOAP 信封的第一個直接子元素。

  • 當定義多個頭部時,SOAP 頭部的所有直接子元素都解釋為 SOAP 頭部塊。

SOAP 頭部屬性

SOAP 頭部可以具有以下兩個屬性:

Actor 屬性

SOAP 協議將訊息路徑定義為 SOAP 服務節點列表。這些中間節點中的每一個都可以執行一些處理,然後將訊息轉發到鏈中的下一個節點。透過設定 Actor 屬性,客戶端可以指定 SOAP 頭部的接收者。

MustUnderstand 屬性

它指示 Header 元素是可選的還是必須的。如果設定為 true,則接收者必須根據其定義的語義理解和處理 Header 屬性,否則返回故障。

以下示例顯示如何在 SOAP 訊息中使用 Header。

<?xml version = "1.0"?>
<SOAP-ENV:Envelope 
   xmlns:SOAP-ENV = " http://www.w3.org/2001/12/soap-envelope"   
   SOAP-ENV:encodingStyle = " http://www.w3.org/2001/12/soap-encoding">

   <SOAP-ENV:Header>
      <t:Transaction 
         xmlns:t = "https://tutorialspoint.tw/transaction/" 
         SOAP-ENV:mustUnderstand = "true">5
      </t:Transaction>
   </SOAP-ENV:Header>
   ...
   ...
</SOAP-ENV:Envelope>

SOAP - 主體 (Body)

SOAP 主體是一個必填元素,它包含在 SOAP 訊息中交換的應用程式定義的 XML 資料。主體必須包含在信封中,並且必須遵循為訊息定義的任何頭部。

主體定義為信封的子元素,主體的語義在關聯的 SOAP 模式中定義。

主體包含打算用於訊息最終接收者的必填資訊。例如:

<?xml version = "1.0"?>
<SOAP-ENV:Envelope>
   ........
   <SOAP-ENV:Body>
      <m:GetQuotation xmlns:m = "http://www.tp.com/Quotation">
         <m:Item>Computers</m:Item>
      </m:GetQuotation>
   </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

上面的示例請求計算機套裝的報價。請注意,上面的 m:GetQuotation 和 Item 元素是特定於應用程式的元素。它們不是 SOAP 標準的一部分。

以下是上述查詢的響應:

<?xml version = "1.0"?>
<SOAP-ENV:Envelope>
   ........
   <SOAP-ENV:Body>
      <m:GetQuotationResponse xmlns:m = "http://www.tp.com/Quotation">
         <m:Quotation>This is Qutation</m:Quotation>
      </m:GetQuotationResponse>
   </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

通常,應用程式還定義一個模式來包含與請求和響應元素相關的語義。

*Quotation* 服務可以使用在應用程式伺服器中執行的 EJB 來實現;如果是這樣,SOAP 處理器將負責將主體資訊作為引數對映到 *GetQuotationResponse* 服務的 EJB 實現中和從中映射出來。SOAP 處理器還可以將主體資訊對映到 .NET 物件、CORBA 物件、COBOL 程式等等。

SOAP - 故障 (Fault)

如果在處理過程中發生錯誤,則對 SOAP 訊息的響應是訊息主體中的 SOAP fault 元素,並且 fault 會返回給 SOAP 訊息的傳送者。

SOAP fault 機制返回有關錯誤的特定資訊,包括預定義的程式碼、描述和生成 fault 的 SOAP 處理器的地址。

要點

  • SOAP 訊息只能攜帶一個 fault 塊。

  • Fault 是 SOAP 訊息的可選部分。

  • 對於 HTTP 繫結,成功的響應與 200 到 299 範圍的狀態程式碼相關聯。

  • SOAP Fault 與 500 到 599 範圍的狀態程式碼相關聯。

Fault 的子元素

SOAP Fault 具有以下子元素:

序號 子元素和描述
1

<faultCode>

它是一個文字程式碼,用於指示一類錯誤。請參閱下表以獲取預定義故障程式碼的列表。

2

<faultString>

它是一個解釋錯誤的文字訊息。

3

<faultActor>

它是一個文字字串,指示誰導致了故障。如果 SOAP 訊息透過 SOAP 訊息路徑中的多個節點傳輸,並且客戶端需要知道哪個節點導致了錯誤,這將非常有用。不充當最終目標的節點必須包含 *faultActor* 元素。

4

<detail>

它是一個用於攜帶特定於應用程式的錯誤訊息的元素。detail 元素可以包含稱為 detail 條目的子元素。

SOAP 故障程式碼

在描述故障時,必須在 *faultcode* 元素中使用以下定義的 faultCode 值。

序號 錯誤和描述
1

SOAP-ENV:VersionMismatch

找到 SOAP Envelope 元素的無效名稱空間。

2

SOAP-ENV:MustUnderstand

Header 元素的直接子元素,其 mustUnderstand 屬性設定為“1”,未被理解。

3

SOAP-ENV:Client

訊息格式不正確或包含不正確的資訊。

4

SOAP-ENV:Server

伺服器出現問題,因此訊息無法繼續。

SOAP 故障示例

以下程式碼是一個示例 Fault。客戶端請求了一個名為 *ValidateCreditCard* 的方法,但服務不支援此方法。這表示客戶端請求錯誤,伺服器返回以下 SOAP 響應:

<?xml version = '1.0' encoding = 'UTF-8'?>
<SOAP-ENV:Envelope
   xmlns:SOAP-ENV = "http://schemas.xmlsoap.org/soap/envelope/"
   xmlns:xsi = "http://www.w3.org/1999/XMLSchema-instance"
   xmlns:xsd = "http://www.w3.org/1999/XMLSchema">

   <SOAP-ENV:Body>
      <SOAP-ENV:Fault>
         <faultcode xsi:type = "xsd:string">SOAP-ENV:Client</faultcode>
         <faultstring xsi:type = "xsd:string">
            Failed to locate method (ValidateCreditCard) in class (examplesCreditCard) at
               /usr/local/ActivePerl-5.6/lib/site_perl/5.6.0/SOAP/Lite.pm line 1555.
         </faultstring>
      </SOAP-ENV:Fault>
   </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

SOAP - 編碼

SOAP 包含一組內建規則,用於編碼資料型別。它使 SOAP 訊息能夠指示特定資料型別,例如整數、浮點數、雙精度數或陣列。

  • SOAP 資料型別分為兩大類:標量型別和複合型別。

  • 標量型別恰好包含一個值,例如姓氏、價格或產品描述。

  • 複合型別包含多個值,例如採購訂單或股票報價列表。

  • 複合型別進一步細分為陣列和結構。

  • SOAP 訊息的編碼樣式透過 *SOAP-ENV:encodingStyle* 屬性設定。

  • 要使用 SOAP 1.1 編碼,請使用值 http://schemas.xmlsoap.org/soap/encoding/

  • 要使用 SOAP 1.2 編碼,請使用值 http://www.w3.org/2001/12/soap-encoding

  • 最新的SOAP規範採用了XML Schema定義的所有內建型別。但是,SOAP仍然保持其自身約定來定義XML Schema未標準化的結構,例如陣列和引用。

標量型別

對於標量型別,SOAP採用XML Schema規範指定的所有內建簡單型別。這包括字串、浮點數、雙精度浮點數和整數。

下表列出了主要簡單型別,摘自XML Schema Part 0 − Primer http://www.w3.org/TR/2000/WD-xmlschema-0-20000407/

XML Schema內建的簡單型別
簡單型別 示例
string 確認這是電動的。
boolean true, false, 1, 0。
float -INF, -1E4, -0, 0, 12.78E-2, 12, INF, NaN。
double -INF, -1E4, -0, 0, 12.78E-2, 12, INF, NaN。
decimal -1.23, 0, 123.4, 1000.00.
binary 100010
integer -126789, -1, 0, 1, 126789.
nonPositiveInteger -126789, -1, 0.
negativeInteger -126789, -1.
long -1, 12678967543233
int -1, 126789675
short -1, 12678
byte -1, 126
nonNegativeInteger 0, 1, 126789
unsignedLong 0, 12678967543233
unsignedInt 0, 1267896754
unsignedShort 0, 12678
unsignedByte 0, 126
positiveInteger 1, 126789.
date 1999-05-31, ---05.
time 13:20:00.000, 13:20:00.000-05:00

例如,這是一個帶有雙精度浮點數資料型別的SOAP響應:

<?xml version = '1.0' encoding = 'UTF-8'?>
<SOAP-ENV:Envelope 
   xmlns:SOAP-ENV = "http://www.w3.org/2001/12/soap-envelope"
   xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" 
   xmlns:xsd = "http://www.w3.org/2001/XMLSchema">
   
   <SOAP-ENV:Body>
      <ns1:getPriceResponse 
         xmlns:ns1 = "urn:examples:priceservice"  
         SOAP-ENV:encodingStyle = "http://www.w3.org/2001/12/soap-encoding">
         <return xsi:type = "xsd:double">54.99</return>
      </ns1:getPriceResponse>
   </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

複合型別

SOAP陣列有一套非常具體的規則,要求您同時指定元素型別和陣列大小。SOAP也支援多維陣列,但並非所有SOAP實現都支援多維功能。

要建立陣列,必須將其指定為陣列的xsi:type。陣列還必須包含一個arrayType屬性。此屬性是必需的,用於指定所包含元素的資料型別和陣列的維度。

例如,以下屬性指定了一個包含10個雙精度浮點數值的陣列:

arrayType = "xsd:double[10]"

相反,以下屬性指定了一個二維字串陣列:

arrayType = "xsd:string[5,5]"

這是一個包含雙精度浮點數陣列的SOAP響應示例:

<?xml version = '1.0' encoding = 'UTF-8'?>
<SOAP-ENV:Envelope
   xmlns:SOAP-ENV = "http://www.w3.org/2001/12/soap-envelope" 
   xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" 
   xmlns:xsd = "http://www.w3.org/2001/XMLSchema">

   <SOAP-ENV:Body>
      <ns1:getPriceListResponse 
         xmlns:ns1 = "urn:examples:pricelistservice"  
         SOAP-ENV:encodingStyle = "http://www.w3.org/2001/12/soap-encoding">

         <return xmlns:ns2 = "http://www.w3.org/2001/09/soap-encoding"  
            xsi:type = "ns2:Array" ns2:arrayType = "xsd:double[2]">
            <item xsi:type = "xsd:double">54.99</item>
            <item xsi:type = "xsd:double">19.99</item>
         </return>
      </ns1:getPriceListResponse>
   </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

結構體包含多個值,但每個元素都用唯一的訪問器元素指定。例如,考慮產品目錄中的一個專案。在這種情況下,結構體可能包含產品SKU、產品名稱、描述和價格。以下是這種結構體在SOAP訊息中的表示方式:

<?xml version = '1.0' encoding = 'UTF-8'?>
<SOAP-ENV:Envelope 
   xmlns:SOAP-ENV = "http://www.w3.org/2001/12/soap-envelope"
   xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" 
   xmlns:xsd = "http://www.w3.org/2001/XMLSchema">

   <SOAP-ENV:Body>
      <ns1:getProductResponse
         xmlns:ns1 = "urn:examples:productservice" 
         SOAP-ENV:encodingStyle = "http://www.w3.org/2001/12/soap-encoding">
		
         <return xmlns:ns2 = "urn:examples" xsi:type = "ns2:product">
            <name xsi:type = "xsd:string">Red Hat Linux</name>
            <price xsi:type = "xsd:double">54.99</price>
            <description xsi:type = "xsd:string">
               Red Hat Linux Operating System
            </description>
            <SKU xsi:type = "xsd:string">A358185</SKU>
         </return>
      </ns1:getProductResponse>
   </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

注意 -編寫SOAP程式碼時,請注意正確的縮排。結構體中的每個元素都用唯一的訪問器名稱指定。例如,上面的訊息包含四個訪問器元素:名稱、價格、描述和SKU。每個元素可以有自己的資料型別。例如,名稱指定為字串,而價格指定為雙精度浮點數。

SOAP - 傳輸

SOAP不依賴於任何傳輸協議。SOAP可以透過SMTP、FTP、IBM的MQSeries或Microsoft訊息佇列(MSMQ)傳輸。

SOAP規範只包含HTTP的詳細資訊。HTTP仍然是最流行的SOAP傳輸協議。

透過HTTP的SOAP

SOAP請求透過HTTP請求傳送,SOAP響應在HTTP響應的內容中返回,這是很符合邏輯的。雖然SOAP請求可以透過HTTP GET傳送,但規範只包含HTTP POST的詳細資訊。

此外,HTTP請求和響應都必須將其內容型別設定為text/xml。

SOAP規範要求客戶端必須提供一個SOAPAction標頭,但SOAPAction標頭的實際值取決於SOAP伺服器的實現。

例如,要訪問由XMethods託管的AltaVista BabelFish翻譯服務,必須將以下內容指定為SOAPAction標頭。

urn:xmethodsBabelFish#BabelFish

即使伺服器不需要完整的SOAPAction標頭,客戶端也必須指定一個空字串("")或空值。例如:

SOAPAction: ""
SOAPAction:

這是一個透過HTTP傳送到XMethods Babelfish翻譯服務的請求示例:

POST /perl/soaplite.cgi HTTP/1.0
Host: services.xmethods.com
Content-Type: text/xml; charset = utf-8
Content-Length: 538
SOAPAction: "urn:xmethodsBabelFish#BabelFish"

<?xml version = '1.0' encoding = 'UTF-8'?>
<SOAP-ENV:Envelope 
   xmlns:SOAP-ENV = "http://schemas.xmlsoap.org/soap/envelope/" 
   xmlns:xsi = "http://www.w3.org/1999/XMLSchema-instance"
   xmlns:xsd = "http://www.w3.org/1999/XMLSchema">

   <SOAP-ENV:Body>
      <ns1:BabelFish
         xmlns:ns1 = "urn:xmethodsBabelFish"
         SOAP-ENV:encodingStyle = "http://schemas.xmlsoap.org/soap/encoding/">
         <translationmode xsi:type = "xsd:string">en_fr</translationmode>
         <sourcedata xsi:type = "xsd:string">Hello, world!</sourcedata>
      </ns1:BabelFish>
   </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

請注意內容型別和SOAPAction標頭。還要注意,BabelFish方法需要兩個字串引數。翻譯模式en_fr將英語翻譯成法語。

以下是來自XMethods的響應:

HTTP/1.1 200 OK
Date: Sat, 09 Jun 2001 15:01:55 GMT
Server: Apache/1.3.14 (Unix) tomcat/1.0 PHP/4.0.1pl2
SOAPServer: SOAP::Lite/Perl/0.50
Cache-Control: s-maxage = 60, proxy-revalidate
Content-Length: 539
Content-Type: text/xml

<?xml version = "1.0" encoding = "UTF-8"?>
<SOAP-ENV:Envelope
   xmlns:SOAP-ENC = "http://schemas.xmlsoap.org/soap/encoding/"
   SOAP-ENV:encodingStyle = "http://schemas.xmlsoap.org/soap/encoding/"
   xmlns:xsi = "http://www.w3.org/1999/XMLSchema-instance"
   xmlns:SOAP-ENV = "http://schemas.xmlsoap.org/soap/envelope/"
   xmlns:xsd = "http://www.w3.org/1999/XMLSchema">
   
   <SOAP-ENV:Body>
      <namesp1:BabelFishResponse xmlns:namesp1 = "urn:xmethodsBabelFish">
         <return xsi:type = "xsd:string">Bonjour, monde!</return>
      </namesp1:BabelFishResponse>
   </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

透過HTTP交付的SOAP響應必須遵循相同的HTTP狀態程式碼。例如,狀態程式碼200 OK表示成功響應。狀態程式碼500內部伺服器錯誤表示存在伺服器錯誤,並且SOAP響應包含一個Fault元素。

SOAP - 示例

在下面的示例中,一個GetQuotation請求透過HTTP傳送到SOAP伺服器。請求具有一個QuotationName引數,響應中將返回一個報價。

函式的名稱空間在http://www.xyz.org/quotation地址中定義。

這是SOAP請求:

POST /Quotation HTTP/1.0
Host: www.xyz.org
Content-Type: text/xml; charset = utf-8
Content-Length: nnn

<?xml version = "1.0"?>
<SOAP-ENV:Envelope
   xmlns:SOAP-ENV = "http://www.w3.org/2001/12/soap-envelope"
   SOAP-ENV:encodingStyle = "http://www.w3.org/2001/12/soap-encoding">

   <SOAP-ENV:Body xmlns:m = "http://www.xyz.org/quotations">
      <m:GetQuotation>
         <m:QuotationsName>MiscroSoft</m:QuotationsName>
      </m:GetQuotation>
   </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

相應的SOAP響應如下所示:

HTTP/1.0 200 OK
Content-Type: text/xml; charset = utf-8
Content-Length: nnn

<?xml version = "1.0"?>
<SOAP-ENV:Envelope
   xmlns:SOAP-ENV = "http://www.w3.org/2001/12/soap-envelope"
   SOAP-ENV:encodingStyle = "http://www.w3.org/2001/12/soap-encoding">

   <SOAP-ENV:Body xmlns:m = "http://www.xyz.org/quotation">
      <m:GetQuotationResponse>
         <m:Quotation>Here is the quotation</m:Quotation>
      </m:GetQuotationResponse>
   </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

SOAP - 標準

SOAP 1.1最初於2000年5月提交給W3C。正式提交者包括微軟、IBM和Ariba等大型公司,以及UserLand Software和DevelopMentor等小型公司。

2001年7月,XML協議工作組釋出了SOAP 1.2的“工作草案”。在W3C中,此文件正式處於開發中,這意味著在最終確定之前,該文件可能會多次更新。

SOAP 1.1版本可在網上獲得:http://www.w3.org/TR/SOAP/

SOAP 1.2版本的工作草案可在以下網址獲得:http://www.w3.org/TR/soap12/

請注意,W3C還託管了“帶有附件的SOAP訊息”的提交內容,該內容與核心SOAP規範分離。此規範使SOAP訊息能夠包含二進位制附件,例如影像和聲音檔案。有關完整詳細資訊,請參閱W3C註釋:http://www.w3.org/TR/SOAP-attachments

廣告