使用開放源代碼框架的 Java 應用程序的 Web 服務集成模式,第 2 部分: 實現接收模式

級別: 中級

Sukriti Goel ([email protected]), 技術架構師, Infosys Technologies Limited
Parameswaran Seshan ([email protected]), 技術架構師, Infosys Technologies Limited

2006 年 8 月 28 日

本系列討論 Web 服務集成模式,包含兩個部分,本文爲第 2 部分,將討論如何將要求-響應和通知 Web 服務客戶端端點模式與應用程序集成。在要求-響應和通知模式中,應用程序充當 Web 服務,將部署到 Web 服務器上,允許外部參與者將應用程序作爲 Web 服務調用。本文中的步驟採用 Document 樣式的 Web 服務調用。

引言

第 1 部分中,我們討論瞭如何將請求-響應和單向模式應用於 Web 服務端點。在這第 2 部分中,您將瞭解到如何將其他兩種模式(要求-響應和通知)應用於 Web 服務客戶端(調用端)端點。讓我們考慮這樣一個應用程序集成場景示例:假定有一個應用程序,比如旅行預訂應用程序 ("App1"),該應用程序包括各種組件。作爲我們討論的參照點,該應用程序接受來自客戶的輸入,例如旅行的出發地、目的地和信用卡信息。然後,該應用程序通過與其他應用程序(如信用驗證系統 ("App2"))集成進行訂票。此外,需要一個付款應用程序 ("App3")。App2 公開一個 Web 服務來驗證信用卡,而 App3 通過從信用卡中扣除相應金額來處理付款。App1 公開兩個 Web 服務;一個 Web 服務從 App3 接收消息(用於處理付款的確認請求)作爲輸入,接着發送確認(“繼續”)消息,另一個 Web 服務從 App3 接收“付款已完成通知”消息。

在要求-響應模式中,端點是一個客戶端,它將消息發送到預期返回響應的服務端點,並接收從該服務端點返回的相關消息。在我們的示例中,當 App3 準備好處理付款請求並且 App1 返回確認(“繼續付款”)消息時,App3 調用 App1 公開的“付款請求確認”Web 服務。對於此處討論的應用程序 App3,這是要求-響應操作。

在通知模式下,扮演將消息發送到服務端點的客戶端的角色的端點並不期望從該服務端點返回響應。在本示例中,“通知付款完成”Web 服務由 App1 公開,而由 App3 在處理付款之後調用。對於 App3,這是通知操作。

在另一方面,對於 App2 的信用驗證 Web 服務(App2 接受信用卡信息作爲輸入,以此對信用卡進行驗證,併發送一條響應消息,告知該信用卡被批准或被拒絕),這是訂票應用程序 App1 調用該服務時的請求-響應操作。類似地,對於付款應用程序 App3 公開的“付款”Web 服務,這是 App1 調用該服務時的單向操作,因爲 App1 可以在發送該消息後繼續執行一些其他任務。

從應用程序 App1 的角度來看,我們將基於要求-響應模式與外部應用程序 App3 的集成看作“同步服務”類型的活動,而將通知看作“異步接收”類型的活動。也就是說,在要求-響應和通知中,我們的參照點應用程序 App1 成爲服務提供者(服務端點),並接收來自客戶端的消息。

在本文中,您將瞭解如何在此類應用程序(假定基於 Java™)中實現這兩種模式來接收 Web 服務。





回頁首


Web 服務實現的開放源代碼框架

Web 服務和客戶端可以使用各種開放源代碼框架實現。對於本文,我們將使用 Apache Axis 開放源代碼框架來實現 Web 服務,同時還要結合使用 Java Architecture for XML Binding [sg3] (JAXB[I2]) 和 Java Message Service (JMS)。

應用程序客戶端端點發出的請求

在此部分,您將瞭解如何在應用程序中爲基於簡單對象訪問協議(Simple Object Access Protocol,SOAP)的 Web 服務操作實現同步服務和異步接收模式。對於此討論,我們將假定使用 Document 樣式的 Web 服務調用。如果外部客戶端通過嚮應用程序發送消息來參與應用程序處理,同步服務和異步接收將尤爲有用。

同步服務

對於同步服務的情況,應用程序充當服務實現端點,而外部參與者則是調用其公開的服務的客戶端。同步服務的一個例子是外部監視系統。外部監視系統可以發送請求,以瞭解應用程序處理的狀態,而應用程序可以提供狀態信息。

如 Web 服務描述語言(Web Services Description Language,WSDL)語法所定義的,要求-響應操作包含輸入和輸出元素,首先輸出,然後輸入,如清單 1 中所示。


清單 1. 要求-響應操作的 WSDL
        
<wsdl:definitions .... >
    <wsdl:portType .... > *
        <wsdl:operation name="nmtoken" parameterOrder="nmtokens">
           <wsdl:output name="nmtoken"? message="qname"/>
           <wsdl:input name="nmtoken"? message="qname"/>
           <wsdl:fault name="nmtoken" message="qname"/>*
        </wsdl:operation>
    </wsdl:portType >
</wsdl:definitions>
      

在本例中,應用程序將針對每個應用程序要求公開一個 Web 服務 (SOAP)。服務需要從外部客戶端接收輸入參數,並將輸出參數返回到它,同時在 WSDL 中對此進行定義。這些輸出參數通常是一些有關應用程序狀態的參數,從外部連接到應用程序的客戶端需要從應用程序獲取此狀態。此 WSDL 將提供給希望調用此服務的客戶端,以提供有關輸入消息、輸出消息和提供服務的 HTTP 端口或 JMS 端口的詳細信息。此 Web 服務可以支持使用 SOAP over HTTP 或 JMS 作爲傳輸協議。

應用程序可以使用 Apache Axis 服務器來實現這種異步服務類型的活動。Web 服務將在 Axis 服務器上運行一次(在應用程序安裝期間)。服務實現類也是應用程序的一部分。

當外部客戶端調用此服務時,Axis 服務器引擎將接收 SOAP 請求消息,並將在請求消息中接收到的參數作爲 Element (org.w3c.dom.Element) 對象數組提供給服務實現類的方法。此方法必須對 Java 對象綁定使用 XML,因此實際對其使用的是 JAXB。通過使用 JAXB,將構造與輸入 XML 元素對應的 Java 對象,並將其放入到 HashMap 中。然後將調用應用程序的 API 方法,並提供此 HashMap 作爲輸入。此 API 方法從應用程序獲取調用方所需的信息,並構造一個 HashMap,將此信息作爲輸出參數對象放置到 HashMap 中。此 HashMap 將返回到服務實現方法。同時,應用程序將繼續進行處理。爲了更好地理解這一點,請參見清單 2 中給出的示例代碼。

服務實現方法使用 JAXB 在 HashMap 中進行 Java 到 XML 的綁定,以便將其轉換爲 org.w3c.dom.Element 數組形式的 XML 元素。此 Element 數組是調用方的輸出參數集,將返回到 Axis 服務器。接下來,Axis 服務器將使用這組輸出參數 Elements 構造對 SOAP 消息的響應,並將響應消息發送回外部客戶端。


清單 2. 作爲 Web 服務公開的服務實現方法 GetActivityState
        
public Element[] getActivityState(Element[] inElements)
{
	Element[] retElements;
	String activityName = null;
	String requestOperation = null;
	
	if ((inElements[0].getChildNodes().getLength() == 1) && 
			inElements[0].getFirstChild().getNodeType() == Node.TEXT_NODE)
	{
		activityName = inElements[0].getFirstChild().getNodeValue();
	};
	
	if ((inElements[1].getChildNodes().getLength() == 1) && 
			inElements[1].getFirstChild().getNodeType() == Node.TEXT_NODE)
	{
		requestOperation = inElements[1].getFirstChild().getNodeValue();
	};
	
	ApplicationAPI appAPI  = ApplicationAPIFactory.getInstance().getApplicationAPI();
	if (requestOperation.equalsIgnoreCase("getActivityData"))
	{
		HashMap retData = appAPI.getDataFromActivity(activityName);
	}
	
	// use JAXB to convert each object value in the HashMap to 
	// its corresponding Element object. Populate the 
	// array of Element objects retElements with these Element objects.
	return retElements;
}

在前面的場景中,服務實現方法還可以查看輸入 XML Element 數組,並確定需要調用應用程序中的哪個 API 方法(具體取決於外部客戶端所請求的信息類型)。例如,即使支持不同類型的監視請求,一個具有唯一方法實現的類可以支持不同類型的請求。但在 Axis 服務器中可以部署多個服務,一個服務與一種請求類型對應,而所有這些服務以及輸入和輸出消息的詳細信息可以在發佈到外部客戶端的一個 WSDL 中定義。

對於 JMS 傳輸的情況,應用程序可以使用 OpenJMS 服務器(JMS 實現)來處理 JMS 消息(其中包含 SOAP 消息作爲內容)。將在 OpenJMS 服務器中爲應用程序公開的每個 Web 服務打開單個隊列,併爲此隊列創建一個消息偵聽器(此操作將在應用程序啓動時進行一次)。正如在前面的段落中所討論的,如果應用程序公開多個服務,而僅有一個用於所有這些服務的服務實現方法和類,則每個隊列的消息偵聽器都將綁定到該應用程序公開的一個服務。在隊列中接收到任何消息時,消息偵聽器將調用 Axis 引擎,並在所綁定到的服務的引擎中設置了相應的服務名稱(即與上面爲 HTTP 服務定義的相同的服務名稱)後將 SOAP 請求消息提供給它。然後,該引擎將調用此服務方法(即在前一段中描述的同一方法)。

異步接收

在本例中,應用程序將充當服務實現端點,而外部客戶端將發送應用程序所使用的消息。沒有響應發送回外部客戶端。外部客戶端將 SOAP 請求消息發送到 Web 服務後,並不等待任何響應。它將繼續隨後的處理。如果外部客戶端需要控制某些應用程序處理,異步接收將特別有用。例如,外部客戶端可以觸發應用程序中的流程;它還可以使應用程序結束處理或停止,如清單 3 中所示。

如 WSDL 語法中所定義的,通知操作僅具有輸出元素。


清單 3. 通知操作的 WSDL
        
<wsdl:definitions .... >
    <wsdl:portType .... > *
        <wsdl:operation name="nmtoken">
           <wsdl:output name="nmtoken"? message="qname"/>
        </wsdl:operation>
    </wsdl:portType >
</wsdl:definitions>
      

外部客戶端可以通過 JMS 傳輸向 Web 服務發送 SOAP 請求;此請求爲單向消息。Web 服務在 Axis 服務器上公開,將在應用程序啓動期間在 OpenJMS 服務器上設置 JMS 接收隊列。此模式的實現與同步服務部分所描述的涉及 JMS 的同步服務的實現一樣,只是在調用應用程序的 API 方法後,服務實現方法並不從 API 方法接收任何輸出參數(一個通知)。API 方法將按照從外部客戶端接收的輸入參數中請求的方式對應用程序狀態執行相關操作。

結束語

在本文中,我們討論了 Web 服務客戶端端點的要求-響應模式和通知模式,並瞭解瞭如何使用與開放源代碼框架有關的相應 Web 服務來支持將應用程序與基於這兩種模式的客戶端集成。

通過使用相應的框架(如 Axis、JAXB)和傳輸協議(如 HTTP 或 JMSWeb),可在單個 Java 應用程序的上下文中實現 Web 服務的四種服務端點模式。

您在本系列中學習的方法均來自我們在流程引擎的上下文中實現這四種 Web 服務模式的經驗。我們希望和您分享在實現這些 Web 服務模式時所遇到的挑戰,並向您提供我們所獲得的解決方案。 

本文來源:developerworks 中國

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章