監(jiān)理公司管理系統(tǒng) | 工程企業(yè)管理系統(tǒng) | OA系統(tǒng) | ERP系統(tǒng) | 造價咨詢管理系統(tǒng) | 工程設(shè)計管理系統(tǒng) | 甲方項目管理系統(tǒng) | 簽約案例 | 客戶案例 | 在線試用
X 關(guān)閉

Web服務(wù)的(革)創(chuàng)新,第3部分

申請免費試用、咨詢電話:400-8352-114

AMTeam.org

Web服務(wù)的(革)創(chuàng)新,第3部分

--SOAP 是如何工作的


Graham Glass

CEO/首席設(shè)計師,The Mind Electric

2001 年 1 月

這篇文章向您解釋 SOAP 是如何工作的,包括有關(guān)它的線上協(xié)議和如何處理消息的信息。本文還解釋對象是如何通過值在 Web 服務(wù)間被傳遞的,并涉及到性能和安全性問題。

歡迎進入本專欄的第 3 部分,本專欄重點講述 Web 服務(wù)技術(shù)的革新和創(chuàng)新方面。在第 2 部分中,我說明了如何使用 Apache 簡單對象訪問協(xié)議 (SOAP) 來建立、部署和調(diào)用一個簡單的 Web 服務(wù)。在這個部分中,我將說明 SOAP 如何在后臺工作,從技術(shù)角度來講這很有趣,它將有助于揭開我們將要討論的未來標(biāo)準(zhǔn)的神秘面紗,例如 Web 服務(wù)描述語言 (WSDL) 和通用描述、發(fā)現(xiàn)和集成 (UDDI) 標(biāo)準(zhǔn)(請參閱參考資料)。

工具和安裝

由于我們使用和前一部分相同的工具,因此無需安裝新軟件。另外,我們將沿用前一部分的示例,所以請確定您還存有 demo1 目錄 下的 IExchange.java、Exchange.java、Client.java 源文件。

這次我要介紹的一個新的軟件工具是 TCP tunneling GUI,它可以讓您看到 TCP 消息如何在客戶端和服務(wù)器間傳送。使用此工具可檢查 SOAP 線上協(xié)議甚至檢驗相互競爭的各種 SOAP 實現(xiàn)是否是符合標(biāo)準(zhǔn)的。

初探 SOAP

TCP tunneling GUI 通過作為一個 TCP 路由器來使您“初探” SOAP 消息。為了看它的實際運行,先啟動在 demo1 目錄下的 Apache Tomcat 服務(wù)器(可以在參考資料中找到它最新的發(fā)行版),輸入:

> cd demo1
> tomcat run

Tomcat 缺省在 8080 端口啟動。然后在另一個窗口啟動 TCP tunneler,輸入:

> java org.apache.soap.util.net.TcpTunnelGui 8070 localhost 8080

這會在 8070 端口啟動一個 TCP 服務(wù)器,它在任意一個客戶端與本機的 8080 端口(在本例中,由 Tomcat 提供)之間扮演一個中介的角色。其 GUI(請參閱圖 1)將在左邊的面板里顯示外發(fā)消息并在右邊的面板里顯示接收的回復(fù)消息。

圖 1:TCP tunneler界面


現(xiàn)在編輯以前示例中的 Client.java 代碼,將 Web 服務(wù) URL 改為使用 8070 端口而不是 8080 端口??蛻舳顺绦虻牡谝恍袘?yīng)該如下:

URL url = new URL( "http://localhost:8070/soap/servlet/rpcrouter" );

然后編譯和運行客戶端。GUI 顯示如圖 2。

圖 2:運行tunneler


如你們所見,左手邊的面板顯示了外發(fā)的 SOAP 請求,它包含 5 行標(biāo)準(zhǔn) HTTP 頭,后面接著是代表客戶端服務(wù)調(diào)用的 XML 文檔。右手邊的面板顯示了 SOAP 響應(yīng)的結(jié)果,它包含 6 行標(biāo)準(zhǔn) HTTP 頭,接著是 XML 文檔表示的服務(wù)器響應(yīng)。即使沒有 SOAP 格式的解釋,您也可以猜出它的大部分意思。您可以將這與二進制、非自描述的和難于跟蹤的 CORBA 和 DCOM 協(xié)議進行比較。我較早接觸這兩個協(xié)議,也曾寫過一個 CORBA ORB。

SOAP 請求剖析

首先要提的是盡管這個特殊的設(shè)置是使用 HTTP 傳遞 SOAP 消息的,但 SOAP 可以運行在任何其它傳輸協(xié)議上。例如,您可以使用 SMTP,即因特網(wǎng)電子郵件協(xié)議來傳遞 SOAP 消息。在傳輸層之間的頭是不同的,但 XML 有效負(fù)載保持相同。清單 1 所示的是一個完整的 SOAP/HTTP 請求,為了更直觀一些,XML 內(nèi)容全部是縮進格式的。

一個 SOAP 請求作為 HTTP POST 被發(fā)送,同時其內(nèi)容類型設(shè)成 text/xml,一個叫 SOAPAction 的字段設(shè)為空字符串或 SOAP 方法的命名。SOAPAction 字段允許負(fù)責(zé)接收的Web服務(wù)器檢測該請求是一個SOAP 消息并潛在地發(fā)送或過濾這個消息。

SOAP 請求的 XML 部分包含三個主要部分:

Envelope 定義各個 SOAP 消息的余下部分會使用的 namespaces,典型的有 xmlns:SOAP-ENV(SOAP Envelope namespace)、xmlns:xsi(XML Schema for Instances) 和 xmlns:xsd(XML Schema for DataTypes)。

Header 是可選的元素,它攜帶認(rèn)證、事務(wù)處理和支付的輔助信息。一個 SOAP 處理鏈中的任一元素可增加或刪除 Header 里的項;元素也可選擇忽略它們不認(rèn)識的項。如果 Header被使用,它必須是 Envelope 的第一個子元素。因為我們的示例簡單,不涉及路由器,所以不需要 Header。
Body 是消息的主要有效載體。當(dāng) SOAP 被用于執(zhí)行一個 RPC 調(diào)用時,Body 包含一個單獨元素,這個元素包含方法名、參數(shù)和 Web 服務(wù)的目標(biāo)地址。元素的 namespace 等于目標(biāo)地址,根名是方法名。在這個示例中,ns1:getRate 表示目標(biāo)地址是 urn:demo1:exchange (ns1 的擴展形式),方法名是 getRate。如果有 Header,Body 必須緊接其后,否則它必須是 Envelope 的第一個子元素。

當(dāng)使用 SOAP 作為一個遠程過程調(diào)用 (RPC) 系統(tǒng)時,SOAP 參數(shù)可以是有類型的或無類型的。當(dāng)前版本的 Apache 只接受有類型參數(shù),正在開發(fā)的某個版本將來也許可以完全允許無類型參數(shù)。缺省的 SOAP 編碼模式使用 xsi:type 屬性來表示一個 XSD 類型。XSD 定義這幾個基本類型:int、byte、short、 boolean、string、float、double、 date、time 和 URL。它也指定了發(fā)送數(shù)組和不透明數(shù)據(jù)塊的格式。

因為我們希望SOAP平臺和語言無關(guān),所以 XSD 沒有為某種個別語言才有的編碼對象和結(jié)構(gòu)定義格式。在本文的后面,我將會展示如何在都運行 Apache SOAP 2.0 的兩臺機器之間發(fā)送 java 對象。

SOAP/HTTP 消息都被運行在一臺 Web 服務(wù)器上的 servlet 所接受。在本示例中,Apache 2.0 在 Tomcat 的soap/servlet/rpcrouter下安裝了一個 servlet,它負(fù)責(zé)接受 HTTP 請求。當(dāng)此 servlet 得到一個請求,它先檢查這個請求是否有 SOAPAction 字段。如果有, 它將其轉(zhuǎn)發(fā)給 Apache SOAP 引擎,然后此引擎分析 XML 有效載體,并在其本地注冊表(啟動時從 DeployedServices.ds 文件讀入)上使用目標(biāo) Web 服務(wù)地址來執(zhí)行查詢。然后它使用內(nèi)省機制來確定服務(wù)位置,并調(diào)用此服務(wù)上的指定的方法以獲得結(jié)果。

下一節(jié)描述了用于將結(jié)果返回給客戶端的 SOAP/HTTP 響應(yīng)的格式 。

SOAP 響應(yīng)剖析

一個 SOAP/HTTP 響應(yīng)(請參閱清單 2)在一個標(biāo)準(zhǔn) HTTP 回應(yīng)內(nèi)以一個 XML 文檔返回,標(biāo)準(zhǔn) HTTP 回應(yīng)的內(nèi)容類型被設(shè)定為 text/xml。除了它的 Body 包含被編碼的方法結(jié)果之外,XML 文檔結(jié)構(gòu)和請求時的結(jié)構(gòu)很像。結(jié)果的命名空間是原始目標(biāo)對象 URI,根名是被調(diào)用的方法名。XSI/XSD 標(biāo)記模式被選擇性地用來指示結(jié)果類型(請參閱參考資料)。SOAP 標(biāo)準(zhǔn)沒有詳細(xì)指出從一個 void 方法中返回什么,目前大多數(shù)的實現(xiàn)省略了 Body 的 部分。

SOAP 異常

如果消息處理過程中有異常出現(xiàn),一個 SOAP 異常就被扔出。SOAP 異常的編碼方式和常規(guī) SOAP 響應(yīng)相似,不同的是由 Body 來包含有關(guān)異常的信息。為了闡明這一點,請編輯 Exchange.java 文件,它描述了我們的貨幣兌換 Web 服務(wù)并迫使它拋出一個異常,如清單 3 所示。

清單 3:一個 SOAP 異常

public class Exchange implements IExchange
{
public float getRate( String country1, String country2 )
{
throw new RuntimeException( "cannot calculate rate" );
/*
System.out.println( "getRate( " + country1 + ", " + country2 + " )" );
return 144.52F; // always return the same value for now
*/
}
}

然后停掉并重啟 Tomcat ,這樣它就使用新版本的 Web 服務(wù)。使用 Client 程序調(diào)用服務(wù)。TCP tunneling GUI 的輸出顯示在清單 3 中。

清單 3:SOAP 異常的tunneler輸出

標(biāo)準(zhǔn)的 HTTP 回應(yīng)頭使用狀態(tài)碼 500 來表示一個異常。就像一個常規(guī)響應(yīng)一樣,XML 有效載體包含一個 Envelope 和 Body,不同的是 Body 的內(nèi)容是一個 Fault 結(jié)構(gòu),它的字段定義如下:

Faultcode 表示錯誤類型的代碼。有效值是 SOAP-ENV:Client (錯誤的構(gòu)造消息)、SOAP-ENV:Server (傳遞問題)、SOAP-ENV:VersionMismatch (Envelope 元素的非法命名空間)和 SOAP-ENV:MustUnderstand (錯誤處理 header 內(nèi)容)。
Faultstring讓人易讀的錯誤的描述。

Faultactor 是可選的字段,它表示錯誤源的 URI。

Detail 是特定應(yīng)用的 XML,它包括詳細(xì)的錯誤信息。

一些 SOAP 執(zhí)行使用 Detail 元素將有關(guān)遠程異常的信息進行編碼,比如它們的類型、數(shù)據(jù)和堆棧跟蹤,這樣它們可以在客戶端再次被自動扔出。這允許使用 SOAP 來實現(xiàn)RMI風(fēng)格的遠程異常。當(dāng)然,如果客戶端和服務(wù)器不使用同樣的 SOAP 實現(xiàn),這個功能會被自動禁止。

性能

既然已經(jīng)知道了 SOAP 是如何使用 HTTP 和 XML 來回傳遞消息的,那么考慮性能問題應(yīng)該會很有趣。

CORBA、DCOM 和 RMI 對參數(shù)和返回值使用二進制編碼。除此之外,他們假設(shè)發(fā)送端和接收端充分了解消息的前后關(guān)系,因此對諸如參數(shù)名稱或類型的任何元信息都不編碼。這種方法產(chǎn)生了良好的性能,但使中介很難處理消息。因為每個系統(tǒng)使用不同的二進制編碼,所以建立互操作的系統(tǒng)很難。

而 SOAP 用 XML 將消息編碼,因此在調(diào)用過程的任何一步都極易處理消息。另外,調(diào)試 SOAP 消息的方便性使各種 SOAP 執(zhí)行能快速聚合在一起,這點很重要因為 SOAP 就是要達到大范圍的協(xié)同工作。

表面看來,基于 XML 的模式本應(yīng)比基于二進制的慢,但它并不像表面那么簡單。首先,當(dāng) SOAP 被用于通過因特網(wǎng)發(fā)送消息時,在每個端點給消息編碼/解碼的時間與在端點間傳輸字節(jié)的時間相比較是微不足道的,所以這種情況下使用 XML 沒太大問題。

其次,當(dāng) SOAP 用于封閉環(huán)境下的點對點間的消息傳送,如在同一公司部門間的傳送時,各端點可能將運行相同的 SOAP 執(zhí)行。這樣,這個特定執(zhí)行就擁有專門的優(yōu)化機會。例如,一個 SOAP 客戶端可添加一個 HTTP header 標(biāo)記到 SOAP 請求上,這個請求說明它支持一個特定的優(yōu)化。如果 SOAP 服務(wù)器也支持那個優(yōu)化,它會在第一個 SOAP 響應(yīng)中返回一個 HTTP header 標(biāo)記,告訴客戶端可以在下面的通信中使用這種優(yōu)化。接下來,客戶端和服務(wù)器可以開始使用這種優(yōu)化了。

在我對 Apache 的實驗中,我通常在同樣的機器上得到每秒 30 次 Java 程序間的消息往返。我還評測過另一個 SOAP 執(zhí)行,它在同樣的配置下進行了每秒 700 次消息往返,所以改進的余地顯然很大。

傳遞對象

一旦建立和部署一個簡單的服務(wù)的最初興奮逐漸減弱,很多開發(fā)人員希望開始在客戶端和服務(wù)器間發(fā)送對象。實現(xiàn)這項任務(wù)至少有兩種方法。

如果能保證客戶端和服務(wù)器配置相同的專有擴展名,您就能使用任何想要的方法在機器間傳遞對象。例如,客戶端和服務(wù)器都在運行 Java 編程語言,它們可同意使用 Java 串行化來傳送對象。

另一方面,如果想要系統(tǒng)使用任意客戶端和服務(wù)器的組合,請在開始時為想要傳送的對象指定 XML 模式。然后確定客戶端和服務(wù)器都配置成可識別符合這些模式的 XML 文檔,并在需要時能將它們轉(zhuǎn)換為對象或從對象中轉(zhuǎn)換出來。例如,如果 C++ 客戶端想要傳送一個對象至 Java 服務(wù)器,客戶端必須能把 C++ 對象轉(zhuǎn)換到指定模式或從指定模式中轉(zhuǎn)換出,而服務(wù)器必須能把 Java 對象轉(zhuǎn)換到指定模式或從指定模式中轉(zhuǎn)換出。

通過包含一個特殊的映射注冊表,Apache SOAP 2.0 包含一個可以在 SOAP 引擎之間傳遞對象的靈活模式。您可以注冊自己的序列化對象來對數(shù)據(jù)加解碼。當(dāng)前的文檔對怎樣建立您自己的串行化的信息涉及較少,但還好它包含了一個有用的缺省 Java BeanSerializer,它可以串行化/去串行化任何符合 JavaBean 規(guī)范的類 -- 即它必須包含公共的缺省構(gòu)造函數(shù),并為它的所有屬性聲明公開的get/set方法。

下面的程序向您說明怎樣發(fā)送和接收對象。在 Tomcat 服務(wù)器上部署一個購買的Web 服務(wù),然后客戶端以值的形式發(fā)送一個發(fā)貨單對象。對象抵達服務(wù)器時被顯示出來,返回到客戶端時再被顯示。您也可以在 SOAP 下通過引用傳遞對象,我在本專欄的下一部分中將對此作解釋。

清單 4 至 7 給出了購買 Web 服務(wù)的源代碼樣本。

清單 4. IPurchasing.java 的代碼

public interface IPurchasing
{
Invoice receive( Invoice invoice );
}

清單 5. Purchasing.java 的代碼

public class Purchasing implements IPurchasing
{
public Invoice receive( Invoice invoice )
{
System.out.println( "got invoice " + invoice );
return invoice;
}
}

清單 6. Invoice.java 的代碼

public class Invoice
{
String name;
int amount;

public Invoice()
{
}

public Invoice( String name, int amount )
{
this.name = name;
this.amount = amount;
}

public String toString()
{
return "Invoice( " + name + ", " + amount + " )";
}

public void setName( String name )
{
this.name = name;
}

public String getName()
{
return name;
}

public void setAmount( int amount )
{
this.amount = amount;
}

public int getAmount()
{
return amount;
}
}

清單 7. Client2.java 的代碼

運行程序,需要執(zhí)行如下步驟:

把以下的 Java 文件復(fù)制到一個新的目錄:demo2 中,并把 demo2 加到您的 CLASSPATH 上。

編譯源文件。

同前,運行 TCP tunneling GUI,偵聽在 8070 端口和 8080 端口傳遞的消息。

在 demo2 目錄下啟動 Tomcat。

打開瀏覽器,輸入 URL
http://localhost:8080/soap

使用管理界面來部署一個購買服務(wù)。輸入以下值:

ID=urn:demo2:purchasing
Scope=Request
Methods=receive
Provider Type=Java
Provider Class=Purchasing
Static=No
Number of Mappings=1
Encoding Style=SOAP
Namespace URI=urn:my_encoding
Local Part=Invoice
Java Type=Invoice
Java To XML Serializer=org.apache.soap.encoding.soapenc.BeanSerializer
XML To Java Deserializer=org.apache.soap.encoding.soapenc.BeanSerializer
運行客戶端。

Namespace URI 和 Local Part 值被 Apache SOAP 引擎作為 xsi:type 的屬性值。只要這些值不和任何其它您使用的映射沖突,它們是什么并不特別重要。

如果一切順利,您該看到圖 4 中 TCP GUI 的結(jié)果,以及圖 5 中客戶端的輸出。

圖 4:運行購買 Web 服務(wù)


圖 5:購買 Web 服務(wù)客戶端的輸出窗口


安全性

安全性是個復(fù)雜的問題,目前確保 SOAP 的安全性需要采取分層的方法。

在最低層,SOAP 消息可通過 HTTPS 傳遞。既然 HTTPS 使用 SSL 傳輸,這就確保被編碼消息內(nèi)容可以避免被竊聽,也確??蛻舳撕头?wù)器可互相驗證身份。如今,基于 SSL 的 SOAP 解決方案出現(xiàn)了,但安裝和配置還不太容易。

盡管 HTTPS 解決了對竊聽者屏蔽消息的問題,但對那種需要更佳安全性來認(rèn)證特殊用戶的特定 Web 服務(wù)的幫助并不大。很多 Web 服務(wù)需要用戶在一開始注冊期間獲得某種用戶/密碼組合,然后當(dāng)以后訪問時就使用這個認(rèn)證信息。IBM、Microsoft 和 Ariba 在線托管的 UDDI Web 服務(wù)注冊表就是需要用戶在使用發(fā)布服務(wù)前先注冊的 Web 服務(wù)例子。還沒有標(biāo)準(zhǔn)規(guī)定 Web 服務(wù)如何支持注冊和認(rèn)證,但毫無疑問這個標(biāo)準(zhǔn)很快就會有了。Microsoft 和 Verisign 最近宣布了他們正在研究一個標(biāo)準(zhǔn),叫做 XML 密鑰管理規(guī)范 (XKMS),他們將把它遞交給標(biāo)準(zhǔn)體系以便有可能運用于 SOAP 和其它系統(tǒng)的整合中(請參閱參考資料)。

我打算在此欄目的今后部分中投入更多時間討論安全性的話題,到時希望在安全標(biāo)準(zhǔn)方面有所進展。

下一部分

在下一部分中,我將介紹 WSDL (Web 服務(wù)描述語言)和 UDDI (通用描述、發(fā)現(xiàn)和集成)這兩個重要的標(biāo)準(zhǔn),它們將有助于推動 Web 服務(wù)技術(shù)進入主流舞臺。

參考資料

  • 在第 1 部分中,Graham 討論了構(gòu)建 Web 服務(wù)應(yīng)用來啟用對等分布式網(wǎng)絡(luò)的好處和挑戰(zhàn)。
  • 在第 2 部分中,Graham 循序漸進地解釋如何開發(fā) Web 服務(wù),包括需要什么工具、如何安裝這些工具、如何編寫代碼以及如何部署服務(wù)。
  • 第4部分:Web 服務(wù)描述語言 (WSDL)
  • 請瀏覽 http://www.w3.org/TR/xmlschema-0/,獲取關(guān)于 XSI 和 XSD 模式的基礎(chǔ)讀物。
  • 請瀏覽 http://www.w3.org/TR/SOAP/,獲取 SOAP 1.1 規(guī)范。
  • 請閱讀 Microsoft/Verisign 公告。
  • Http://www.uddi.org/ 是 UDDI 的主要網(wǎng)站。

關(guān)于作者

Graham Glass 是 The Mind Electric 的創(chuàng)始人、CEO 和首席設(shè)計師。該公司設(shè)計、構(gòu)建和特許前瞻性的分步式計算基礎(chǔ)設(shè)施。他相信,因特網(wǎng)的演變將反映出生物思維的演變,協(xié)助人們和企業(yè)有效聯(lián)網(wǎng)的體系結(jié)構(gòu)能幫助人們理解將人腦聯(lián)結(jié)在一起的體系結(jié)構(gòu)。
在創(chuàng)建 The Mind Electric 之前,Graham 是 ObjectSpace 的主席、CTO 和聯(lián)合發(fā)起人之一。該公司總部位于達拉斯,專門從事商家到商家的集成。Graham 還是 ObjectLesson(一家提供前沿技術(shù)培訓(xùn)的公司)的創(chuàng)辦人。他為 Prentice Hall 撰寫了兩本有關(guān) UNIX 和 STL 的書籍,并以他對新興技術(shù)的熱情和清晰闡述而成為受歡迎的演說家??赏ㄟ^
graham-glass@mindspring.com 和他聯(lián)系。

瀏覽:Web服務(wù)的(革)創(chuàng)新,第1部分

Web服務(wù)的(革)創(chuàng)新,第2部分

Web服務(wù)的(革)創(chuàng)新,第4部分

發(fā)布:2007-03-25 13:27    編輯:泛普軟件 · xiaona    [打印此頁]    [關(guān)閉]
相關(guān)文章:
石家莊OA系統(tǒng)
聯(lián)系方式

成都公司:成都市成華區(qū)建設(shè)南路160號1層9號

重慶公司:重慶市江北區(qū)紅旗河溝華創(chuàng)商務(wù)大廈18樓

咨詢:400-8352-114

加微信,免費獲取試用系統(tǒng)

QQ在線咨詢