IBM WebSphere 開發者技術期刊: 使用 JMS 和 WebSphere ESB 構建強大而可靠的 SOA——

發表于:2007-05-25來源:作者:點擊數: 標簽:
Java Message Service (JMS) 對 J2EE 平臺上的可靠消息傳遞進行了標準化。最近發布的 IBM WebSphere Enterprise Service Bus (ESB) 產品提供了一些重要的功能,這些功能處于任何支持面向服務的體系結構的環境的核心位置。本系列中的三篇文章介紹了如何對 JMS
Java™ Message Service (JMS) 對 J2EE™ 平臺上的可靠消息傳遞進行了標準化。最近發布的 IBM® WebSphere® Enterprise Service Bus (ESB) 產品提供了一些重要的功能,這些功能處于任何支持面向服務的體系結構的環境的核心位置。本系列中的三篇文章介紹了如何對 JMS 消息傳遞和 WebSphere ESB 進行集成,作為其中的結束篇,本文描述了如何在 WebSphere ESB 中為中介流組件構建 JMS 自定義綁定。

摘自 IBM WebSphere 開發者技術期刊。

引言

第 1 部分中,我們介紹了企業服務總線 (ESB) 的概念,在第 2 部分中,我們演示了如何建立測試應用程序客戶端和提供程序。本系列中的三篇文章介紹了如何通過 JMS 和 IBM WebSphere ESB 建立服務提供者和使用者之間的連接,在最后這篇文章中,我們將研究如何使用帶有自定義 JMS 綁定的中介流組件來最終建立連接。

如果您還記得第 1 部分,我們曾討論過構成 WebSphere ESB 基礎的編程模型,即服務組件體系結構 (SCA)。在這個體系結構中,不同類型的組件都被看作服務,并且可使用相同的方式進行訪問。WebSphere ESB 中介流是這些組件類型中的一種。與任何 SCA 組件一樣,可以通過中介流所提供的導出對其進行訪問,并且中介流可以通過導入將消息轉發到其他的外部服務。JMS 的特殊類型的導入和導出,稱為JMS 綁定,允許用戶指定綁定配置并編寫自己的數據處理代碼。中介流本身包含一系列的中介基元,在消息通過總線時,可以使用這些中介基元對消息進行相應的操作。

另外兩篇 developerWorks 文章 Getting started with WebSphere Enterprise Service Bus and WebSphere Integration DeveloperDeveloping custom mediations for WebSphere Enterprise Service Bus 將向您介紹創建中介模塊的基本場景。在繼續學習本文之前,最好先閱讀(或至少是瀏覽)這些文章。

概括地說,最后的這篇文章將:

  • 介紹如何為 JMS 綁定編寫處理各種 JMS 消息類型的數據處理插件。
  • 說明如何建立充分利用自定義綁定代碼的導出和導入。
  • 描述使用 WebSphere Integration Developer 的一個簡單中介流的實現。
  • 將所有的內容組合到一個中介模塊中,您可以將這個中介模塊部署到 WebSphere ESB 運行時,并且這將允許您運行整個應用程序。

下載部分中包含了完整的項目交換 ZIP 文件,您可以將它導入到 WebSphere Integration Developer,并且其中包含了所有的代碼和運行該示例所需的其他內容。為了節省時間,并使得我們可以把主要精力放在接下來的主題,請在繼續學習本文前下載并導入這個文件。本文余下的內容假設您已完成了這項操作。在描述該解決方案中的各個部分時,我們將說明在導入了該文件后,每個部分位于 WebSphere Integration Developer 中的何處。





回頁首


JMS 自定義綁定

在為導入或導出創建 JMS 綁定時,您需要確定用來處理傳入和傳出消息的兩個 Java 類。一個類稱為函數選擇器,另一個類稱為 數據綁定。我們還需要定義用于入站和出站 JMS 流量的 JMS 隊列的名稱。讓我們更仔細地看看這些部分。

函數選擇器

與所有的 SCA 服務組件一樣,WebSphere ESB 中介具有一個接口。在 WebSphere ESB 中,將該接口表示為 WSDL PortType,這意味著每個中介流組件支持一項或多項操作(或方法,在此上下文中,這兩個術語表示相同的含義)。然而,JMS 消息僅包含數據,而不包含它想要進行的任何目標操作的指示。所以,我們需要將特定的 JMS 消息映射到目標服務接口的特定操作。這正是函數選擇器所完成的工作。

在我們的示例中,我們已經為每個 JMS 消息類型(可在 JMSCustomBindingLibrary/JMSCustomBindingInterface.wsdl 中找到)定義了具有一項操作的服務接口。例如,應該將 JMS 文本消息發送到 handleText() 操作,而將流消息發送到 handleStream() 操作等等。稍后您將看到,我們可以為不同的操作指定不同的數據綁定。

清單 1 顯示了我們的示例中函數選擇器的代碼段:


清單 1. 函數選擇器代碼段
public class SimpleJMSFunctionSelector implements FunctionSelector {
            public String generateEISFunctionName(Object[] arguments) {
            ... ...
            Message message = (javax.jms.Message) arguments[0];
            functionName = message.getJMSType();
            if (functionName == null) {
            if (message instanceof BytesMessage)
            messageBodyType = "Bytes";
            else {
            if (message instanceof TextMessage)}
            messageBodyType = "Text";
            ... ...
            functionName = "handle" + messageBodyType;
            ... ...
            }

請注意 generateEISFunctionName() 方法如何返回關聯于指定消息的函數(或操作,或方法)的名稱。在我們的示例中,函數名稱為“handle”加上該消息類型。例如,對于 JMS 文本消息,將返回“handleText”。換句話說,當中介接收到一個 JMS 文本消息時,會將它發送到 handleText() 方法。

(您可以在 JMSCustomBindingClasses 項目的 SimpleJMSFunctionSelector.java 文件中找到完整的源代碼。)

在導出的綁定屬性中,在 Connection 選項卡的高級設置下,對函數選擇器進行了定義,如圖 1 所示。


圖 1. 在 WebSphere Integration Developer 中對函數選擇器進行設置
圖 1. 在 WebSphere Integration Developer 中對函數選擇器進行設置

WebSphere Integration Developer 還提供了一個缺省的函數選擇器,稱為 com.ibm.websphere.sca.jms.selector.impl.JMSFunctionSelectorImpl,它從傳入的 JMS 消息的 Header 屬性 TargetFunctionName 處獲取指定的字符串值作為函數的名稱。

數據綁定

數據綁定的實現是 JMS 自定義綁定的關鍵部分。在導出綁定的情況下,這個數據綁定實現必須清楚每個傳入消息的格式和結構,并將其轉換為適合于該中介流的格式,即 SDO DataObject。在導入綁定的情況下,則進行相反的處理,也就是說,將傳出的 SDO DataObject 轉換為發送到外部服務的 JMS 消息。

SCA 要求每個服務組件都具有一個接口,該接口可以是一個 Java 接口,或者描述為 WSDL portType(WebSphere ESB MediationFlow 組件支持 WSDL 接口)。要接收任意的 JMS 消息作為中介流中的成員,我們必須定義表示這些消息的一組操作。例如,JMS 文本消息由下面的 WSDL portType 操作來表示:


清單 2. JMS 文本消息的 portType 操作
p<wsdl:portType name="JMSCustomBindingInterface">
            <wsdl:operation name="handleText">
            <wsdl:input message="wsdl1:JMSTextMessage"/>
            <wsdl:output message="wsdl1:JMSTextMessage"/>
            <wsdl:fault message="wsdl1:JMSTextMessage" name="TextFault"/>
            </wsdl:operation>
            ... ...
            </wsdl:portType>

(可以在 JMSCustomBindingLibrary 項目的 JMSCustomBindingInterface.wsdl 文件中找到完整的操作列表。)

在為導出或導入綁定定義了該接口之后,您需要提供處理 DataObject 和 JMS 之間轉換的數據綁定類。它可以是針對整個導出/導入的一個類,或者每個操作一個類。我們已經在接口中定義了幾項操作(每個 JMS 消息類型一項操作),因此我們定義了方法級的數據綁定,如圖 2 所示。


圖 2. 方法級數據綁定定義
圖 2. 方法級數據綁定定義

每個數據綁定類都必須實現 com.ibm.websphere.sca.jms.data.JMSDataBinding 接口。

在我們的測試應用程序中,共有 5 個 JMSDataBinding 實現:

  • JMSTextDataBinding
  • JMSBytesDataBinding
  • JMSStreamDataBinding
  • JMSMapDataBinding
  • JMSObjectDataBinding.

您可以在 JMSCustomBindingClasses 項目中找到它們的源文件和其他的實用工具類。

一個數據綁定實現必須提供對下列方法的實現:

  • setDataObject() 設置表示 JMS 消息有效負載的 DataObject 的值。DataObject 必須符合相應的模式定義。

  • getDataObject() 返回表示 JMS 消息有效負載的 DataObject,并且該對象符合相應的模式。

  • getMessageType() 返回 JMS 消息的類型(在 JMSDataBinding 接口中定義)。

  • read(Message message) 根據 JMS 消息設置 DataObject 屬性的值,JMS 消息作為方法參數提供。

  • write(Message message) 根據 DataObject 的屬性設置 JMS 消息有效負載的值,JMS 消息作為方法參數提供。

  • isBusinessException() 表示是否將該 JMSDataBinding 實例所表示的 DataObject 作為一項業務異常。

  • setBusinessException() 設置是否將該 JMSDataBinding 實例所表示的 DataObject 作為一項業務異常。


圖 3. 帶 JMS 綁定的 SCA 導入/導出的方法執行流
圖 3. 帶 JMS 綁定的 SCA 導入/導出的方法執行流

在圖 3 中,當 JMS 消息發送到該中介模塊(即導出)時發生 JMS-->SDO 流,而在該中介模塊(即導入)發送 JMS 消息時發生 SDO-->JMS 流。請注意,帶 JMS 綁定的導入的響應消息并沒有經過函數選擇器。

清單 3 顯示了 com.ibm.websphere.sibx.samp.jms.JMSTextDataBinding 類的部分源代碼,該類對所有傳入和傳出的 JMS 文本消息進行處理。


清單 3. JMSTextBinding 代碼示例
public class JMSTextDataBinding extends AbstractJMSDataBindingImpl
            implements JMSDataBinding {
            private String payload = null;
            private DataObject jmsData = null;
            public int getMessageType() {
            return JMSDataBinding.TEXT_MESSAGE;
            }
            public void read(Message message) throws JMSException {
            ... ...
            TextMessage textMessage = (TextMessage) message;
            payload = textMessage.getText();
            ... ...
            // construct a DataObject based on the schema definition for
            // "JMSTextMessage"
            jmsData = DataFactory.INSTANCE.create("com.ibm.ws.sib.mfp/schema","JMSTextBody");
            ... ...
            // set the "value" property to the String value of the message payload
            jmsData.setString("value", payload);
            ... ...
            }
            public void write(Message message) throws JMSException {
            ... ...
            TextMessage textMessage = (TextMessage) message;
            // Clears the body of the JMS message
            textMessage.clearBody();
            // Sets the value of the JMS message payload from the DataObject's
            // 'value' property
            payload = jmsData.getString("value");
            textMessage.setText(payload);
            ... ...
            }
            public DataObject getDataObject() throws DataBindingException {
            return jmsData;
            }
            public void setDataObject(DataObject jmsData) throws DataBindingException {
            this.jmsData = jmsData;
            }
            }
            

read() 方法將 JMS TextMessage 轉換為數據對象,而 write() 方法將數據對象重新轉換為 JMS TextMessage。在 read() 方法中,使用相應的模式創建了一個新的數據對象,在部署該中介模塊的過程中,WebSphere ESB 運行時可以使用該數據對象。在 write() 方法中,代碼讀取了數據對象的內容,并將其存儲在傳遞的“message”參數中。通過 getMessagetype() 方法來確定消息的類型。

使用下面的一行代碼來讀取 DataObject 的有效負載:

payload = jmsData.getString("value");

這段代碼使用了標準的 SDO API 調用。檢索屬性的名稱為“value”,來源于 JMSTextBody 的模式定義(在 JMSCustomBindingLibrary/JMSBodyModels.xsd 文件中):


清單 4.
  <xsd:complexType name="JMSTextBody">
            <xsd:sequence>
            <xsd:element name="value" type="xsd:string"/>
            </xsd:sequence>
            </xsd:complexType>
            

在該中介的 WSDL 接口中引用 JMSTextBody 類型。清單 2 中的 portType 消息指向這個模式。換句話說,該中介的接口定義了數據綁定類必須處理的 SDO 的結構。因此,任何 JMS 自定義數據綁定實現都與關聯于中介流組件接口的模式密切相關!

其他 JMS 消息類型的數據綁定類也是類似的。我們將把對這些類的分析工作留給您完成。此外,每個數據綁定實現都與 JMSBodyModels.xsd 文件中給出的相應模式定義密切相關。JMSStreamDataBinding 和 JMSMapDataBinding 類稍微復雜一點,因為它們需要保留流或映射中每個單獨的元素的類型信息。有關更詳細的信息,請查看 JMSBodyModels.xsd 文件中的復雜類型定義。

所有自定義 JMS 數據綁定都具有一個稱為 AbstractJMSDataBindingImpl 的公共超類,這個類實現了一些公共的功能,比如,進行異常處理的方法。

JMSDataBindingLogger 類負責進行日志記錄。要在自定義綁定代碼中激活日志記錄,可以將 WebSphere ESB 運行時中的 Trace details 設置為 com.ibm.websphere.sibx.samp.jms.*=fine。

JMS 參數

在本系列的第 2 部分中,我們已經為 JNDI 名稱創建了實際的隊列目標和隊列連接工廠。在這里,我們只是簡單重用它們。

完成 JMS 自定義綁定定義的最后一步是為傳入和傳出的流量選擇合適的 JMS 資源。

在綁定屬性中,還定義了所需的 JMS 隊列目標和連接工廠引用。如下面的圖中所示,JMS 導出綁定組件的連接工廠的定義位于 JMS Export Binding 選項卡的高級設置下面:


圖 4. JMS 導出綁定的連接工廠引用定義
圖 4. JMS 導出綁定的連接工廠引用定義

隊列目標引用的定義位于 JMS Destinations 選項卡下面:


圖 5. JMS 導出綁定的隊列目標引用定義
圖 5. JMS 導出綁定的隊列目標引用定義

我們沒有給出導入綁定組件相應的屏幕截圖,因為除了可以在 JMS Import Binding 選項卡下面找到連接工廠定義之外,它們基本上都是相同的。在您導入本文中的項目交換文件時,所有這些值都應該已經設置好了。





回頁首


中介流

在為導出和導入編寫了自定義綁定代碼之后,我們可以開始將注意力集中到中介流組件本身。在 WebSphere Integration Developer Assembly Editor 中,打開 JMSCustomBindingMediationModule,然后雙擊 JMSCustomBindingMediationComponent1 以打開 Mediation Flow Editor。在這個編輯器中,流組件接口的每項操作都表示為一個請求和一個響應流(圖 6)。


圖 6. Mediation Flow Editor
圖 6. Mediation Flow Editor

這些流完全與導入和導出中所使用的那些綁定獨立。實際上,這正是在流實現之外將其轉換為一個 SDO DataObject 實例的原因:無需知道發送到該中介模塊的和該中介模塊發送的消息的協議和格式,就可以構建這些流。

在這里,我們只將其中的一個流作為示例進行詳細描述,即 JMS TextMessage 流,因為這是最常見的 JMS 消息類型。我們還為這個消息類型的響應流添加了一些特定的異常處理機制。(其他消息類型的流也都是非常相似的。)

讓我們一步一步地描述該中介模塊對 JMS TextMessage 的處理:

  1. 當客戶端向中介模塊發送 JMS TextMessage 時,中介模塊將這個消息放到 JMS 導出綁定組件的接收隊列目標中。因為這個導出組件作為 JMS 自定義綁定實現,所以由自定義的函數選擇器對該消息進行處理。如上所述,根據傳入消息的類型,選擇器返回函數名稱“handleText”。

  2. 由于導出組件采用方法級數據綁定定義(如圖 2 所示),所以選擇了 JMSTextDataBinding 類來處理數據轉換。這個類提取了傳入的 JMS TextMessage 的文本有效負載,并且創建了遵循適當的 XML 數據類型(即 JMSTextBody)的 SDO DataObject 實例。將 DataObject 中的“value”字符串屬性設置為 JMS TextMessage 的有效負載的值。

  3. 然后將這個新的 DataObject 傳遞給中介流組件。因為將它傳遞給了 handleText 操作,所以這個流處理的消息正是當您在 Mediation Flow Editor 中選擇 handleText 鏈接時所看到的那個消息(請參見圖 6)。

  4. 使用 MessageLogger 中介基元在請求流中記錄下這個消息。

  5. 當這個消息離開請求流時,它進入在 Mediation Flow Editor 中由 JMSCustomBindingPartnerInterface 表示的 JMS 導入綁定組件。在這里,將 DataObject 重新轉換為 JMS TextMessage,并且最終發送到導入組件的發送隊列目標。

  6. 服務提供者(在我們的測試應用程序中是消息驅動的 Bean)監聽這個隊列目標上的消息。它的 onMessage() 方法僅打印出接收到的消息的內容。其中添加了一些特殊的代碼,以模擬異常處理過程:如果文本消息的內容為“exception”,那么將該響應 JMS TextMessage 中稱為 IsBusinessException 的 Header 屬性設置為“true”。

  7. 現在,將響應 JMS TextMessage 發送回該中介模塊,并將對其進行和前面一樣的處理:JMS 導入綁定組件將其轉換為 SDO DataObject。如果傳入 IsBusinessException 屬性設置為“true”的 TextMessage,那么通過錯誤調出 錯誤調出 而不是正常的響應調出 正常調出 將它傳遞給響應流。

  8. 如圖 6 所示,在響應流中,如果通過錯誤調出 錯誤調出 輸入消息,那么僅對這個消息進行記錄(通過 MessageLogger3),并將其轉發到錯誤輸入 錯誤輸入。在所有其他的情況下,消息將通過一個稱為 BusinessExceptionCustomMediation 的自定義中介元素,我們在這個中介元素中添加了相應的邏輯,以便在文本消息的內容為“Error”時生成另一個異常。在這種情況下,該消息將流過自定義中介元素的失敗終端,并對其進行記錄,然后再次被轉發到錯誤輸入 錯誤輸入。

  9. 對于所有“正常”消息(即沒有執行異常處理的消息),僅對其進行記錄,并轉發到輸入終端 輸入終端。

  10. 最后,將到達 JMS 導出組件的響應 DataObject 重新轉換為 JMS TextMessage,并將其放到發送隊列目標。這樣,任何 JMS 客戶端都可以對其進行檢索。如果導出組件通過中介流的錯誤輸入 錯誤輸入 接收到響應消息,那么它不僅將執行正常的數據轉換,還將為生成的 JMS TextMessage 添加一個名為 IsBusinessException 的 Header??蛻舳丝梢允褂盟鼇泶_認在消息處理的過程中是否發生了異常。





回頁首


將其組合到一起

既然我們已經完成了導出和導入綁定的定義,并且提供了中介流的實現,那么我們就可以最終部署并運行整個示例了。在第 2 部分中,我們向您介紹了如何安裝和部署測試應用程序客戶端和測試提供程序。還需要進行安裝的就只有該中介模塊了。

有兩種方法可以將中介模塊安裝到 WebSphere ESB 運行時服務器

  1. 使用 WebSphere Integration Developer WebSphere ESB 測試環境

    1. 在 WebSphere Integration Developer 中,打開 Servers 視圖,請確保創建并啟動了 WebSphere ESB Server v6。

    2. 右鍵單擊該服務器并從上下文菜單中選擇 Add and remove projects… 。

    3. 在接下來的對話框中,選擇 JMSCustomBindingMediationModuleApp 項目,并將它添加到服務器。

  2. 使用 WebSphere ESB 管理控制臺:

    1. 在 WebSphere Integration Developer 中,切換到 J2EE Perspective 并選擇 Enterprise Applications 下的 JMSCustomBindingMediationModuleApp。

    2. 將該項目導出到一個 EAR 文件。

    3. 打開 Servers 視圖,右鍵單擊 WebSphere ESB Server v6 并從上下文菜單中選擇 Run administrative console。

    4. 在管理控制臺中,通過 Applications => Install New Application 將導出的 EAR 安裝到運行時中。

要測試該應用程序,可以打開一個 Web 瀏覽器,然后瀏覽至 http://<HOSTNAME>:<HOSTPORT>/JMSTestClientWeb/index.html(<HOSTNAME> 和 <HOSTPORT> 取決于您本地的服務器配置,通??梢允褂?ldquo;localhost”和端口 9080)。請按照第 2 部分中給出的說明來發送不同類型的 JMS 消息,然后選擇 Click here to select messages on the reply queue 以查看響應消息。其屏幕顯示應該與圖 7 所示類似。


圖 7. 成功發送一個 TextMessage 后 JMSTestClient 的結果 Web 頁面
圖 7. 成功發送一個 TextMessage 后 JMSTestClient 的結果 Web 頁面




回頁首


結束語

在本文中,我們通過一個具體的示例向您介紹了如何在 WebSphere ESB 中為中介流組件構建 JMS 自定義綁定。我們討論了處理傳入和傳出的 JMS 消息所必需的數據綁定和函數選擇器代碼,以及導出和導入所需的綁定屬性。我們了解了如何以可視化的方式構建中介流組件,最重要的是,獨立于與中介流進行通信的過程中使用的協議。

我們以這篇文章結束了關于這個主題的系列文章。請繼續閱讀更多關于 WebSphere ESB 的文章,以及如何使用它及其相應的工具 WebSphere Integration Developer 來構建高級的解決方案!





回頁首


本系列的其他文章

  • 第 1 部分:將 WebSphere ESB V6.0.1 和 JMS 結合使用
  • 第 2 部分:創建用于常見場景的示例應用程序





回頁首


下載

描述名字大小下載方法
Code sample WESBCustomJMSPart3 PI.zip 69 KB  FTP|HTTP

原文轉自:http://www.anti-gravitydesign.com

国产97人人超碰caoprom_尤物国产在线一区手机播放_精品国产一区二区三_色天使久久综合给合久久97