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

無SOAP的Web服務,第二部分

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

AMTeam.org

無SOAP的Web服務,第二部分

--“Web 服務調(diào)用框架”的體系結構,WSIF 的體系結構


Nirmal K. Mukhi(nmukhi@us.ibm.com),副研究員,IBM Research

Aleksandor Slominski(
aslom@indiana.edu),研究助理,IU Extreme! Lab,Indiana University

2001 年 9 月

在前面的文章中介紹了 WSIF,說明了它怎樣為簡化的 Web 服務調(diào)用提供獨立于綁定的 API。這篇文章將看看一些高級的 WSIF 功能。這將需要對其體系結構有一個概述,接下來您將看到怎樣開發(fā)多服務綁定,以及怎樣給 Web 服務更新和添加新的綁定實現(xiàn)。

“Web 服務調(diào)用框架”(Web Services Invocation Framework(WSIF))是為調(diào)用 Web 服務提供簡單 API 的工具箱,而不管服務怎樣提供或由哪里提供。在前面的文章中(請參閱參考資料),我們討論了對 WSIF 的需要、其設計背后的思想以及描述了一些主要的功能。我們比較了 WSIF 的由 WSDL 驅動的 API 和用于使用Web 服務的常規(guī) API,并且描述了端口類型編譯器和無存根調(diào)用。

WSIF 甚至還可以提供更多。其體系結構允許通過端口工廠(port factory)發(fā)現(xiàn)調(diào)用端口。我們可以使用定制的綁定實現(xiàn)進行服務調(diào)用的調(diào)用端口,并且將它們插入到框架中。我們也可以設計我們自己的端口工廠,這樣使用定制的算法能夠查找或創(chuàng)建調(diào)用端口。最后,對于消息內(nèi)用到的數(shù)據(jù),WSIF 允許我們使用任何本機類型系統(tǒng)。在這篇文章中,我們將描述啟用這些功能的 WSIF 的體系結構方面,并且討論利用這種靈活體系結構的特定方法。

WSIF 的體系結構

WSIF 通過以下步驟調(diào)用服務操作:

裝入 WSDL 文檔。

為服務創(chuàng)建一個端口工廠。

該端口工廠用來檢索服務端口。

如果需要,通過使用根據(jù)某個本機類型系統(tǒng)定型的消息部件創(chuàng)建消息。

通過給該端口提供待調(diào)用操作的名稱以及操作需要的一個輸入和/或輸出消息進行調(diào)用。

WSIFPort

這里關鍵的抽象是 WSDL 端口的運行時表示,稱之為 WSIFPort。它負責在特殊綁定的基礎上進行實際調(diào)用。例如,為了調(diào)用抽象服務操作,我們要有 WSIFSOAPPort,它能使用為此服務在 WSDL 中指定的 SOAP 綁定。該體系結構的靈活性集中在清單 1 中所示的 WSIFPort 接口上。

清單 1:WSIFPort 接口

public interface WSIFPort {
public boolean executeRequestResponseOperation (String op,
WSIFMessage input,
WSIFMessage output,
WSIFMessage fault)
throws WSIFException;
// some other methods not specified here
}

這個接口的實現(xiàn)將必須知道使用指定的抽象輸入和輸出消息怎樣調(diào)用操作。如果基于 Apache SOAP API,WSIFPort 的 SOAP 實現(xiàn)可以根據(jù)來自該服務 WSDL 文檔的 SOAP 綁定信息創(chuàng)建一個 Call 對象,然后使用抽象輸入消息創(chuàng)建調(diào)用必需的參數(shù)??梢杂?SOAP 響應來植入隨后可由客戶機檢查的抽象輸出消息。

WSIFPortFactory

WSIFPortFactory 負責檢索用于特殊調(diào)用的 WSIFPort。它具有清單 2 所描述的接口。

清單 2:WSIFPortFactory 接口

public interface WSIFPortFactory {
public WSIFPort getPort () throws WSIFException;
public WSIFPort getPort (String portName) throws WSIFException;
}

請注意不帶參數(shù)的 getPort 版本允許該接口實現(xiàn)有某個定制的算法來選擇用于調(diào)用的 WSIFPort。WSIF 分發(fā)包有該接口的兩個實現(xiàn):靜態(tài)端口工廠和動態(tài)端口工廠。靜態(tài)端口工廠存儲 WSIFPort 對象列表,并且當發(fā)出 getPort() 時,以偽隨機方式返回其中一個對象。動態(tài)端口工廠存儲動態(tài)提供者列表。這些提供者中的每一個能夠根據(jù)服務的 WSDL 信息在運行時創(chuàng)建 WSIFPort。當在動態(tài)端口工廠調(diào)用 getPort() 時,工廠將以偽隨機方式選擇動態(tài)提供者,使它能創(chuàng)建接著返回的 WSIFPort。端口工廠體系結構的整體視圖如圖 1 所示。

圖 1:WSIF 端口/端口工廠體系結構


WSIF 部件

到此為止我們討論了 WSIF 端口怎樣從特定的實現(xiàn)分離出來以及怎樣用端口工廠來發(fā)現(xiàn)和創(chuàng)建端口。端口使我們能夠建立調(diào)用,但是實施調(diào)用本身之前基本的一步是創(chuàng)建操作所需的消息。WSDL 中的消息由綁到某個類型系統(tǒng)的命名部件組成。典型情況下,將 XML 模式用作類型系統(tǒng)為 WSDL 部件定型。這獨立于語言,非常強大。通過將這種模式類型映射到更方便的類型系統(tǒng)以及允許在屬于該類型系統(tǒng)和模式類型的對象之間進行轉換,從客戶機調(diào)用這種服務。例如,當 Java 是本機類型系統(tǒng)時,使用設計為具有明確目的類,通過序列化和反序列化完成 Java 和模式之間的轉換。

將 WSIF 的部件體系結構設計為任何本機類型系統(tǒng)可用于消息部件,并允許相同消息內(nèi)的部件用不同的類型系統(tǒng)定型。在必須將來自兩個或多個獨立的 WSDL 消息(和不同的本機類型系統(tǒng)相關聯(lián))組合到單一消息中時,后者是必需的。除了允許有不同的本機類型系統(tǒng),還需要有解釋消息部件的通用的方法,這樣就可能統(tǒng)一地查看 WSIF 消息對象。WSIF 采取的方法是模式為消息部件所用的標準抽象類型,并且所有這樣的模式類型有相應的 JavaBean(可以使用將模式轉換到 Java 的規(guī)范映射進行定義)。這給出了 WSIF 部件通用的類型系統(tǒng)。因此 WSIFPart 接口看似如清單 3 所示。

清單 3:WSIFPart 接口

public interface WSIFPart {
public Class getJavaType ();
public Object getJavaValue ();
}

只要能將這些表示轉換為相應的規(guī)范 Java 類型,該接口的特定實現(xiàn)就可以使用任何一個內(nèi)部類型系統(tǒng)。由 WSIF 提供的唯一 WSIFPart 接口實現(xiàn)是使用 Java 作為類型系統(tǒng)的 WSIFJavaPart。還有別的實現(xiàn)能夠利用通用使用模式來提高效率。例如,請考慮在所用的最通用的綁定中與在文檔風格 SOAP 綁定中一樣,涉及 XML 文檔交換。此處,將部件值表示為文字的 XML 而不是 Java 對象將非常高效,當使用文檔風格 SOAP 綁定進行調(diào)用時,可以不需要解析或序列化/反序列化。

修改綁定選擇算法

綁定選擇算法的修改非常直截了當。所有開發(fā)者必須做的是編寫他們自己的 WSIFPortFactory 實現(xiàn),或擴展現(xiàn)有的實現(xiàn)。請考慮 WSIFDynamicPortFactory。它存儲動態(tài)提供者列表,該列表根據(jù)需要給特殊的 WSDL 綁定生成一個 WSIFPort。例如,這個端口工廠根據(jù)提供者類型查找動態(tài)提供者,這樣它知道哪一個動態(tài)提供者處理 SOAP 端口,哪一個處理我們可能定義的 CORBA 端口,等等。我們可以用我們自己的 getPort() 方法擴展該端口工廠來選擇需要的端口。為了說明這是有幫助的情況,請考慮清單 4 中的地址簿 Web 服務。

清單 4:地址簿 Web 服務


xmlns:tns="
http://www.ibm.com/namespace/wsif/samples/ab"
xmlns:typens="
http://www.ibm.com/namespace/wsif/samples/ab/types"
xmlns:xsd="
http://www.w3.org/1999/XMLSchema"
xmlns:soap="
http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:java="
http://schemas.xmlsoap.org/wsdl/java/"
xmlns="
http://schemas.xmlsoap.org/wsdl/">















transport="
http://schemas.xmlsoap.org/soap/http"/>



namespace="
http://www.ibm.com/namespace/wsif/samples/ab"
encodingStyle="
http://schemas.xmlsoap.org/soap/encoding/"/>


namespace="
http://www.ibm.com/namespace/wsif/samples/ab"
encodingStyle="
http://schemas.xmlsoap.org/soap/encoding/"/>





namespace="
http://www.ibm.com/namespace/wsif/samples/ab"
encodingStyle="
http://schemas.xmlsoap.org/soap/encoding/"/>


namespace="
http://www.ibm.com/namespace/wsif/samples/ab"
encodingStyle="
http://schemas.xmlsoap.org/soap/encoding/"/>









>





該服務提供兩種綁定:HTTP 之上的 SOAP 和本機 Java。在 WSDL 中直接綁定 Java 類沒有標準的方法,但是這只會造成理解上的障礙,因此我們不再贅述。給定該服務多綁定的可用性,客戶機將希望使用可能提供最好性能(比如 Java 綁定)的一個,大概因為它包含抽象操作到 Java 方法調(diào)用直接轉換,而不需要網(wǎng)絡、序列化/反序列化等操作。當然,Java 綁定只在部署了服務的環(huán)境可用。不象 SOAP 綁定,它不能在因特網(wǎng)上公用。因此我們希望做的是當可以時選擇 Java 綁定,而在其它情況下使用 SOAP 綁定。如清單 5 所示,可以通過編寫我們自己的 WSIFPortFactory 來實現(xiàn)。

清單 5:定制的綁定選擇算法(請參閱參考資料以獲取全部代碼)

public class MyWSIFPortFactory extends
WSIFDynamicPortFactory {
public WSIFPort getPort () throws WSIFException {
WSIFException ex = null;
WSIFPort portInstance = null;
// examine list of available ports
// do we have a port with a Java binding?
for(int i = 0; i < myPortsArr.length; ++i) {
try {
Port port = myPortsArr[i];
Binding binding = port.getBinding();
if (binding instanceof JavaBinding) {
// attempt to create a port that can
// make invocations using this binding
portInstance =
createDynamicWSIFPort(def, service, port);
if(portInstance != null) {
return portInstance;
}
}
} catch(WSIFException wex) {
if(ex == null) {
ex = wex;
}
}
}
// unable to create a port that can invoke a Java
// binding (why? perhaps there is no Java port
// for this service, or the Java port cannot be
// created for invocation since we are not in
// an environment that has access to the resources
// that the Java binding uses)
// use WSDL ports with other
// bindings for invoking the service
// Full code not shown here due to length.
// Please see the Resources section at the end of
// this article to download the actual code.
}
}

如果您下載了清單 5 中示例的全部代碼(參考資料部分中可得到),您應該仔細查看下面的指導說明來執(zhí)行它:

將 zip 壓縮文檔解壓縮到某個目錄(本例我們使用 C:Forge)。它將創(chuàng)建一個子目錄,比如 C:Forgetwsif-1.0-my-factory。
當您準備好編譯這個示例時,務必包括 WSIF 文檔中描述的所有必需的 JAR 文件。
編譯 C:FORGEwsif-1.0-my-factorysamples 中的樣本源代碼,然后將包含已編譯的 Java .class 文件的這個目錄添加到 CLASSPATH 環(huán)境變量中。

當它完全編譯成功時,在命令行運行清單 6 中的第一個命令。它使用本地示例文件,并且利用修改的動態(tài)調(diào)用器。

清單 6:本地應用程序中的動態(tài)調(diào)用

C:jdk1.3binjava.exe -classpath ".;C:Forgewsif-1.0-my-factorysamples;
C:Forgewsif-1.0samples;C:Forgewsif-1.0samplesgenerated;
C:Forgewsif-1.0samplesgenerated;C:Forgexml-soapxml_soap22.jar;C:Forge
jaxp-1.1jaxp.jar;C:Forgejaxp-1.1crimson.jar;C:Forgejavamail-1.2mail.jar;
C:Forgejaf-1.0.1activation.jar;C:Forgewsif-1.0libwsif-all-1.0.jar"
clients.MyDynamicInvoker samplesservicesstockquoteStockquote.wsdl
getQuote IBM
Reading WSDL document from 'samplesservicesstockquoteStockquote.wsdl'
Preparing WSIF dynamic invocation
DEBUG: examining for selection port SOAPPort
DEBUG: selected soap port SOAPPort
DEBUG: examining for selection port JavaPort
DEBUG: selected java port JavaPort
Preffered port name 'JavaPort'
Executing operation getQuote
Result:
quote=90.05
Done!

清單 7 展示了第二個使用 WSDL 的示例,來自 Web 服務站點 Xmethods.net 而不是本地示例文件。

清單 7:跨網(wǎng)絡的動態(tài)調(diào)用

C:jdk1.3binjava.exe -classpath ".;C:Forgewsif-1.0-my-factorysamples;
C:Forgewsif-1.0samples;C:Forgewsif-1.0samplesgenerated;
C:Forgewsif-1.0samplesgenerated;C:Forgexml-soapxml_soap22.jar;
C:Forgejaxp-1.1jaxp.jar;C:Forgejaxp-1.1crimson.jar;
C:Forgejavamail-1.2mail.jar;C:Forgejaf-1.0.1activation.jar;
C:Forgewsif-1.0libwsif-all-1.0.jar" clients.MyDynamicInvoker
http://services.xmethods.net/soap/urn:xmethods-
delayed-quotes.wsdl getQuote IBM
Reading WSDL document from 'http://services.xmethods.net/soap/urn:xmethods-delayed-quotes.wsdl'
Preparing WSIF dynamic invocation
DEBUG: examining for selection port net.xmethods.services.stockquote.StockQuotePort
DEBUG: selected soap port net.xmethods.services.stockquote.StockQuotePort
Preffered port name 'net.xmethods.services.stockquote.StockQuotePort'
Executing operation getQuote
Result:
Result=90.0
Done!

在運行時更新/添加綁定實現(xiàn)

假如我們想要升級 SOAP 實現(xiàn)。使用該體系結構,我們可以不必重編譯用戶代碼或存根代碼完成到新的實現(xiàn)的遷移,因為 WSIF API 將保持不變。我們將編寫新的 WSIFPort 實現(xiàn),能夠使用由新的 SOAP 實現(xiàn)提供的修改過的 SOAP 客戶機 API 進行調(diào)用。接著,我們編寫將 WSDL SOAP 接口轉換到新的 WSIFPort 實現(xiàn)的動態(tài)提供者。一旦我們注冊了這個新的動態(tài)提供者,它將代替以前注冊的 SOAP 動態(tài)提供者,并且將通過新的 WSIFPort 實現(xiàn)進行所有 WSDL SOAP 端口調(diào)用。

請考慮一下我們定義我們自己的 WSDL 綁定的情況。首先,我們必須確保 WSIF 運行時能夠裝入帶有新的綁定的 WSDL 文檔;這需要我們?yōu)榭蓴U展性元素定義處理程序,這些元素是使用 WSDL4J(請參閱參考資料)的擴展注冊中心 API 添加到我們的 WSDL 中的元素。我們將不深入到這怎樣實現(xiàn)的細節(jié)中。然后我們可以編寫 WSIFPort 和動態(tài)提供者實現(xiàn),以更新 SOAP 綁定同樣的方式向端口工廠注冊新的動態(tài)提供者。

存根體系結構

我們可以從這種體系結構得到的最重要的好處是:它使我們能夠得到可由受管環(huán)境定制的客戶機存根。所有 WSIF 存根擴展清單 8 指定的基本類。

清單 8:WSIFStub 基本類

// some methods and other details omitted
public abstract class WSIFStub {
/**
* Locates a port factory using JNDI if available,
* otherwise uses dynamic port factory with
* pre-registered dynamic providers
*/
protected void locatePortFactory(.....) {
.....
}
/**
* Initializes stub with ports defined in WSDL document
* document must contain *exactly* one service and all
* ports must implement one and only one port type.
*/
protected void initializeFromLocation (...) {
.....
}
/**
* Return the port currently being used.
*/
public WSIFPort getPort () {
return wp;
}
/**
* Return the port factory currently being used.
*/
public WSIFPortFactory getPortFactory () {
return wpf;
}
/**
* Create a new proxy using the given WSIFPortFactory.
*/
public void setPortFactory (WSIFPortFactory wpf) {
.....
}
/**
* Create a new proxy pre-configured to use the given port
* for interacting with the service.
*/
public void setPort (WSIFPort wp) {
.....
}
/**
* Select the port to use by giving the name of the port
* that is desired. If a port of that name cannot be retrived from
* the port factory than an exception will be thrown. The port
* I use will only be updated if this method is successful.
*/
public void selectPort (String portName) {
.....
}
}

這種體系結構給了我們巨大的好處。在允許受管環(huán)境順著模式作出改變的同時,它使應用程序能夠使用同一存根,而不必重新編譯任何東西。請考慮清單 5 中的例子,我們使用定制的綁定選擇算法編寫了我們自己的端口工廠。如果我們在應用程序服務器環(huán)境操作 JNDI,我們可以將該端口工廠實現(xiàn)綁定到恰當?shù)闹付ǖ?JNDI 環(huán)境。當存根在初始化期間查找端口工廠時,它將得到新的實現(xiàn)。當然,我們可以通過直接調(diào)用存根上的 setPortFactory 方法強制在存根所使用的端口工廠進行改變(如果這是我們想要做的),或者我們可以通過使用存根的 setPort 方法強制使用特殊端口。

總結

隨著 Web 服務持續(xù)發(fā)展,使用 SOAP 之外的協(xié)議訪問服務端點將變得很普遍。因此當我們編寫使用 Web 服務的應用程序時,我們需要工作在 WSDL 級而不是在 SOAP 級的 API。

WSIF 提供了著眼于 Web 服務調(diào)用的抽象方式,這樣我們可以使用不受綁定束縛的調(diào)用 API 編寫應用程序。WSIF 有生成可定制存根的端口類型編譯器;WSIF API 足夠簡單,以至于應用程序能夠通過直接使用它來進行無存根調(diào)用。WSIF 的體系結構能夠以靈活的方式定義定制端口和端口工廠,并且也使被創(chuàng)建的消息能夠使用任何本機類型系統(tǒng)。在存根用來進行調(diào)用的端口或端口工廠中,對于受管環(huán)境(比如應用程序服務器),生成的存根有入口點來進行運行時修改。

Web 服務需要獨立于綁定的可擴展調(diào)用框架,WSIF 是朝該方向邁出的第一步。

參考資料

  • 請參加關于這篇文章的討論論壇。
  • 請閱讀介紹性文章,它討論了 WSIF 怎樣促成當前 Web 服務調(diào)用模型的改進,并且描述了 WSIF 的一些主要功能。
  • 您可以從此處下載本文清單 5 的所有代碼以及清單 6 和清單 7 中的示例。
  • 請下載 alphaWorks 上的 WSIF 分發(fā)包,并且試驗比較簡單的樣本。它將給您一個由 WSIF 支持的不同調(diào)用風格的第一手示例以及它優(yōu)于特定協(xié)議客戶機 API 的優(yōu)勢。
  • 重溫 WSDL 規(guī)范,看一看允許哪一種擴展;您也可以學習怎樣使用 WSDL 擴展機制定義用來訪問 Web 服務的 SOAP 綁定。
  • 重溫 SOAP 規(guī)范本身。
  • 如果以前您沒有對 Web 服務編過程,Web Services Toolkit 是很好的起點。
  • 請查看 WSDL4J,一個可擴展的 WSDL 分析框架,WSIF 在此基礎上進行構建。

關于作者

Nirmal K. Mukhi 是 IBM 的 T J Watson Research Lab 的“副研究員”,自 2000 年 11 月,他一直在從事各種 Web 服務技術的研究。他還對 AI、創(chuàng)造性編寫以及過時的計算機游戲感興趣。您可以通過
nmukhi@us.ibm.com 與 Nirmal 聯(lián)系。


Aleksander Slominski 是 Indiana University 的博士生,他是 IU Extreme! Lab 的研究助理,致力于實現(xiàn)“公共組件體系結構”的 XML/SOAP 啟用版。他還設計和實現(xiàn)了“XML 拖解析器”(XML Pull Parser),并且對 XML 的性能和可用性方面感興趣。在 2001 年夏天期間,他是 IBM 的 T J Watson Research Lab 的實習生,在那里他從事 WSIF 第一版的研究。您能夠通過 aslom@indiana.edu 和 Alek 聯(lián)系。

瀏覽:無SOAP的Web服務,第一部分

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

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

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

咨詢:400-8352-114

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

QQ在線咨詢