本文是一個由四篇文章組成的系列的第三篇(請參閱 參考資料),本系列文章旨在介紹創(chuàng)建、描述和發(fā)布 Web 服務(wù)的過程。在第一部分中,我借助 WSDL 編制示例講解了如何描述一個 Web 服務(wù)。在第二部分中,我討論了 SOAP 的體系結(jié)構(gòu)及其語義。在本文中,我將看一看與 SOAP 相關(guān)的互操作性問題。
Web 服務(wù)模型將整個 B2B 領(lǐng)域分成三個步驟或三個域:描述一個服務(wù)、將該服務(wù)與具體的實現(xiàn)綁定,然后通過注冊中心發(fā)布該服務(wù)。這三個步驟彼此獨立,會引發(fā)各自的互操作性問題。
WSDL(Web 服務(wù)描述語言(Web Services Description Language))構(gòu)成描述域,SOAP 覆蓋綁定域,統(tǒng)一描述、發(fā)現(xiàn)和集成(Universal Description, Discovery and Integration,UDDI)注冊中心覆蓋發(fā)布域。我在這部分的討論將僅限于與綁定域相關(guān)的互操作性問題。我將從討論 SOAP 的發(fā)展入手,接著討論實際的 SOAP 互操作性問題。
SOAP 版本的發(fā)展
1999 年,當(dāng) XML Schema 規(guī)范仍在發(fā)展中且被視為 SOAP 規(guī)范的關(guān)鍵部分的時候,W3C 就開始了關(guān)于 SOAP 規(guī)范的工作。SOAP 使用 XML Schema 數(shù)據(jù)類型定義來定義并實例化 SOAP 中的數(shù)據(jù)類型。
2000 年 5 月,SOAP 1.1 作為 W3C 紀(jì)要發(fā)行( 參考資料)。這是來自 Microsoft、IBM、Lotus Development 和 UserLand Software, Inc. 的開發(fā)人員共同努力的成果。SOAP 1.1 采用帶有 1999 名稱空間 URI( "http://www.w3.org/1999/XMLSchema")的 XML Schema 工作草案。目前,SOAP 1.2( 參考資料)已經(jīng)很接近于成為候選推薦,而且它已經(jīng)采用了 XML Schema 推薦(2001 年 5 月)和 XML Schema 的 2001 名稱空間 URI( "http://www.w3.org/2001/XMLSchema")。
互操作性問題
我將從基于傳輸(HTTP)的 SOAP 互操作性問題入手。
1. 傳輸
SOAP 1.1 規(guī)范允許在 HTTP 請求中發(fā)送 SOAP 消息。如同第 2 部分( 參考資料)中所描述的,SOAP 與 HTTP 集成并不會影響 SOAP 的語義。SOAP 規(guī)范將必選的 SOAPAction 頭添加到 HTTP 請求頭中。我在前一篇文章中已經(jīng)描述過, SOAPAction 頭的合法取值有三種:
它可以為空
它可以是一個用引號括起來的空字符串
它還可以是一個任意的 URI
這種靈活性使 SOAP 實現(xiàn)能夠選擇它們自己的 SOAPAction 樣式及其功能。但是這種靈活性已經(jīng)引發(fā)了互操作性問題。
為了研究這些互操作性問題,我創(chuàng)建了一個 SOAP 客戶機( 參考資料),該客戶機向 SOAP 服務(wù)器(由 URL 參數(shù)指定的)發(fā)送一個請求并且在接收到時顯示服務(wù)器響應(yīng)。我在更改 SOAPAction 頭的值之后將簡單的 SOAP 請求發(fā)送給不同的服務(wù)器,從而查看服務(wù)器如何支持 SOAP 1.1 規(guī)范所允許的三種頭。
除 SOAPAction 頭(這個頭由我操作)外,我的測試均按照 SOAPBuilders 的第 2 輪(基本)echoString 測試(SOAPBuilders' Round 2 (Base) echoString test)( 參考資料)進行。您應(yīng)該訪問 SOAPBuilders 的第 2 輪測試站點以獲得 WSDL 文件(基本測試),該文件描述了我在執(zhí)行測試期間將調(diào)用的測試 Web 服務(wù)。
被測試的 SOAP 服務(wù)器
我在本文中測試了下列 SOAP 服務(wù)器:
Apache Axis SOAP Server
Apache SOAP 2.2 Server
WhiteMesa 2.7 SOAP Server
IONA XMLBus
SOAP::Lite
EasySOAP++
4S4C
Microsoft ASP.NET Web Services
我在測試中使用了四個 SOAP 請求。
清單 1 包含了 SOAPAction 頭的值用雙引號括起來的 SOAP 請求。 SOAPAction 頭的值與 WSDL 文件中給定的值( "http://soapinterop.org/")一樣。
清單 2 包含了相同的 SOAPAction 頭值,但是沒有雙引號( http://soapinterop.org/)。
清單 3 包含了一個與 WSDL 文件中給定的頭不同的 SOAPAction 頭( "http://differentfromwsdl.org/")。
清單 4 為 SOAPAction 頭指定了一個空值。
我向 WhiteMesa SOAP Server 2.7 發(fā)送 清單 1,它作出了一個成功響應(yīng),說明 WhiteMesa 可以成功地處理這樣的 SOAPAction 頭。接下來,我向 WhiteMesa 發(fā)送 清單 2,它再次成功地對其進行了處理。最后,當(dāng)我將 SOAPAction 頭的值更改為 "http://differentfromwsdl.org/"( 清單 3)時,WhiteMesa 未能成功處理該請求并返回一個故障響應(yīng)。故障字符串為 “Unrecognized 'SOAPAction' HTTP header received.”。WhiteMesa SOAP Server 2.7 還針對 清單 4 中的請求(其中 SOAPAction 值為空)返回一個故障響應(yīng)。
我還用 IONA XMLBus 和 SOAP::Lite 對清單 1、 3和 4進行了測試,它們成功地處理了 清單 1中的請求,但卻針對清單 3和 4中的請求返回了故障消息。IONA XMLBus 也針對 清單 2(未用雙引號將 URI 引起來)返回了一個故障響應(yīng),指出它期望請求中的 SOAPAction 頭要和 WSDL 文件中定義的 SOAPAction 頭一樣,并且要用雙引號括起來。
接下來,我向 Easy SOAP++ 0.6 發(fā)送清單 1、 3和 4 中的請求,它返回正確的響應(yīng)。不管 SOAPAction 頭的值為何,Apache Axis 和 Apache SOAP 2.2 都返回正確的響應(yīng)。
結(jié)論
為了獲得最大程度的互操作性,我推薦用引號將 SOAPAction 頭的值括起來;這個值應(yīng)該與 WSDL 文件中給定的一致。
2. XML
XML Schema
這一部分描述了各種 SOAP 服務(wù)器對編制 SOAP 請求的過程中所使用的不同的 XML Schema 版本表現(xiàn)出的行為。我將對使用測試客戶機測試不同的 SOAP 服務(wù)器支持的 XML 模式名稱空間 URI 所得到的測試結(jié)果進行分析。
清單 1和 清單 5是完全相同的 SOAP 請求,只是所使用的 XML Schema 版本不同。 清單 1使用 2001 XML Schema URI,而 清單 5使用 1999 URI。我對大量服務(wù)器進行了名稱空間 URI 支持測試,然后發(fā)現(xiàn) IONA XMLBus 不能成功處理 1999 URI,但是卻向使用 2001 URI 的 清單 1中的請求返回了一個成功的響應(yīng)。因此,IONA XMLBus 中的支持被限制為 2001 XML Schema 名稱空間 URI。
我可以有把握地說,2001 URI 將對大多數(shù)實現(xiàn)起作用,但是諸如 IBM SOAP Toolkit 和 Apache SOAP 之類較老的實現(xiàn)仍然廣泛存在,這些實現(xiàn)使用的是 1999 URI。Apache SOAP 2.2 既接收 1999 URI,也接收 2001 URI,但是它在響應(yīng)消息中缺省情況下使用 1999 URI(盡管它確實允許您將其更改為 2001)。因此,您可以預(yù)料到那些僅期待 2001 URI 的客戶機(比如 IONA XMLBus)與早期的 SOAP 實現(xiàn)之間將存在互操作性問題。
結(jié)論
因為 2001 URI 不久就要成為標(biāo)準(zhǔn)(SOAP 1.2 規(guī)范)了,并且它為目前的 SOAP 實現(xiàn)所廣泛支持,所以,對于 XML Schema 名稱空間 URI 來說,最佳做法可能就是在請求中使用 2001 URI 了。
連接類型相關(guān)性與 WSDL 知曉性的比較
SOAP 1.1 允許實現(xiàn)提供有關(guān)消息中包含的數(shù)據(jù)的類型信息。這是對數(shù)據(jù)的文字描述(例如, int 、 string 等)。一些實現(xiàn)依賴該信息來正確地反序列化消息中的數(shù)據(jù)。Apache SOAP 2.2 是那些在連接時需要顯式輸入信息的實現(xiàn)之一(即,數(shù)據(jù)類型信息被作為包含數(shù)據(jù)的元素的一個屬性值提供);否則它就無法反序列化數(shù)據(jù)。
我在第 1 部分( 參考資料)中已經(jīng)討論了 WSDL 文件的語義。WSDL 文件用于描述 Web 服務(wù)。它包含有關(guān) Web 服務(wù)所公開的一些方法以及它們的說明的信息。因為 WSDL 文件包含關(guān)于哪些參數(shù)可以傳遞給一個方法以及期望返回哪些內(nèi)容的信息,這些信息可以被用于反序列化一個調(diào)用方法的 SOAP 請求及其響應(yīng)。因此,WSDL 文件知曉性是上述問題的解決方案;即,正在反序列化一條 SOAP 消息的運行時應(yīng)用程序能夠利用 WSDL 文件中提供的數(shù)據(jù)類型信息。
現(xiàn)在,大多數(shù)實現(xiàn)都是 WSDL 知曉的并且不依賴于連接時的類型化。Apache Axis 無需連接時的類型化就可以處理數(shù)據(jù),White Mesa 2.7 也可以;但是這里就出現(xiàn)了一個互操作性問題。如果元素名稱和 WSDL 文件中指定的不同,White Mesa 2.7 就不能處理這個請求。對于許多其它實現(xiàn)都是如此。但是另一方面,Apache Axis 能夠處理這樣一個請求而不發(fā)出一個故障。所以,如果您為 Apache Axis 編寫一個這樣的請求,它將不會在 White Mesa 2.7 上運行。為服務(wù)編寫遵循 WSDL 文件的請求和響應(yīng)可能是一個更好的做法。這將能處理所有具有 WSDL 知曉性的實現(xiàn)。
3. 數(shù)據(jù)類型
數(shù)據(jù)類型兼容性可能是 SOAP 互操作性中最重要的問題。如果兩個應(yīng)用程序不能理解彼此的數(shù)據(jù)類型,那么它們就不能執(zhí)行有意義的數(shù)據(jù)交換,從而也就不能互操作。
在本系列文章的第二篇文章中已經(jīng)介紹了數(shù)據(jù)類型,我在那篇文章中討論了幾種簡單的數(shù)據(jù)類型和復(fù)雜的數(shù)據(jù)類型。SOAP 使用 XML Schema 數(shù)據(jù)類型和結(jié)構(gòu)來標(biāo)識 SOAP 消息中攜帶的數(shù)據(jù)的類型。
使用 SOAP 進行傳遞的數(shù)據(jù)首先被序列化;即,數(shù)據(jù)值被轉(zhuǎn)換成字符串以在 XML 文檔中傳送。在目的地,這個字符串必須被反序列化,即,被轉(zhuǎn)換成表示原來的值的數(shù)據(jù)類型。
將 XML Schema 數(shù)據(jù)類型映射到適當(dāng)?shù)谋緳C數(shù)據(jù)類型是由 SOAP 實現(xiàn)負(fù)責(zé)的。如果兩個本機數(shù)據(jù)類型不一致,即,此時 XML 中的同一種數(shù)據(jù)類型在不同的實現(xiàn)中有不同的值(因此,也就有不同的含義),就可能產(chǎn)生問題。在序列化和反序列化之后保持?jǐn)?shù)據(jù)的一致是很重要的。我將詳細討論這個問題。
連接類型相關(guān)性與 WSDL 知曉性的比較
SOAP 1.1 允許實現(xiàn)提供有關(guān)消息中包含的數(shù)據(jù)的類型信息。這是對數(shù)據(jù)的文字描述(例如, int 、 string 等)。一些實現(xiàn)依賴該信息來正確地反序列化消息中的數(shù)據(jù)。Apache SOAP 2.2 是那些在連接時需要顯式輸入信息的實現(xiàn)之一(即,數(shù)據(jù)類型信息被作為包含數(shù)據(jù)的元素的一個屬性值提供);否則它就無法反序列化數(shù)據(jù)。
我在第 1 部分( 參考資料)中已經(jīng)討論了 WSDL 文件的語義。WSDL 文件用于描述 Web 服務(wù)。它包含有關(guān) Web 服務(wù)所公開的一些方法以及它們的說明的信息。因為 WSDL 文件包含關(guān)于哪些參數(shù)可以傳遞給一個方法以及期望返回哪些內(nèi)容的信息,這些信息可以被用于反序列化一個調(diào)用方法的 SOAP 請求及其響應(yīng)。因此,WSDL 文件知曉性是上述問題的解決方案;即,正在反序列化一條 SOAP 消息的運行時應(yīng)用程序能夠利用 WSDL 文件中提供的數(shù)據(jù)類型信息。
現(xiàn)在,大多數(shù)實現(xiàn)都是 WSDL 知曉的并且不依賴于連接時的類型化。Apache Axis 無需連接時的類型化就可以處理數(shù)據(jù),White Mesa 2.7 也可以;但是這里就出現(xiàn)了一個互操作性問題。如果元素名稱和 WSDL 文件中指定的不同,White Mesa 2.7 就不能處理這個請求。對于許多其它實現(xiàn)都是如此。但是另一方面,Apache Axis 能夠處理這樣一個請求而不發(fā)出一個故障。所以,如果您為 Apache Axis 編寫一個這樣的請求,它將不會在 White Mesa 2.7 上運行。為服務(wù)編寫遵循 WSDL 文件的請求和響應(yīng)可能是一個更好的做法。這將能處理所有具有 WSDL 知曉性的實現(xiàn)。
Float(浮點)
與 float 有關(guān)的常見問題出現(xiàn)在無窮大的表示上。XML Schema 用字符串 INF表示無窮大。 清單 6在請求中將 INF 作為 float 無窮大發(fā)送,Apache SOAP 2.2 服務(wù)器以 Infinity返回它,而 Apache Axis 則返回 INF( 清單 7)。
我還通過發(fā)送 清單 6 的 SOAP 請求對 MS SOAP Toolkit 3.0 服務(wù)器進行了測試。它返回一個服務(wù)器端的故障代碼,且不能將 float 無窮大值 INF反序列化,如同故障字符串 “SoapMapper:Converting data for SoapMapper failed inside the typemapper”所指出的那樣。
另一個問題與 float 精度支持有關(guān)。我把 1.23456789E38 作為 float 發(fā)送給幾臺 SOAP 服務(wù)器(請參閱 清單 8)。IONA XMLBus 返回 1.23456789E38,White Mesa 2.7 服務(wù)器返回 1.234568E38,而 MS SOAP ToolKit 3.0 服務(wù)器返回 1.23456786051167E+38。盡管這指出了各個實現(xiàn)正在進行互操作的事實,但是這些實現(xiàn)仍然不能將數(shù)據(jù)重新生成為它的原始值。
Decimal(十進制)
對于 decimal ,XML Schema 規(guī)范要求實現(xiàn)要支持的最少位數(shù)是 18 位。因為在規(guī)范中沒有定義上限,所以各個實現(xiàn)可以隨意設(shè)置它們自己的上限。Microsoft ASP.NET Web Services 和 WhiteMesa 2.7 給出的精度最多達 28 位,而 Apache Axis 可以精確支持?jǐn)?shù)百位。這種支持上的差異意味著,當(dāng)一個 Apache Axis 實現(xiàn)向 WhiteMesa 2.7 實現(xiàn)發(fā)送一些大小超過 28 位的 decimal 數(shù)字時,額外的精度將被截斷,從而造成數(shù)據(jù)不一致。
我發(fā)送 清單 9 中的 decimal 數(shù)字請求(該請求帶有一個很大的 decimal 數(shù)字)以了解不同服務(wù)器的精度支持。在清單 10、 11和 12中,可以分別看到來自 ASP.NET 服務(wù)器、Apache Axis 以及 WhiteMesa 2.7 的響應(yīng)。4S4C 服務(wù)器在對 清單 9的響應(yīng)中返回的值為 1.235。
DateTime(日期時間)
XML Schema 中用于時間和日期信息的數(shù)據(jù)類型是 dateTime 。White Mesa 2.7 給出的精度為秒。Apache SOAP 2.2 和 Apache Axis 用 java.util.Date 類表示一個特定的時間實例,精度為毫秒。Microsoft ASP.NET Web Services 使用 Date 類型,該類型可以表示精度為納秒的時間。
現(xiàn)在,如果一個基于 .NET 的 SOAP 客戶機端實現(xiàn)向 SOAP 2.2 實現(xiàn)或 White Mesa 2.7 實現(xiàn)發(fā)送 dateTime 信息, dateTime 中額外的精度將被丟失,從而導(dǎo)致數(shù)據(jù)不一致性。請注意:在 XML Schema 中,精度達到秒是強制性的,而秒的小數(shù)部分則是可選的且合法的。
我用 清單 13 中的請求進行了 dateTime 測試。在清單 14、 15、 16和 17中分別顯示了來自 Microsoft ASP.NET Web Services、Apache Axis、WhiteMesa 2.7 和 SOAP::Lite 的響應(yīng)。
字節(jié)數(shù)組(Byte Array)
SOAP 允許您以字節(jié)數(shù)組的形式交換數(shù)據(jù)。字節(jié)數(shù)組在被放入一個 XML 文檔中之前,它必須是 base64編碼的。許多實現(xiàn)未能通過 SOAPBuilder( 參考資料)的第 2 輪(基本)互操作性測試中的 echoBase64 測試。由于本機數(shù)據(jù)類型格式的差異,一些實現(xiàn)返回的是不一致的值。一些實現(xiàn)通過對已經(jīng)進行 base64 編碼的值進一步進行 base64 編碼來返回值。
清單 18(使用 1999 XML Schema base64Binary 數(shù)據(jù)類型)和 清單 19(使用 2001 Schema base64Binary 數(shù)據(jù)類型)中的請求向 SOAP 服務(wù)器發(fā)送一個簡單的 echoBase64 方法調(diào)用。
Apache SOAP 2.2 在對 清單 18和 清單 19的響應(yīng)中都返回故障消息。該服務(wù)器未能識別兩個例子中的數(shù)據(jù)類型,因此無法反序列化 base 64 編碼的字節(jié)數(shù)組。
請看一下 清單 20,它指定 base64 作為數(shù)據(jù)類型編碼。與 XML Schema 規(guī)范定義的 base64Binary 數(shù)據(jù)類型相比, base64 編碼是由 SOAP 1.1 規(guī)范定義的。Apache SOAP 2.2 成功地處理了 清單 20的請求。
IONA XMLBus 成功地處理了 19,但處理 18(請回顧一下講述 XML Schema 問題的部分,在那部分中,我發(fā)現(xiàn)了 IONA XMLBus 只支持 2001 XML Schema URI)時失敗了。它也無法識別 清單 20 中的請求中的 SOAP-ENC:base64 數(shù)據(jù)類型實例,然后返回一個故障字符串。
從上面的測試中能明顯看出,當(dāng) Apache SOAP 2.2 和 IONAXMLBus 交換 base64 編碼的字節(jié)數(shù)組時,它們之間有互操作性問題。
數(shù)組(Array)
數(shù)組形式的數(shù)據(jù)對實現(xiàn)來說一直是一個困難的測試,尤其是當(dāng)情形復(fù)雜,滿是使用嵌套的數(shù)組、多維數(shù)組以及嵌套結(jié)構(gòu)(struct)的情況時。
struct 是一種復(fù)雜的、用戶定義的數(shù)據(jù)類型,它可以包含簡單的或更復(fù)雜的數(shù)據(jù)類型。具有 C 語言編程經(jīng)驗的讀者可能會想在 C struct 和 XML Schema struct 之間做一個類比。
有無數(shù)種方法可以把一維數(shù)組和多維數(shù)組與其它的數(shù)據(jù)類型結(jié)合在 structs 中。因此,我設(shè)計了大量 SOAP 請求來測試不同 SOAP 服務(wù)器的行為。這些測試遵循 SOAPBuilders 的第 2 輪(B 組)測試套件。您可以在 SOAPBuilders 的第 2 輪 Web 站點上得到 B 組測試的 WSDL 文件。
清單 21 包含了一個簡單的 strings 數(shù)組。
清單 22 包含了一個 structs 數(shù)組。該 struct 包含了一個 string 、一個 float 和一個 int 數(shù)據(jù)類型。
清單 23 包含一個二維的 strings 數(shù)組。
清單 24為二維數(shù)組定義了一個偏移量(這個值定義了應(yīng)該從哪個位置開始處理數(shù)組)。
清單 25 包含了一個 struct ,該 struct 帶有一個嵌套的 strings 數(shù)組。
清單 26包含一個二維數(shù)組,未指定最里面一維的大小。
我所測試的所有 SOAP 實現(xiàn)對于簡單類型和復(fù)雜類型的數(shù)組(即 清單 21和 清單 22)都沒有問題。
用清單 21、 22、 23、 24、 25和 26對 WhiteMesa 2.7 服務(wù)器進行了測試。盡管 只是當(dāng)指定了偏移量(大于零)時,WhiteMesa 2.7 服務(wù)器未能成功處理 清單 25,但它還是成功地處理了所有請求。White Mesa 2.7 就已經(jīng)顯示了在最里面一維的大小未被指定( 清單 26)時能夠處理二維數(shù)組。
我向 SOAP::Lite 發(fā)送 清單 23中的請求,SOAP::Lite 無法處理該請求,它返回一個帶有故障字符串 “Not implemented, because SOAP::Lite does not generate multidimensional arrays (yet accepts ;))”的故障響應(yīng)。 清單 26中的請求能被 WhiteMesa 成功地處理,卻不能被許多其它的實現(xiàn)成功處理;SOAP::Lite 和 Apache Axis 返回故障消息。
結(jié)論
包括數(shù)組以及數(shù)組的不同組合的交換的數(shù)據(jù)交換,對于大多數(shù) SOAP 實現(xiàn)可能是可以的,除了上面我已經(jīng)指出的幾個實現(xiàn)外。為了確保最大程度的互操作性和數(shù)據(jù)一致性,Web 服務(wù)開發(fā)者應(yīng)該編寫全面的數(shù)據(jù)測試,這些測試由期望的數(shù)據(jù)模式的所有可能變體組成,因為那樣做可以找出可以解決的問題并確認(rèn)應(yīng)用程序和數(shù)據(jù)一致性。
雜項
在 SOAP 中,還有其它可能引發(fā)互操作性問題的地方。這些問題可能會因引擎無法處理 mustUnderstand SOAP 頭而顯露出來。可以通過定制頭來擴展 SOAP 功能。這個可擴展性還為最終可能會導(dǎo)致互操作性問題的專有的、非標(biāo)準(zhǔn)的解決方案打開了解決渠道。SOAP 允許使用一些實現(xiàn)(例如,Apache SOAP 2.2)所不支持的多個返回參數(shù)。編碼模式描述了將數(shù)據(jù)序列化到 XML 以及將數(shù)據(jù)從 XML 反序列化時所遵循的規(guī)則。遺憾的是,盡管 SOAP 1.1 確實提議了一個 SOAP 消息的編碼,但是它并沒有為 SOAP 消息指定一個缺省編碼。SOAP 實現(xiàn)者并沒有被該規(guī)范所束縛,不會為了遵循規(guī)范而實現(xiàn)規(guī)范定義的編碼。缺少缺省編碼模式可能會導(dǎo)致互操作性問題。
結(jié)束語
對于那些正在計劃在現(xiàn)在的 SOAP 實現(xiàn)上構(gòu)建 Web 服務(wù)的開發(fā)者,或者那些正在編寫他們自己的 SOAP 服務(wù)器和客戶機的開發(fā)者,現(xiàn)在我可以提供幾點建議。
如果您正在計劃使用 SOAP 1.1 實現(xiàn),請在您的請求中用引號把 SOAPAction 頭括起來,并且要確保它與服務(wù)的 WSDL 文件中的 SOAPAction 頭一致。
請采用 XML Schema 的 2001 名稱空間 URI,因為它現(xiàn)在是事實上的標(biāo)準(zhǔn)。
請遵照 SOAP 1.1 定義的編碼,并請確保您發(fā)送和接收的數(shù)據(jù)確實是以它應(yīng)該的格式進行的。
您的方法元素名稱應(yīng)該遵循 WSDL 描述。
請在 SOAP 消息中提供連接時的數(shù)據(jù)類型信息。
清單 1. SOAPAction 值為 "http://soapinterop.org/" 的 SOAP 請求。
?
POST?/endpoint?HTTP/1.1?
Host:host-URL?
Content-Type:?"text/xml";?Charset="utf-8"?
SOAPAction:?"http://soapinterop.org/"?
<?xml?version="1.0"?encoding="UTF-8"?>?
<SOAP-ENV:Envelope?xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"?
????xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"?
????xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"?
????xmlns:xsd="http://www.w3.org/2001/XMLSchema">?
????<SOAP-ENV:Body>?
????????<ns1:echoString?xmlns:ns1="http://soapinterop.org/">?
????????????<inputString?xsi:type="xsd:string">?
????????????????A?Test?String?
????????????</inputString>?
????????</ns1:echoString>?
????</SOAP-ENV:Body>?
</SOAP-ENV:Envelope>?

清單 2. SOAPAction 值(未加引號的)為 http://soapinterop.org/ 的 SOAP 請求。
POST?/endpoint?HTTP/1.1?
Host:host-URL?
Content-Type:?"text/xml";?Charset="utf-8"?
SOAPAction:?http://soapinterop.org/?
<?xml?version="1.0"?encoding="UTF-8"?>?
<SOAP-ENV:Envelope?xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"?
????xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"?
????xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"?
????xmlns:xsd="http://www.w3.org/2001/XMLSchema">?
????<SOAP-ENV:Body>?
????????<ns1:echoString?xmlns:ns1="http://soapinterop.org/">?
????????????<inputString?xsi:type="xsd:string">?
????????????????A?Test?String?
????????????</inputString>?
????????</ns1:echoString>?
????</SOAP-ENV:Body>?
</SOAP-ENV:Envelope>?


清單 3. SOAPAction 值為 "http://differentfromwsdl.org/" 的 SOAP 請求。
POST?/endpoint?HTTP/1.1?
Host:host-URL?
Content-Type:?"text/xml";?Charset="utf-8"?
SOAPAction:?"http://differentfromwsdl.org/"?
<?xml?version="1.0"?encoding="UTF-8"?>?
<SOAP-ENV:Envelope?xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"?
????xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"?
????xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"?
????xmlns:xsd="http://www.w3.org/2001/XMLSchema">?
????<SOAP-ENV:Body>?
????????<ns1:echoString?xmlns:ns1="http://soapinterop.org/">?
????????????<inputString?xsi:type="xsd:string">?
????????????????A?Test?String?
????????????</inputString>?
????????</ns1:echoString>?
????</SOAP-ENV:Body>?
</SOAP-ENV:Envelope>?

清單 4. SOAPAction 值為空的 SOAP 請求。
POST?/endpoint?HTTP/1.1?
Host:host-URL?
Content-Type:?"text/xml";?Charset="utf-8"?
SOAPAction:?
<?xml?version="1.0"?encoding="UTF-8"?>?
<SOAP-ENV:Envelope?xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"?
????xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"?
????xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"?
????xmlns:xsd="http://www.w3.org/2001/XMLSchema">?
????<SOAP-ENV:Body>?
????????<ns1:echoString?xmlns:ns1="http://soapinterop.org/">?
????????????<inputString?xsi:type="xsd:string">?
????????????????A?Test?String?
????????????</inputString>?
????????</ns1:echoString>?
????</SOAP-ENV:Body>?
</SOAP-ENV:Envelope>?

清單 5. 帶有 XML Schema 的 1999 名稱空間 URI 的 SOAP 請求。
<?xml?version="1.0"?encoding="UTF-8"?>?
<SOAP-ENV:Envelope?xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"?
????xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"?
????xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance"?
????xmlns:xsd="http://www.w3.org/1999/XMLSchema">?
????<SOAP-ENV:Body>?
????????<ns1:echoString?xmlns:ns1="http://soapinterop.org/">?
????????????<inputString?xsi:type="xsd:string">?
????????????????A?Test?String?
????????????</inputString>?
??</ns1:echoString>?
????</SOAP-ENV:Body>?
</SOAP-ENV:Envelope>?


清單 6. “INF”作為 float 無窮大的 SOAP 請求。
<?xml?version="1.0"?encoding="UTF-8"?>?
<SOAP-ENV:Envelope?xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"?
????xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"?
????xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance"?
????xmlns:xsd="http://www.w3.org/1999/XMLSchema">?
????<SOAP-ENV:Body>?
????????<ns1:echoFloat?xmlns:ns1="http://soapinterop.org/">?
????????????<inputFloat?xsi:type="xsd:float">INF</inputFloat>?
????????</ns1:echoFloat>?
????</SOAP-ENV:Body>?
</SOAP-ENV:Envelope>?
清單 7. Apache Axis 服務(wù)器對清單 6 中的請求的響應(yīng)。
<?xml?version="1.0"?encoding="UTF-8"?>?
<SOAP-ENV:Envelope?xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"?
????xmlns:xsd="http://www.w3.org/2001/XMLSchema"?
????xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">?
????<SOAP-ENV:Body>?
????????<ns1:echoFloatResponse?
????????????SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"?
????????????xmlns:ns1="http://soapinterop.org/">?
????????????<echoFloatReturn?xsi:type="xsd:float">INF</echoFloatReturn>?
????????</ns1:echoFloatResponse>?
????</SOAP-ENV:Body>?
</SOAP-ENV:Envelope>?

清單 8. 用于對 SOAP 服務(wù)器進行 float 值測試的 SOAP 請求。
<?xml?version="1.0"?encoding="UTF-8"?>?
<SOAP-ENV:Envelope?xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"?
????xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"?
????xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"?
????xmlns:xsd="http://www.w3.org/2001/XMLSchema">?
????<SOAP-ENV:Body>?
????????<ns1:echoFloat?xmlns:ns1="http://soapinterop.org/">?
????????????<inputFloat?xsi:type="xsd:float">1.23456789E38</inputFloat>?
????????</ns1:echoFloat>?
????</SOAP-ENV:Body>?
</SOAP-ENV:Envelope>?

清單 9. 很大的十進制數(shù)的 SOAP 請求。
<?xml?version="1.0"?encoding="UTF-8"?>?
<SOAP-ENV:Envelope?xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"?
????xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"?
????xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"?
????xmlns:xsd="http://www.w3.org/2001/XMLSchema">?
????<SOAP-ENV:Body>?
????????<ns1:echoDecimal?xmlns:ns1="http://soapinterop.org/">?
????????????<inputDecimal?xsi:type="xsd:decimal">?
????????????????0.123456789123456789123456789123456789?
????????????</inputDecimal>?
????????</ns1:echoDecimal>?
????</SOAP-ENV:Body>?
</SOAP-ENV:Envelope>?

清單 10. 來自 Microsoft 的 ASP.NET Web Services 對清單 9 中的請求的 SOAP 響應(yīng)。
HTTP/1.0?200?OK?
Server:?Microsoft-IIS/5.0?
Date:?Sat,?29?Jun?2002?09:05:39?GMT?
X-Powered-By:?ASP.NET?X-AspNet-Version:?1.0.4221?
Cache-Control:?private,?max-age=0?
Content-Type:?text/xml;?charset=utf-8?
Content-Length:?568?
X-Cache:?MISS?from?cache-L7.wol.net.pk?
Connection:?keep-alive??
<?xml?version="1.0"?encoding="UTF-8"?>?
<soap:Envelope?xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"?
????xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"?
????xmlns:tns="http://soapinterop.org/"?xmlns:types="http://soapinterop.org/"?
????xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"?
????xmlns:xsd="http://www.w3.org/2001/XMLSchema">?
????<soap:Body?
????????soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">?
????????<types:echoDecimalResponse>?
????????????<return?xsi:type="xsd:decimal">?
????????????????0.1234567891234567891234567891?
????????????</return>?
????????</types:echoDecimalResponse>?
????</soap:Body>?
</soap:Envelope>?

清單 11. 來自 Apache Axis 的對清單 9 中的請求的 SOAP 響應(yīng)。
HTTP/1.1?200?OK?
Content-Type:?text/xml;?charset=utf-8?
Date:?Sat,?29?Jun?2002?09:09:07?GMT?
Transfer-Encoding:?chunked?
Server:?Apache?Tomcat/4.0.3?(HTTP/1.1?Connector)?
1fc?
<?xml?version="1.0"?encoding="UTF-8"?>?
<soapenv:Envelope?xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"?
????xmlns:xsd="http://www.w3.org/2001/XMLSchema"?
????xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">?
????<soapenv:Body>?
????????<ns1:echoDecimalResponse?
????????????soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"?
????????????xmlns:ns1="http://soapinterop.org/">?
????????????<return?xsi:type="xsd:decimal">?
????????????????0.123456789123456789123456789123456789?
????????????</return>?
????????</ns1:echoDecimalResponse>?
????</soapenv:Body>?
</soapenv:Envelope>?
0
清單 12. 來自 WhiteMesa 2.7 的對清單 9 中的請求的 SOAP 響應(yīng)。
HTTP/1.0?200?OK?
Date:?Sat,?29?Jun?2002?09:36:29?GMT?
Server:?WhiteMesa?SOAP?Server/2.7?
Content-Type:?text/xml;?charset="utf-8"?
Content-Length:?362?
X-Cache:?MISS?from?cache-L3.wol.net.pk?
Connection:?keep-alive??
<?xml?version="1.0"?encoding="UTF-8"?>?
<SOAP-ENV:Envelope?xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">?
????<SOAP-ENV:Body>?
????????<m:echoDecimalResponse?
????????????SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"?
????????????xmlns:m="http://soapinterop.org/">?
????????????<return>?
????????????????0.1234567891234567891234567891?
????????????</return>?
????????</m:echoDecimalResponse>?
????</SOAP-ENV:Body>?
</SOAP-ENV:Envelope>?

清單 13. SOAP dataTime 數(shù)據(jù)類型請求。
<?xml?version="1.0"?encoding="UTF-8"?>?
<SOAP-ENV:Envelope?
????xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"?
????xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"?
????xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"?
????xmlns:xsd="http://www.w3.org/2001/XMLSchema">?
????<SOAP-ENV:Body>?
????????<ns1:echoDate?xmlns:ns1="http://soapinterop.org/">?
????????????<inputDate?xsi:type="xsd:dateTime">?
????????????????1956-10-18T22:20:00.1234567?
????????????</inputDate>?
????????</ns1:echoDate>?
????</SOAP-ENV:Body>?
</SOAP-ENV:Envelope>?

清單 14. 來自 Microsoft ASP.NET Web Services 的對清單 13 中的請求的響應(yīng)。
HTTP/1.0?200?OK?Server:?Microsoft-IIS/5.0?
Date:?Sat,?29?Jun?2002?07:50:58?GMT?
X-Powered-By:?ASP.NET?X-AspNet-Version:?1.0.4221?
Cache-Control:?private,?max-age=0?
Content-Type:?text/xml;?charset=utf-8?
Content-Length:?566?
X-Cache:?MISS?from?malhitest?
Connection:?keep-alive??
<?xml?version="1.0"?encoding="utf-8"?>?
<SOAP-ENV:Envelope?
????xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"?
????xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"?
????xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"?
????xmlns:xsd="http://www.w3.org/2001/XMLSchema">?
????<SOAP-ENV:Body>?
????????<ns1:echoDate?xmlns:ns1="http://soapinterop.org/">?
????????????<inputDate?xsi:type="xsd:dateTime">?
????????????????1956-10-18T22:20:00.1234567?
????????????</inputDate>?
????????</ns1:echoDate>?
????</SOAP-ENV:Body>?
</SOAP-ENV:Envelope>?

清單 15. 來自 Apache Axis 的對清單 13 中的請求的響應(yīng)。
HTTP/1.1?200?OK?
Content-Type:?text/xml;?charset=utf-8?
Date:?Sat,?29?Jun?2002?09:09:01?GMT?
Transfer-Encoding:?chunked?
Server:?Apache?Tomcat/4.0.3?(HTTP/1.1?Connector)?
1e9?
<?xml?version="1.0"?encoding="utf-8"?>?
<soapenv:Envelope?
????xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"?
????xmlns:xsd="http://www.w3.org/2001/XMLSchema"?
????xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">?
????<soapenv:Body>?
????????<ns1:echoDateResponse?
????????????soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"?
????????????xmlns:ns1="http://soapinterop.org/">?
????????????<return?xsi:type="xsd:dateTime">?
????????????????1956-10-18T22:20:00.123Z?
????????????</return>?
????????</ns1:echoDateResponse>?
????</soapenv:Body>?
</soapenv:Envelope>?
0
清單 16. 來自 WhiteMesa 2.7 的對清單 13 中的請求的響應(yīng)。
HTTP/1.0?200?OK?
Date:?Sat,?29?Jun?2002?09:16:09?GMT?
Server:?WhiteMesa?SOAP?Server/2.7?
Content-Type:?text/xml;?charset="utf-8"?
Content-Length:?346?
X-Cache:?MISS?from?cache-L4.wol.net.pk?
Connection:?keep-alive??
<?xml?version="1.0"?encoding="utf-8"?>?
<SOAP-ENV:Envelope?
????xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">?
????<SOAP-ENV:Body>?
????????<m:echoDateResponse?
????????????SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"?
????????????xmlns:m="http://soapinterop.org/">?
????????????<return>?
????????????????1956-10-18T22:20:00Z?
????????????</return>?
????????</m:echoDateResponse>?
????</SOAP-ENV:Body>?
</SOAP-ENV:Envelope>?

清單 17. 來自 SOAP::Lite 的對清單 13 中的請求的響應(yīng)。
HTTP/1.0?200?OK?
Date:?Sat,?29?Jun?2002?09:17:20?GMT?
Server:?Apache/1.3.26?(Unix)?mod_gzip/1.3.19.1a?mod_ssl/2.8.1?OpenSSL/0.9.4?PHP/4.2.1?
SOAPServer:?SOAP::Lite/Perl/0.55?
Content-Length:?553?
Content-Type:?text/xml;?charset=utf-8?
X-Cache:?MISS?from?cache-L4.wol.net.pk?
Connection:?keep-alive??
<?xml?version="1.0"?encoding="utf-8"?>?
<SOAP-ENV:Envelope?
????xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"?
????xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"?
????xmlns:xsd="http://www.w3.org/2001/XMLSchema"?
????SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"?
????xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">?
????<SOAP-ENV:Body>?
????????<namesp1:echoDateResponse?
????????????xmlns:namesp1="http://soapinterop.org/">?
????????????<return?xsi:type="xsd:dateTime">?
????????????????1956-10-18T22:20:00.1234567?
????????????</return>?
????????</namesp1:echoDateResponse>?
????</SOAP-ENV:Body>?
</SOAP-ENV:Envelope>?

清單 18. 帶有 1999 XML Schema URI 限定的 base64Binary 數(shù)據(jù)類型的 SOAP 請求。
<?xml?version="1.0"?encoding="utf-8"?>?
<SOAP-ENV:Envelope?
????xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"?
????xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"?
????xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance"?
????xmlns:xsd="http://www.w3.org/1999/XMLSchema">?
????????<SOAP-ENV:Body>?
????????????<ns1:echoBase64?
????????????????xmlns:ns1="http://soapinterop.org/">?
????????????????<inputBase64?
????????????????????xsi:type="xsi:base64Binary">?
????????????????????VGhpcyBpcyBhIFRlc3QgU3RyaW5n?
????????????????</inputBase64>?
????????????</ns1:echoBase64>?
????????</SOAP-ENV:Body>?
</SOAP-ENV:Envelope>?

清單 19. 帶有 2001 XML Schema URI 限定的 base64Binary 數(shù)據(jù)類型的 SOAP 請求。
<?xml?version="1.0"?encoding="utf-8"?>?
<SOAP-ENV:Envelope?
????xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"?
????xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"?
????xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"?
????xmlns:xsd="http://www.w3.org/2001/XMLSchema">?
????<SOAP-ENV:Body>?
????????<ns1:echoBase64?
????????????xmlns:ns1="http://soapinterop.org/">?
????????????<inputBase64?
????????????????xsi:type="xsi:base64Binary">?
????????????????VGhpcyBpcyBhIFRlc3QgU3RyaW5n?
????????????</inputBase64>?
????????</ns1:echoBase64>?
????</SOAP-ENV:Body>?
</SOAP-ENV:Envelope>?

清單 20. 帶有 SOAP-ENC 限定的 base64 數(shù)據(jù)類型的 SOAP 請求。
<?xml?version="1.0"?encoding="utf-8"?>?
<SOAP-ENV:Envelope?
????xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"?
????xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"?
????xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance"?
????xmlns:xsd="http://www.w3.org/1999/XMLSchema">?
????<SOAP-ENV:Body>?
????????<ns1:echoBase64?
????????????xmlns:ns1="http://soapinterop.org/">?
????????????<inputBase64?
????????????????xsi:type="SOAP-ENC:base64">?
????????????????VGhpcyBpcyBhIFRlc3QgU3RyaW5n?
????????????</inputBase64>?
????????</ns1:echoBase64>?
????</SOAP-ENV:Body>?
</SOAP-ENV:Envelope>?

清單 21. SOAP 請求中的一個字符串?dāng)?shù)組。
<?xml?version="1.0"?encoding="utf-8"?>?
<SOAP-ENV:Envelope?
????xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"?
????xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"?
????xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance"?
????xmlns:xsd="http://www.w3.org/1999/XMLSchema">?
????<SOAP-ENV:Body>?
????????<ns1:echoStringArray?
????????????xmlns:ns1="http://soapinterop.org/">?
????????????<inputStringArray?
????????????????SOAP-ENC:arrayType="xsd:string[2]"?
????????????????xsi:type="SOAP-ENC:Array">?
????????????????<item?xsi:type="xsd:string">?
????????????????????hello?
????????????????</item>?
????????????????<item?xsi:type="xsd:string">?
????????????????????goodbye?
????????????????</item>?
????????????</inputStringArray>?
????????</ns1:echoStringArray>?
????</SOAP-ENV:Body>?
</SOAP-ENV:Envelope>?

清單 22. SOAP 請求中的結(jié)構(gòu)數(shù)組。
<?xml?version="1.0"?encoding="utf-8"?>?
<SOAP-ENV:Envelope?
????xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"?
????xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"?
????xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance"?
????xmlns:xsd="http://www.w3.org/1999/XMLSchema"?
????xmlns:ns2="http://soapinterop.org/xsd">?
????<SOAP-ENV:Body>?
????????<ns1:echoStructArray?
????????????xmlns:ns1="http://soapinterop.org/">?
????????????<inputStructArray?
????????????????SOAP-ENC:arrayType="ns2:SOAPStruct[2]"?
????????????????xsi:type="SOAP-ENC:Array">?
????????????????<inputStruct?
????????????????????xsi:type="ns2:SOAPStruct">?
????????????????????<varFloat?
????????????????????????xsi:type="xsd:float">?
????????????????????????????6.2237275295275275295297529752?
????????????????????</varFloat>?
????????????????????<varString?
????????????????????????xsi:type="xsd:string">?
????????????????????????????test?string?
????????????????????</varString>?
????????????????????<varInt?
????????????????????????xsi:type="xsd:int">?
????????????????????????????5?
????????????????????</varInt>?
????????????????</inputStruct>?
????????????????<inputStruct?xsi:type="ns2:SOAPStruct">?
????????????????????<varFloat?
????????????????????????xsi:type="xsd:float">?
?????????????????????????????12.4?
????????????????????</varFloat>?
????????????????????<varString?
????????????????????????xsi:type="xsd:string">?
?????????????????????????????another?test?
????????????????????</varString>?
????????????????????<varInt?
????????????????????????xsi:type="xsd:int">?
????????????????????????????10?
????????????????????</varInt>?
????????????????</inputStruct>?
????????????</inputStructArray>?
????????</ns1:echoStructArray>?
????</SOAP-ENV:Body>?
</SOAP-ENV:Envelope>?

清單 23. SOAP 請求中的一個二維字符串?dāng)?shù)組。
<?xml?version="1.0"?encoding="utf-8"?>?
<SOAP-ENV:Envelope?
????xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"?
????xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"?
????xmlns:xsd="http://www.w3.org/2001/XMLSchema"?
????xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"?
????SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">?
????<SOAP-ENV:Body>?
????????<m:echo2DStringArray?
????????????xmlns:m="http://soapinterop.org/">?
????????????<input2DStringArray?SOAP-ENC:arrayType="xsd:string[3,2]">?
????????????????<item>Row-0,Column-0</item>?
????????????????<item>Row-0,Column-1</item>?
????????????????<item>Row-1,Column-0</item>?
????????????????<item>Row-1,Column-1</item>?
????????????????<item>Row-2,Column-0</item>?
????????????????<item>Row-2,Column-1</item>?
????????????</input2DStringArray>?
?????????</m:echo2DStringArray>?
?????</SOAP-ENV:Body>?
</SOAP-ENV:Envelope>?

清單 24. SOAP 請求中一個帶有偏移量的二維字符串?dāng)?shù)組。
<?xml?version="1.0"?encoding="utf-8"?>?
<SOAP-ENV:Envelope?
????xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"?
????xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"?
????xmlns:xsd="http://www.w3.org/2001/XMLSchema"?
????xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"?
????SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">?
????<SOAP-ENV:Body>?
????????<m:echo2DStringArray?
????????????xmlns:m="http://soapinterop.org/">?
<input2DStringArray?
????????????????SOAP-ENC:arrayType="xsd:string[3,2]"?
????????????????SOAP-ENC:offset="[2,0]">?
????????????????????<item>Row-0,Column-0</item>?
????????????????????<item>Row-0,Column-1</item>?
????????????????????<item>Row-1,Column-0</item>?
????????????????????<item>Row-1,Column-1</item>?
????????????????????<item>Row-2,Column-0</item>?
????????????????????<item>Row-2,Column-1</item>?
????????????</input2DStringArray>?
????????</m:echo2DStringArray>?
????</SOAP-ENV:Body>?
</SOAP-ENV:Envelope>?

清單 25. 結(jié)構(gòu)中帶有一個嵌套的字符串?dāng)?shù)組的 SOAP 請求。
<?xml?version="1.0"?encoding="utf-8"?>?
<SOAP-ENV:Envelope?
????xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"?
????xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"?
????xmlns:xsd="http://www.w3.org/2001/XMLSchema"?
????xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"?
????SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">?
????<SOAP-ENV:Body>?
????????<m:echoNestedArray?
????????????xmlns:m="http://soapinterop.org/">?
????????????<inputStruct>?
????????????????<varInt>12345</varInt>?
????????????????<varFloat>1234.5678?
????????????</varFloat>?
????????????<varString>?
????????????????A?Test?String?
????????????</varString>?
????????????<varArray?
????????????????SOAP-ENC:arrayType="xsd:string[4]"?
????????????????SOAP-ENC:offset="[0]">?
????????????????<item>First?Array?String</item>?
????????????????<item>Second?Array?String</item>?
????????????????<item>Third?Array?String</item>?
????????????????<item>Fourth?Array?String</item>?
????????????</varArray>?
????????</inputStruct>?
??????</m:echoNestedArray>?
???</SOAP-ENV:Body>?
</SOAP-ENV:Envelope>?

清單 26. 帶有二維數(shù)組的 SOAP 請求,未指定行(最里面一維)大小。
<?xml?version="1.0"?encoding="utf-8"?>?
<SOAP-ENV:Envelope?
????xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"?
????xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"?
????xmlns:xsd="http://www.w3.org/2001/XMLSchema"?
????xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"?
????SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">?
????<SOAP-ENV:Body>?
????????<m:echo2DStringArray?
????????????xmlns:m="http://soapinterop.org/">?
????????????<input2DStringArray?
????????????????SOAP-ENC:arrayType="xsd:string[,3]"?
????????????????SOAP-ENC:offset="[2,0]">?
????????????????<item>2,0</item>?
????????????????<item>2,1</item>?
????????????????<item>2,2</item>?
????????????????<item>3,0</item>?
????????????????<item>3,1</item>?
????????????????<item>3,2</item>?
????????????????<item>4,0</item>?
????????????????<item>4,1</item>?
????????????????<item>4,2</item>?
????????????</input2DStringArray>?
????????</m:echo2DStringArray>?
????</SOAP-ENV:Body>?
</SOAP-ENV:Envelope>?

Web 服務(wù)模型將整個 B2B 領(lǐng)域分成三個步驟或三個域:描述一個服務(wù)、將該服務(wù)與具體的實現(xiàn)綁定,然后通過注冊中心發(fā)布該服務(wù)。這三個步驟彼此獨立,會引發(fā)各自的互操作性問題。
WSDL(Web 服務(wù)描述語言(Web Services Description Language))構(gòu)成描述域,SOAP 覆蓋綁定域,統(tǒng)一描述、發(fā)現(xiàn)和集成(Universal Description, Discovery and Integration,UDDI)注冊中心覆蓋發(fā)布域。我在這部分的討論將僅限于與綁定域相關(guān)的互操作性問題。我將從討論 SOAP 的發(fā)展入手,接著討論實際的 SOAP 互操作性問題。
SOAP 版本的發(fā)展
1999 年,當(dāng) XML Schema 規(guī)范仍在發(fā)展中且被視為 SOAP 規(guī)范的關(guān)鍵部分的時候,W3C 就開始了關(guān)于 SOAP 規(guī)范的工作。SOAP 使用 XML Schema 數(shù)據(jù)類型定義來定義并實例化 SOAP 中的數(shù)據(jù)類型。
2000 年 5 月,SOAP 1.1 作為 W3C 紀(jì)要發(fā)行( 參考資料)。這是來自 Microsoft、IBM、Lotus Development 和 UserLand Software, Inc. 的開發(fā)人員共同努力的成果。SOAP 1.1 采用帶有 1999 名稱空間 URI( "http://www.w3.org/1999/XMLSchema")的 XML Schema 工作草案。目前,SOAP 1.2( 參考資料)已經(jīng)很接近于成為候選推薦,而且它已經(jīng)采用了 XML Schema 推薦(2001 年 5 月)和 XML Schema 的 2001 名稱空間 URI( "http://www.w3.org/2001/XMLSchema")。
互操作性問題
我將從基于傳輸(HTTP)的 SOAP 互操作性問題入手。
1. 傳輸
SOAP 1.1 規(guī)范允許在 HTTP 請求中發(fā)送 SOAP 消息。如同第 2 部分( 參考資料)中所描述的,SOAP 與 HTTP 集成并不會影響 SOAP 的語義。SOAP 規(guī)范將必選的 SOAPAction 頭添加到 HTTP 請求頭中。我在前一篇文章中已經(jīng)描述過, SOAPAction 頭的合法取值有三種:
它可以為空
它可以是一個用引號括起來的空字符串
它還可以是一個任意的 URI
這種靈活性使 SOAP 實現(xiàn)能夠選擇它們自己的 SOAPAction 樣式及其功能。但是這種靈活性已經(jīng)引發(fā)了互操作性問題。
為了研究這些互操作性問題,我創(chuàng)建了一個 SOAP 客戶機( 參考資料),該客戶機向 SOAP 服務(wù)器(由 URL 參數(shù)指定的)發(fā)送一個請求并且在接收到時顯示服務(wù)器響應(yīng)。我在更改 SOAPAction 頭的值之后將簡單的 SOAP 請求發(fā)送給不同的服務(wù)器,從而查看服務(wù)器如何支持 SOAP 1.1 規(guī)范所允許的三種頭。
除 SOAPAction 頭(這個頭由我操作)外,我的測試均按照 SOAPBuilders 的第 2 輪(基本)echoString 測試(SOAPBuilders' Round 2 (Base) echoString test)( 參考資料)進行。您應(yīng)該訪問 SOAPBuilders 的第 2 輪測試站點以獲得 WSDL 文件(基本測試),該文件描述了我在執(zhí)行測試期間將調(diào)用的測試 Web 服務(wù)。
被測試的 SOAP 服務(wù)器
我在本文中測試了下列 SOAP 服務(wù)器:
Apache Axis SOAP Server
Apache SOAP 2.2 Server
WhiteMesa 2.7 SOAP Server
IONA XMLBus
SOAP::Lite
EasySOAP++
4S4C
Microsoft ASP.NET Web Services
我在測試中使用了四個 SOAP 請求。
清單 1 包含了 SOAPAction 頭的值用雙引號括起來的 SOAP 請求。 SOAPAction 頭的值與 WSDL 文件中給定的值( "http://soapinterop.org/")一樣。
清單 2 包含了相同的 SOAPAction 頭值,但是沒有雙引號( http://soapinterop.org/)。
清單 3 包含了一個與 WSDL 文件中給定的頭不同的 SOAPAction 頭( "http://differentfromwsdl.org/")。
清單 4 為 SOAPAction 頭指定了一個空值。
我向 WhiteMesa SOAP Server 2.7 發(fā)送 清單 1,它作出了一個成功響應(yīng),說明 WhiteMesa 可以成功地處理這樣的 SOAPAction 頭。接下來,我向 WhiteMesa 發(fā)送 清單 2,它再次成功地對其進行了處理。最后,當(dāng)我將 SOAPAction 頭的值更改為 "http://differentfromwsdl.org/"( 清單 3)時,WhiteMesa 未能成功處理該請求并返回一個故障響應(yīng)。故障字符串為 “Unrecognized 'SOAPAction' HTTP header received.”。WhiteMesa SOAP Server 2.7 還針對 清單 4 中的請求(其中 SOAPAction 值為空)返回一個故障響應(yīng)。
我還用 IONA XMLBus 和 SOAP::Lite 對清單 1、 3和 4進行了測試,它們成功地處理了 清單 1中的請求,但卻針對清單 3和 4中的請求返回了故障消息。IONA XMLBus 也針對 清單 2(未用雙引號將 URI 引起來)返回了一個故障響應(yīng),指出它期望請求中的 SOAPAction 頭要和 WSDL 文件中定義的 SOAPAction 頭一樣,并且要用雙引號括起來。
接下來,我向 Easy SOAP++ 0.6 發(fā)送清單 1、 3和 4 中的請求,它返回正確的響應(yīng)。不管 SOAPAction 頭的值為何,Apache Axis 和 Apache SOAP 2.2 都返回正確的響應(yīng)。
結(jié)論
為了獲得最大程度的互操作性,我推薦用引號將 SOAPAction 頭的值括起來;這個值應(yīng)該與 WSDL 文件中給定的一致。
2. XML
XML Schema
這一部分描述了各種 SOAP 服務(wù)器對編制 SOAP 請求的過程中所使用的不同的 XML Schema 版本表現(xiàn)出的行為。我將對使用測試客戶機測試不同的 SOAP 服務(wù)器支持的 XML 模式名稱空間 URI 所得到的測試結(jié)果進行分析。
清單 1和 清單 5是完全相同的 SOAP 請求,只是所使用的 XML Schema 版本不同。 清單 1使用 2001 XML Schema URI,而 清單 5使用 1999 URI。我對大量服務(wù)器進行了名稱空間 URI 支持測試,然后發(fā)現(xiàn) IONA XMLBus 不能成功處理 1999 URI,但是卻向使用 2001 URI 的 清單 1中的請求返回了一個成功的響應(yīng)。因此,IONA XMLBus 中的支持被限制為 2001 XML Schema 名稱空間 URI。
我可以有把握地說,2001 URI 將對大多數(shù)實現(xiàn)起作用,但是諸如 IBM SOAP Toolkit 和 Apache SOAP 之類較老的實現(xiàn)仍然廣泛存在,這些實現(xiàn)使用的是 1999 URI。Apache SOAP 2.2 既接收 1999 URI,也接收 2001 URI,但是它在響應(yīng)消息中缺省情況下使用 1999 URI(盡管它確實允許您將其更改為 2001)。因此,您可以預(yù)料到那些僅期待 2001 URI 的客戶機(比如 IONA XMLBus)與早期的 SOAP 實現(xiàn)之間將存在互操作性問題。
結(jié)論
因為 2001 URI 不久就要成為標(biāo)準(zhǔn)(SOAP 1.2 規(guī)范)了,并且它為目前的 SOAP 實現(xiàn)所廣泛支持,所以,對于 XML Schema 名稱空間 URI 來說,最佳做法可能就是在請求中使用 2001 URI 了。
連接類型相關(guān)性與 WSDL 知曉性的比較
SOAP 1.1 允許實現(xiàn)提供有關(guān)消息中包含的數(shù)據(jù)的類型信息。這是對數(shù)據(jù)的文字描述(例如, int 、 string 等)。一些實現(xiàn)依賴該信息來正確地反序列化消息中的數(shù)據(jù)。Apache SOAP 2.2 是那些在連接時需要顯式輸入信息的實現(xiàn)之一(即,數(shù)據(jù)類型信息被作為包含數(shù)據(jù)的元素的一個屬性值提供);否則它就無法反序列化數(shù)據(jù)。
我在第 1 部分( 參考資料)中已經(jīng)討論了 WSDL 文件的語義。WSDL 文件用于描述 Web 服務(wù)。它包含有關(guān) Web 服務(wù)所公開的一些方法以及它們的說明的信息。因為 WSDL 文件包含關(guān)于哪些參數(shù)可以傳遞給一個方法以及期望返回哪些內(nèi)容的信息,這些信息可以被用于反序列化一個調(diào)用方法的 SOAP 請求及其響應(yīng)。因此,WSDL 文件知曉性是上述問題的解決方案;即,正在反序列化一條 SOAP 消息的運行時應(yīng)用程序能夠利用 WSDL 文件中提供的數(shù)據(jù)類型信息。
現(xiàn)在,大多數(shù)實現(xiàn)都是 WSDL 知曉的并且不依賴于連接時的類型化。Apache Axis 無需連接時的類型化就可以處理數(shù)據(jù),White Mesa 2.7 也可以;但是這里就出現(xiàn)了一個互操作性問題。如果元素名稱和 WSDL 文件中指定的不同,White Mesa 2.7 就不能處理這個請求。對于許多其它實現(xiàn)都是如此。但是另一方面,Apache Axis 能夠處理這樣一個請求而不發(fā)出一個故障。所以,如果您為 Apache Axis 編寫一個這樣的請求,它將不會在 White Mesa 2.7 上運行。為服務(wù)編寫遵循 WSDL 文件的請求和響應(yīng)可能是一個更好的做法。這將能處理所有具有 WSDL 知曉性的實現(xiàn)。
3. 數(shù)據(jù)類型
數(shù)據(jù)類型兼容性可能是 SOAP 互操作性中最重要的問題。如果兩個應(yīng)用程序不能理解彼此的數(shù)據(jù)類型,那么它們就不能執(zhí)行有意義的數(shù)據(jù)交換,從而也就不能互操作。
在本系列文章的第二篇文章中已經(jīng)介紹了數(shù)據(jù)類型,我在那篇文章中討論了幾種簡單的數(shù)據(jù)類型和復(fù)雜的數(shù)據(jù)類型。SOAP 使用 XML Schema 數(shù)據(jù)類型和結(jié)構(gòu)來標(biāo)識 SOAP 消息中攜帶的數(shù)據(jù)的類型。
使用 SOAP 進行傳遞的數(shù)據(jù)首先被序列化;即,數(shù)據(jù)值被轉(zhuǎn)換成字符串以在 XML 文檔中傳送。在目的地,這個字符串必須被反序列化,即,被轉(zhuǎn)換成表示原來的值的數(shù)據(jù)類型。
將 XML Schema 數(shù)據(jù)類型映射到適當(dāng)?shù)谋緳C數(shù)據(jù)類型是由 SOAP 實現(xiàn)負(fù)責(zé)的。如果兩個本機數(shù)據(jù)類型不一致,即,此時 XML 中的同一種數(shù)據(jù)類型在不同的實現(xiàn)中有不同的值(因此,也就有不同的含義),就可能產(chǎn)生問題。在序列化和反序列化之后保持?jǐn)?shù)據(jù)的一致是很重要的。我將詳細討論這個問題。
連接類型相關(guān)性與 WSDL 知曉性的比較
SOAP 1.1 允許實現(xiàn)提供有關(guān)消息中包含的數(shù)據(jù)的類型信息。這是對數(shù)據(jù)的文字描述(例如, int 、 string 等)。一些實現(xiàn)依賴該信息來正確地反序列化消息中的數(shù)據(jù)。Apache SOAP 2.2 是那些在連接時需要顯式輸入信息的實現(xiàn)之一(即,數(shù)據(jù)類型信息被作為包含數(shù)據(jù)的元素的一個屬性值提供);否則它就無法反序列化數(shù)據(jù)。
我在第 1 部分( 參考資料)中已經(jīng)討論了 WSDL 文件的語義。WSDL 文件用于描述 Web 服務(wù)。它包含有關(guān) Web 服務(wù)所公開的一些方法以及它們的說明的信息。因為 WSDL 文件包含關(guān)于哪些參數(shù)可以傳遞給一個方法以及期望返回哪些內(nèi)容的信息,這些信息可以被用于反序列化一個調(diào)用方法的 SOAP 請求及其響應(yīng)。因此,WSDL 文件知曉性是上述問題的解決方案;即,正在反序列化一條 SOAP 消息的運行時應(yīng)用程序能夠利用 WSDL 文件中提供的數(shù)據(jù)類型信息。
現(xiàn)在,大多數(shù)實現(xiàn)都是 WSDL 知曉的并且不依賴于連接時的類型化。Apache Axis 無需連接時的類型化就可以處理數(shù)據(jù),White Mesa 2.7 也可以;但是這里就出現(xiàn)了一個互操作性問題。如果元素名稱和 WSDL 文件中指定的不同,White Mesa 2.7 就不能處理這個請求。對于許多其它實現(xiàn)都是如此。但是另一方面,Apache Axis 能夠處理這樣一個請求而不發(fā)出一個故障。所以,如果您為 Apache Axis 編寫一個這樣的請求,它將不會在 White Mesa 2.7 上運行。為服務(wù)編寫遵循 WSDL 文件的請求和響應(yīng)可能是一個更好的做法。這將能處理所有具有 WSDL 知曉性的實現(xiàn)。
Float(浮點)
與 float 有關(guān)的常見問題出現(xiàn)在無窮大的表示上。XML Schema 用字符串 INF表示無窮大。 清單 6在請求中將 INF 作為 float 無窮大發(fā)送,Apache SOAP 2.2 服務(wù)器以 Infinity返回它,而 Apache Axis 則返回 INF( 清單 7)。
我還通過發(fā)送 清單 6 的 SOAP 請求對 MS SOAP Toolkit 3.0 服務(wù)器進行了測試。它返回一個服務(wù)器端的故障代碼,且不能將 float 無窮大值 INF反序列化,如同故障字符串 “SoapMapper:Converting data for SoapMapper failed inside the typemapper”所指出的那樣。
另一個問題與 float 精度支持有關(guān)。我把 1.23456789E38 作為 float 發(fā)送給幾臺 SOAP 服務(wù)器(請參閱 清單 8)。IONA XMLBus 返回 1.23456789E38,White Mesa 2.7 服務(wù)器返回 1.234568E38,而 MS SOAP ToolKit 3.0 服務(wù)器返回 1.23456786051167E+38。盡管這指出了各個實現(xiàn)正在進行互操作的事實,但是這些實現(xiàn)仍然不能將數(shù)據(jù)重新生成為它的原始值。
Decimal(十進制)
對于 decimal ,XML Schema 規(guī)范要求實現(xiàn)要支持的最少位數(shù)是 18 位。因為在規(guī)范中沒有定義上限,所以各個實現(xiàn)可以隨意設(shè)置它們自己的上限。Microsoft ASP.NET Web Services 和 WhiteMesa 2.7 給出的精度最多達 28 位,而 Apache Axis 可以精確支持?jǐn)?shù)百位。這種支持上的差異意味著,當(dāng)一個 Apache Axis 實現(xiàn)向 WhiteMesa 2.7 實現(xiàn)發(fā)送一些大小超過 28 位的 decimal 數(shù)字時,額外的精度將被截斷,從而造成數(shù)據(jù)不一致。
我發(fā)送 清單 9 中的 decimal 數(shù)字請求(該請求帶有一個很大的 decimal 數(shù)字)以了解不同服務(wù)器的精度支持。在清單 10、 11和 12中,可以分別看到來自 ASP.NET 服務(wù)器、Apache Axis 以及 WhiteMesa 2.7 的響應(yīng)。4S4C 服務(wù)器在對 清單 9的響應(yīng)中返回的值為 1.235。
DateTime(日期時間)
XML Schema 中用于時間和日期信息的數(shù)據(jù)類型是 dateTime 。White Mesa 2.7 給出的精度為秒。Apache SOAP 2.2 和 Apache Axis 用 java.util.Date 類表示一個特定的時間實例,精度為毫秒。Microsoft ASP.NET Web Services 使用 Date 類型,該類型可以表示精度為納秒的時間。
現(xiàn)在,如果一個基于 .NET 的 SOAP 客戶機端實現(xiàn)向 SOAP 2.2 實現(xiàn)或 White Mesa 2.7 實現(xiàn)發(fā)送 dateTime 信息, dateTime 中額外的精度將被丟失,從而導(dǎo)致數(shù)據(jù)不一致性。請注意:在 XML Schema 中,精度達到秒是強制性的,而秒的小數(shù)部分則是可選的且合法的。
我用 清單 13 中的請求進行了 dateTime 測試。在清單 14、 15、 16和 17中分別顯示了來自 Microsoft ASP.NET Web Services、Apache Axis、WhiteMesa 2.7 和 SOAP::Lite 的響應(yīng)。
字節(jié)數(shù)組(Byte Array)
SOAP 允許您以字節(jié)數(shù)組的形式交換數(shù)據(jù)。字節(jié)數(shù)組在被放入一個 XML 文檔中之前,它必須是 base64編碼的。許多實現(xiàn)未能通過 SOAPBuilder( 參考資料)的第 2 輪(基本)互操作性測試中的 echoBase64 測試。由于本機數(shù)據(jù)類型格式的差異,一些實現(xiàn)返回的是不一致的值。一些實現(xiàn)通過對已經(jīng)進行 base64 編碼的值進一步進行 base64 編碼來返回值。
清單 18(使用 1999 XML Schema base64Binary 數(shù)據(jù)類型)和 清單 19(使用 2001 Schema base64Binary 數(shù)據(jù)類型)中的請求向 SOAP 服務(wù)器發(fā)送一個簡單的 echoBase64 方法調(diào)用。
Apache SOAP 2.2 在對 清單 18和 清單 19的響應(yīng)中都返回故障消息。該服務(wù)器未能識別兩個例子中的數(shù)據(jù)類型,因此無法反序列化 base 64 編碼的字節(jié)數(shù)組。
請看一下 清單 20,它指定 base64 作為數(shù)據(jù)類型編碼。與 XML Schema 規(guī)范定義的 base64Binary 數(shù)據(jù)類型相比, base64 編碼是由 SOAP 1.1 規(guī)范定義的。Apache SOAP 2.2 成功地處理了 清單 20的請求。
IONA XMLBus 成功地處理了 19,但處理 18(請回顧一下講述 XML Schema 問題的部分,在那部分中,我發(fā)現(xiàn)了 IONA XMLBus 只支持 2001 XML Schema URI)時失敗了。它也無法識別 清單 20 中的請求中的 SOAP-ENC:base64 數(shù)據(jù)類型實例,然后返回一個故障字符串。
從上面的測試中能明顯看出,當(dāng) Apache SOAP 2.2 和 IONAXMLBus 交換 base64 編碼的字節(jié)數(shù)組時,它們之間有互操作性問題。
數(shù)組(Array)
數(shù)組形式的數(shù)據(jù)對實現(xiàn)來說一直是一個困難的測試,尤其是當(dāng)情形復(fù)雜,滿是使用嵌套的數(shù)組、多維數(shù)組以及嵌套結(jié)構(gòu)(struct)的情況時。
struct 是一種復(fù)雜的、用戶定義的數(shù)據(jù)類型,它可以包含簡單的或更復(fù)雜的數(shù)據(jù)類型。具有 C 語言編程經(jīng)驗的讀者可能會想在 C struct 和 XML Schema struct 之間做一個類比。
有無數(shù)種方法可以把一維數(shù)組和多維數(shù)組與其它的數(shù)據(jù)類型結(jié)合在 structs 中。因此,我設(shè)計了大量 SOAP 請求來測試不同 SOAP 服務(wù)器的行為。這些測試遵循 SOAPBuilders 的第 2 輪(B 組)測試套件。您可以在 SOAPBuilders 的第 2 輪 Web 站點上得到 B 組測試的 WSDL 文件。
清單 21 包含了一個簡單的 strings 數(shù)組。
清單 22 包含了一個 structs 數(shù)組。該 struct 包含了一個 string 、一個 float 和一個 int 數(shù)據(jù)類型。
清單 23 包含一個二維的 strings 數(shù)組。
清單 24為二維數(shù)組定義了一個偏移量(這個值定義了應(yīng)該從哪個位置開始處理數(shù)組)。
清單 25 包含了一個 struct ,該 struct 帶有一個嵌套的 strings 數(shù)組。
清單 26包含一個二維數(shù)組,未指定最里面一維的大小。
我所測試的所有 SOAP 實現(xiàn)對于簡單類型和復(fù)雜類型的數(shù)組(即 清單 21和 清單 22)都沒有問題。
用清單 21、 22、 23、 24、 25和 26對 WhiteMesa 2.7 服務(wù)器進行了測試。盡管 只是當(dāng)指定了偏移量(大于零)時,WhiteMesa 2.7 服務(wù)器未能成功處理 清單 25,但它還是成功地處理了所有請求。White Mesa 2.7 就已經(jīng)顯示了在最里面一維的大小未被指定( 清單 26)時能夠處理二維數(shù)組。
我向 SOAP::Lite 發(fā)送 清單 23中的請求,SOAP::Lite 無法處理該請求,它返回一個帶有故障字符串 “Not implemented, because SOAP::Lite does not generate multidimensional arrays (yet accepts ;))”的故障響應(yīng)。 清單 26中的請求能被 WhiteMesa 成功地處理,卻不能被許多其它的實現(xiàn)成功處理;SOAP::Lite 和 Apache Axis 返回故障消息。
結(jié)論
包括數(shù)組以及數(shù)組的不同組合的交換的數(shù)據(jù)交換,對于大多數(shù) SOAP 實現(xiàn)可能是可以的,除了上面我已經(jīng)指出的幾個實現(xiàn)外。為了確保最大程度的互操作性和數(shù)據(jù)一致性,Web 服務(wù)開發(fā)者應(yīng)該編寫全面的數(shù)據(jù)測試,這些測試由期望的數(shù)據(jù)模式的所有可能變體組成,因為那樣做可以找出可以解決的問題并確認(rèn)應(yīng)用程序和數(shù)據(jù)一致性。
雜項
在 SOAP 中,還有其它可能引發(fā)互操作性問題的地方。這些問題可能會因引擎無法處理 mustUnderstand SOAP 頭而顯露出來。可以通過定制頭來擴展 SOAP 功能。這個可擴展性還為最終可能會導(dǎo)致互操作性問題的專有的、非標(biāo)準(zhǔn)的解決方案打開了解決渠道。SOAP 允許使用一些實現(xiàn)(例如,Apache SOAP 2.2)所不支持的多個返回參數(shù)。編碼模式描述了將數(shù)據(jù)序列化到 XML 以及將數(shù)據(jù)從 XML 反序列化時所遵循的規(guī)則。遺憾的是,盡管 SOAP 1.1 確實提議了一個 SOAP 消息的編碼,但是它并沒有為 SOAP 消息指定一個缺省編碼。SOAP 實現(xiàn)者并沒有被該規(guī)范所束縛,不會為了遵循規(guī)范而實現(xiàn)規(guī)范定義的編碼。缺少缺省編碼模式可能會導(dǎo)致互操作性問題。
結(jié)束語
對于那些正在計劃在現(xiàn)在的 SOAP 實現(xiàn)上構(gòu)建 Web 服務(wù)的開發(fā)者,或者那些正在編寫他們自己的 SOAP 服務(wù)器和客戶機的開發(fā)者,現(xiàn)在我可以提供幾點建議。
如果您正在計劃使用 SOAP 1.1 實現(xiàn),請在您的請求中用引號把 SOAPAction 頭括起來,并且要確保它與服務(wù)的 WSDL 文件中的 SOAPAction 頭一致。
請采用 XML Schema 的 2001 名稱空間 URI,因為它現(xiàn)在是事實上的標(biāo)準(zhǔn)。
請遵照 SOAP 1.1 定義的編碼,并請確保您發(fā)送和接收的數(shù)據(jù)確實是以它應(yīng)該的格式進行的。
您的方法元素名稱應(yīng)該遵循 WSDL 描述。
請在 SOAP 消息中提供連接時的數(shù)據(jù)類型信息。
清單 1. SOAPAction 值為 "http://soapinterop.org/" 的 SOAP 請求。
?


















清單 2. SOAPAction 值(未加引號的)為 http://soapinterop.org/ 的 SOAP 請求。



















清單 3. SOAPAction 值為 "http://differentfromwsdl.org/" 的 SOAP 請求。


















清單 4. SOAPAction 值為空的 SOAP 請求。


















清單 5. 帶有 XML Schema 的 1999 名稱空間 URI 的 SOAP 請求。















清單 6. “INF”作為 float 無窮大的 SOAP 請求。











清單 7. Apache Axis 服務(wù)器對清單 6 中的請求的響應(yīng)。













清單 8. 用于對 SOAP 服務(wù)器進行 float 值測試的 SOAP 請求。












清單 9. 很大的十進制數(shù)的 SOAP 請求。














清單 10. 來自 Microsoft 的 ASP.NET Web Services 對清單 9 中的請求的 SOAP 響應(yīng)。

























清單 11. 來自 Apache Axis 的對清單 9 中的請求的 SOAP 響應(yīng)。





















清單 12. 來自 WhiteMesa 2.7 的對清單 9 中的請求的 SOAP 響應(yīng)。




















清單 13. SOAP dataTime 數(shù)據(jù)類型請求。















清單 14. 來自 Microsoft ASP.NET Web Services 的對清單 13 中的請求的響應(yīng)。























清單 15. 來自 Apache Axis 的對清單 13 中的請求的響應(yīng)。






















清單 16. 來自 WhiteMesa 2.7 的對清單 13 中的請求的響應(yīng)。





















清單 17. 來自 SOAP::Lite 的對清單 13 中的請求的響應(yīng)。

























清單 18. 帶有 1999 XML Schema URI 限定的 base64Binary 數(shù)據(jù)類型的 SOAP 請求。

















清單 19. 帶有 2001 XML Schema URI 限定的 base64Binary 數(shù)據(jù)類型的 SOAP 請求。

















清單 20. 帶有 SOAP-ENC 限定的 base64 數(shù)據(jù)類型的 SOAP 請求。

















清單 21. SOAP 請求中的一個字符串?dāng)?shù)組。























清單 22. SOAP 請求中的結(jié)構(gòu)數(shù)組。















































清單 23. SOAP 請求中的一個二維字符串?dāng)?shù)組。






















清單 24. SOAP 請求中一個帶有偏移量的二維字符串?dāng)?shù)組。
























清單 25. 結(jié)構(gòu)中帶有一個嵌套的字符串?dāng)?shù)組的 SOAP 請求。






























清單 26. 帶有二維數(shù)組的 SOAP 請求,未指定行(最里面一維)大小。


























