Jboss ESB簡介及開發實例

1、Jboss ESB的簡介 一、 什麼是ESB。         ESB的全稱是Enterprise Service Bus,即企業服務總線。ESB是過去消息中間件的發展,ESB採用了「總線」這樣一種模式來管理和簡化應用之間的集成拓撲結構,以廣爲接受的開放標準爲基礎來支持應用之間在消息、事件和服務的級別上動態的互連互通。        ESB是一種在鬆散耦合的服務和應用之間標準的集成方式。它能夠做用於: ①面向服務的架構 - 分佈式的應用由可重用的服務組成。        ②面向消息的架構 - 應用之間經過ESB發送和接受消息。java

③事件驅動的架構 - 應用之間異步地產生和接收消息。        用一句比較通俗的話來描述ESB:ESB就是在SOA架構中實現服務間智能化集成與管理的中介。     二、 ESB和SOA之間的關係。         介紹ESB就不得不提到SOA的概念,那麼什麼是SOA吶? 簡單的說,SOA(service-oriented architecture)是面向服務的體系結構,是一類分佈式系統的體系結構。這類系統是將異構平臺上應用程序的不一樣功能部件(稱爲服務)經過這些服務之間定義良好的接口和規範按鬆耦合方式整合在一塊兒,即將多個現有的應用軟件經過網絡將其整合成一個新系統。 多應用的整合不可是跨平臺的,並且應該是鬆耦合的,也就是說,被整合的應用自身仍保持其自主,如香港政府已迴歸中國,但保持一國二制。 新增設的業務功能,應容許適應變化,即隨需應變。 如何作到跨平臺、鬆耦合,除使用方和服務方外,另有中介方,提供駐冊登記和查詢。如今社會的勞務市場和職業介紹所等都起這樣做用。即先查詢、梆定、而後調用。 在SOA的體系結構中,簡單的能夠分爲以下幾個角色: ①服務使用者:服務使用者是一個應用程序、一個軟件模塊或須要一個服務的另外一個服務。它發起對註冊中心中的服務的查詢,經過傳輸綁定服務,而且執行服務功能。服務使用者根據接口契約來執行服務。web

②服務提供者:服務提供者是一個可經過網絡尋址的實體,它接受和執行來自使用者的請求。它將本身的服務和接口契約發佈到服務註冊中心,以便服務使用者能夠發現和訪問該服務。 ③服務註冊中心:服務註冊中心是服務發現的支持者。它包含一個可用服務的存儲庫,並容許感興趣的服務使用者查找服務提供者接口。 SOA體系結構中的操做 ①發佈:爲了使服務可訪問,須要發佈服務描述以使服務使用者能夠發現和調用它。 ②發現:服務請求者定位服務,方法是查詢服務註冊中心來找到知足其標準的服務。 ③綁定和調用:在檢索完服務描述以後,服務使用者繼續根據服務描述中的信息來調用服務。 SOA的優勢以下: ①利用現有的資產。 方法是將這些現有的資產包裝成提供企業功能的服務。組織能夠繼續從現有的資源中獲取價值,而沒必要從新從頭開始構建。 ②更易於集成和管理複雜性。 將基礎設施和實現發生的改變所帶來的影響降到最低限度。由於複雜性是隔離的。當更多的企業一塊兒協做提供價值鏈時,這會變得更加劇要。 那麼ESB和SOA有什麼關係吶? ESB同SOA之間的關係:ESB是邏輯上與SOA 所遵循的基本原則保持一致的服務集成基礎架構,它提供了服務管理的方法和在分佈式異構環境中進行服務交互的功能。 能夠這樣說,ESB是特定環境下(SOA架構中)實施EAI的方式:首先,在ESB系統中,被集成的對象被明肯定義爲服務,而不是傳統EAI中各類各樣的中間件平臺,這樣就極大簡化了在集成異構性上的考慮,由於無論有怎樣的應用底層實現,只要是SOA架構中的服務,它就必定是基於標準的。 其次,ESB明確強調消息(Message)處理在集成過程當中的做用,這裏的消息指的是應用環境中被集成對象之間的溝通。以往傳統的EAI實施中碰到的最大的問題就是被集成者都有本身的方言,即各自的消息格式。做爲基礎架構的EAI系統,必須可以對系統範疇內的任何一種消息進行解析。傳統的EAI系統中的消息處理大可能是被動的,消息的處理須要各自中間件的私有方式支持,例如API的方式。所以儘管消息處理自己很重要,但消息的直接處理不會是傳統EAI系統的核心。ESB系統因爲集成對象統一到服務,消息在應用服務之間傳遞時格式是標準的,直接面向消息的處理方式成爲可能。若是ESB可以在底層支持現有的各類通信協議,那麼對消息的處理就徹底不考慮底層的傳輸細節,而直接經過消息的標準格式定義來進行。這樣,在ESB中,對消息的處理就會成爲ESB的核心,由於經過消息處理來集成服務是最簡單可行的方式。這也是ESB中總線(Bus)功能的體現。其實,總線的概念並不新鮮,傳統的EAI系統中,也曾經提出過信息總線的概念,經過某種中間件平臺,如CORBA來鏈接企業信息孤島,可是,ESB的概念不只僅是提供消息交互的通道,更重要的是提供服務的智能化集成基礎架構。 最後,事件驅動成爲ESB的重要特徵。一般服務之間傳遞的消息有兩種形式,一種是調用(Call),即請求/迴應方式,這是常見的同步模式。還有一種咱們稱之爲單路消息(One-way),它的目的每每是觸發異步的事件,發送者不須要立刻獲得回覆。考慮到有些應用服務是長時間運行的,所以,這種異步服務之間的消息交互也是ESB必須支持的。除此以外,ESB的不少功能均可以利用這種機制來實現,例如,SOA中服務的性能監控等基礎架構功能,須要經過ESB來提供數據,當服務的請求經過ESB中轉的時候,ESB很容易經過事件驅動機制向SOA的基礎架構服務傳遞信息。    三、 Jboss ESB的主要特徵和功能   ①Jboos esb 4.2主要的特性包括: 支持普通的通知框架。支持的Transports包括JMS (JBossMQ, JBoss Messaging, Oracle AQ and MQSeries), email, 數據庫或文件系統. 推薦的缺省 JMS 實現是JBoss Messaging 1.2.0GA. jBPM 集成.數據庫

支持WS-BPEL. 支持Web Services. 使用特定的ESB 服務器改進部署和配置. 支持Groovy. trailblazer 例子.apache

許多quickstart 例子. 支持使用Smooks or XSLT轉數據 . 支持交互步驟鬆耦合的偵聽器和動做模型. 使用Drools或者 XPath 基於內容的路由. 支持JAX-R和jUDDI註冊 . 提供容許non-ESB traffic與ESB進行集成的網關. 圖形化的配置編輯器. 高性能和可靠性(大型保險公司3年的使用).       ②何時使用Jboos ESB 下面的圖表說明JBossESB能夠被使用的具體例子。雖然這些例子在參與者間使用非互操做的JMS實現特殊的交互,但原理是相同的。 下面的這張圖表顯示了在兩個系統間簡單的文件發送,而沒有使用消息隊列管理。服務器

下一個圖表說明了在與上圖相同的環境下如何經過注入實現轉換。網絡

下面的幾個例子,咱們使用了消息隊列系統(例如,一個JMS實現)。session

下面這幅圖表顯示了在相同環境下的轉換和排隊。架構

JBossESB能被用在多種狀況下。舉一個例子,下面的圖顯示了ESB利用文件系統進行基本數據轉換。app

最後的場景又是一個使用了轉換和排隊的例子。composer

3. JBossESB的核心 JbossESB創建在三個核心的體系結構組件上: • 消息監聽器和消息過濾器代碼。消息監聽器監聽消息(例如,JMS上的Queue/Topic,或文件系統),並路由。而後引導消息處處理管道。消息過濾器則過濾消息,並將消息路由到另外一個消息端點。 • 數據轉換使用Smooks轉換處理器。 • 一個基於路由服務的目錄。 • 一個消息存儲庫, 用來存儲在ESB上交換的消息/事件。

一個典型的JBossESB部署以下圖。

2、Jboss ESB的詳細介紹。 一、總述 JBossESB是JBoss推出的ESB的實現,也是JBoss的SOA產品的基礎.首先你們對於ESB的定義有不少的不一樣,我我的更喜歡把ESB看做是系統集成的一個平臺. JBossESB是一個基於消息的中間件(Message Oriented). 在這篇文章中,咱們只是看待ESB中的一個很基礎部份,也就是怎麼從Endpoint A發送信息給ESB的服務S1,而後再有S1發送信息到Endpoint B去調用服務。還有一些關於Router(路由),Data Transformation(數據轉換)功能點的介紹,比較基礎要詳細瞭解JbossESB的各類功能請詳細參考相關的文檔。 咱們就假設一個簡單的系統集成場景來開始闡述JBossESB的設計和概念。 A系統(Endpoint A) –  Message ->  ESB -> –  Message --> B系統 (Endpoint B) 因此,若是簡單的對於JBossESB定義的話,咱們能夠定義如下三個概念: Message Listener (接收「inbound」 message)

Message Filter (發送 "outbound」 message)

Message (消息對象) JBossESB 是一個面向服務(Service Oriented)的架構,因此在ESB內部的要麼是一個Service, 要麼是一個Message. 這裏的Service就是指具備實現業務邏輯的服務,也能夠是一個實現路由(Router),或者數據轉化(Transformation)的服務. 就拿上面的這個例子,系統A發送一個Message給 ESB的一個服務,咱們假設叫作S1, 那麼S1收到Message後,作一些處理,轉到S2的服務,S2再把處理後的結果發送給系統B. 這樣就實現了A和B之間經過ESB的通訊. System A -> message -> S1 -> S2 ->....  -> message -> System B 那麼在ESB內部是怎麼去表達一個服務呢?這裏引入了EndpointReference的概念,簡稱EPR. 有了服務以後,服務之間是經過什麼樣的傳輸層(好比JMS, FTP, HTTP)來通訊呢? 因此ESB的內部也引入了Courier的API, 來統一抽象傳輸層. 剛咱們也看到了,ESB的內部無非就是一系列的服務, 可是咱們怎麼來保存/註冊這些服務的呢? JBossESB是使用jUDDI來註冊和保存這些服務元數據的。 二、 JBossESB的幾個重要概念 在要了解和運行JBossESB以前,咱們最好了解下JBossESB中比較重要的幾個概念。 ①Message (消息) ESB內部所交流/傳遞的都是消息,因此可見這個消息格式的重要性. 在JBossESB中, 定義了一個Message的對象,它是有如下幾個部分構成的。 (1). Header (用來存放From, To, Reply-to等Addressing的信息). (2). Body (存放信息主體) (3). Attachment (用來存放附件等)

(4). Properties (5). Context (主要是存放一些相似事務的信息等)

目前在Body裏面通常來講存放兩種格式的數據,一個是串行化數據(Serialized Object ),另一個是XML文件,好比常見 的SOAP的payload. 在ESB中,還有兩個定義,一個叫ESB-aware Message, 咱們上面所講的Message就是ESB-aware Message, 正如名字說講的,它是屬於ESB內部的Message對象. 還有個叫 ESB unaware Message,也就是說他一樣也是一個message,好比SOAP Message,可是若是把soap message直接讓ESB來處理,是處理不了的,因此呢? 常常的在Listener 監聽的端口會有個Adapter (在JBossESB裏叫作Gateway)來負責把ESB-unaware message 轉成 ESB-aware message。 ②Service (服務) ESB的內部服務是用EPR來映射的. ESB的內部服務能夠是任何的一個服務,好比說一個FTP的服務,一個基於文件系統的服務等等, 那麼這個時候咱們就須要用EPR來對這個服務進行描述.在EPR這個類裏,主要是描述了這個服務的URI,以及所必須的一些元數據. 目前在JBossESB中提供的EPR有: FileEPR,EmailEPR,FTPEPR, HibernateEPR等等. 咱們在註冊服務的時候,是將EPR的信息註冊到UDDI的容器裏, 但不只僅是EPR, 還有一些輔助信息,好比定義服務的category-name, service-name. 這些將在後面繼續介紹。 ③Listeners, Gateway Listener的做用是負責監聽端口,通常來講,客戶端是發送消息到Listener,而後有Listener把消息傳遞給ESB, 咱們能夠把Listener看作是inbound router. 在JBossESB中,咱們是叫GatewayListener, 它通常來講作兩件事情. 監聽Message. ESB-unaware message和 ESB-aware message的互轉.

目前ESB支持的Gateway有: JMSGatewayListener, JBossRemotingGatewayListener, FileGatewayListener等等. 在MessageComposer這個類裏的compose/decompose方法來負責ESB-unaware信息和ESB-aware信息的轉化。

public interface MessageComposer<T> {

    /**

     * Set the composer's configuration

     */

    public void setConfiguration(ConfigTree config) throws ConfigurationException;

 

    /**

     * Compose an ESB "aware" message from the supplied message payload.

     * Implementations need to construct and populate an ESB Message from the

     * messagePayload instance.

     */

    public Message compose(T messagePayload) throws MessageDeliverException;

    /**

     * Decompose an ESB "aware" message, extracting and returning the message payload.

     */

    public Object decompose(Message message, T originalInputMessagePayload) throws MessageDeliverException;

} ④Couriers

Courier的做用就是負責傳輸,正如如下接口所顯示: public interface Courier extends DeliverOnlyCourier { Public Boolean deliver(Message message) throwsCourierException,MalformedEPRException; }

目前實現的Transport有:JmsCourier, InVMCourier, HibernateCourier, FileCourier等傳輸層,在ESB內部是經過EPR來跟Courier進行關聯的。 ⑤Actions 在JBossESB中,咱們能夠把ActionProcessingPipeline類看做是Message Filter, 每一個Message都會通過 ActionProcessingPipeline的處理. 裏面有這麼個方法: public boolean process(final Message message) 而actionProcessingPipeline又是由Action (ActionPipelineProcessor)來組成的. 咱們能夠把Action當作是Interceptor, 由它來實現具體的業務邏輯,能夠是路由,又或者數據轉化功能等等. 若是你用JBossESB的話,那麼Action是一個很是重要的部分,咱們來看下它所定義的接口。 通常來講自定義的Action把具體的業務邏輯放在Process的方法裏,固然了,你也能夠定義相對應的Exception處理方法,經過實現processException.在ESB代碼中,自定義的Action能夠用繼承AbstractActionPipelineProcessor 或者 AbstractActionLifecycle。 ⑥Meta-data and Filters 在有些狀況下,你須要一些全局的Interceptor,咱們以前說的Action,能夠理解成是每一個service的interceptor,可是若是我須要使用log來記錄一個消息在各個service之間傳輸的日誌, 又或者想記錄消息進入某個service的時間和退出的時間. 那麼在JBoss ESB中就有Filter的概念. 若是你要實現本身的Filter,須要繼承InputOputFilter類。

public class InputOutputFilter

{  

    /**

     * Called as the message flows towards the transport.

     */

   

    public Message onOutput (Message msg, Map<String, Object> params) throws CourierException

    {

        return msg;

    }

   

    /**

     * Called immediately after the message is received from the transport.

     */

   

    public Message onInput (Message msg, Map<String, Object> params) throws CourierException

    {

        return msg;

    }

} 寫完本身的Filter後,你須要在$JBossESB/server/config (e.g. default)/deploy/jbossesb.sar/jbossesb-properties.xml裏面增長filter. 須要注意的是,在這裏配置的filter是對全部的esb包都起做用,是個全局的變量. onInput方法老是在從傳輸層獲取到Message後,第一步所作的工做;相似的, onOutput是給傳輸層傳遞前所作的最後一步工做. 你能夠在TwoWayCourierImpl中看到這段代碼的調用。 ⑦ServiceInvoker 對於客戶端調用來講,EPR, Courier等都太底層了.因此若是對此進行了封裝. 咱們對每一個service加以service-category和service-name的屬性. 因此若是你想發送一個ESB的內部Message,你只須要知道目標service的service-category和service-name,而後就能夠調用ServiceInvoker來調用服務. 不須要去使用Courier等底層的API, 另外用ServiceInvoker還能夠支持fail-over等特性.

public class ServiceInvoker {

       

        public ServiceInvoker(String serviceCategory, String serviceName) throws MessageDeliverException {

                    this(new Service(serviceCategory, serviceName));

        }

           

        public Message deliverSync(Message message, long timeoutMillis) throws MessageDeliverException, RegistryException, FaultMessageException

        public void deliverAsync(Message message) throws MessageDeliverException

} 三、 Jboss ESB一個簡單示例。 爲了更好的來解釋JBossESB, 最好的一個方法就是試下JBossESB自帶的例子,這裏咱們先以helloworld_action的例子來說解.

①安裝和運行JBossESB sample 到這裏,你已經成功的運行了helloworld_action的例子 1       從JBossESB網站下載 jbossesb-server-4.4.GA.zip 2       解壓jbossesb-server-4.4.GA.zip, 假設到/var/local/jbossesb-sever4.4. 下面以$jbossesb來替代. 3       在$jbossesb中,運行 bin/run.sh 來啓動ESB server 4       另外打開一個窗口,到$jbossesb/samples/quickstarts/helloworld_actions, 運行: ant deploy 5.      再運行: ant runtest 6.      回到JBoss ESB server的控制檯上,應該能夠看到如下的輸出:. 7. INFO  [STDOUT] [Hello World Action]. 8. INFO  [STDOUT] 9. &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& 10. INFO  [STDOUT] Body: Hello World Action 11. INFO  [STDOUT] &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& 12. INFO  [STDOUT] ConsoleNotifier 2008/09/26 06:35:39.643< 13. BEFORE** 14. Hello World Action 15. AFTER** 16. >

 

②分析helloworld_action例子 <1>在看jboss-esb.xml的配置時候,咱們應該分紅兩個部份. providers和services. a. providers

       首先是<providers>,它是有一系列的<provider>組成, 目前有jms-provider, fs-provider, ftp-provider等等. 而後咱們在provider裏面定義這個.esb文件裏面service所定義的listener所須要的bus, Bus能夠簡單理解成消息傳送所須要的傳輸層. 正如如下所顯示的,咱們定義了兩個Bus,一個是給Gateway的Listener用,另一個是給ESB-aware Message傳輸所須要的傳輸層.    

    <providers>

          <jms-provider name="JBossMQ" connection-factory="ConnectionFactory">

                     

              <jms-bus busid="quickstartGwChannel">

                  <jms-message-filter

                      dest-type="QUEUE"

                      dest-name="queue/quickstart_helloworld_action_Request"

                  />

              </jms-bus>

              <jms-bus busid="quickstartEsbChannel">

                  <jms-message-filter

                      dest-type="QUEUE"

                      dest-name="queue/B"

                  />

 

              </jms-bus>

 

          </jms-provider>

      </providers> 雖然在這邊寫的是JBossMQ, 可是對於JBoss ESB server來講,是默認使用JBoss Messaging的; 若是是把JBoss ESB安裝在JBoss AS 4.x的服務器, 那麼就是用JBoss MQ, 由於JBoss AS 4.x默認是使用JBoss MQ.

b. services 第二部份就是定義services的部份, 在這裏定義了當前這個esb包所提供的services. 每一個service又是由 <listener> 和 <actions>組成的.

 

<services>

         

        <service category="HelloWorld_ActionESB"

                 name="SimpleListener"

                 description="Hello World" >

            <listeners>

 

                <jms-listener name="JMS-Gateway"

                    busidref="quickstartGwChannel"                        

                    is-gateway="true"

                />

 

                <jms-listener name="JMS-ESBListener"

                              busidref="quickstartEsbChannel"

                />               

            </listeners>

            <actions mep="OneWay">

            <action name="action2"

                    class="org.jboss.soa.esb.actions.SystemPrintln"

                    />

               <action name="displayAction"

                    class="org.jboss.soa.esb.samples.quickstart.helloworldaction.MyJMSListenerAction"

                    process="displayMessage">

                    <property name="exceptionMethod" value="exceptionHandler"/>

               </action>

               <action name="playAction"

                    class="org.jboss.soa.esb.samples.quickstart.helloworldaction.MyJMSListenerAction"

                    process="playWithMessage">       

                    <property name="exceptionMethod" value="exceptionHandler"/>

               </action> 

            </actions>

        </service>

      </services> 在listener裏,咱們經過 busidref來關聯到咱們定義在provider裏面的bus. 在這裏,咱們定義了兩個listener. 其中一個是作爲Gateway,只負責從外界獲取到JMS的消息,而後轉成ESB內部所須要的Message. 而另一個listener是用來這個Message在services內部之間通信的通道. 因此對於每一個service來講,必定要至少定義一個listener來做爲內部Message傳輸用.     這裏的action是對消息(Message)處理的地方. <2> MyJMSListenerAction 正如咱們在上面看到的,咱們在jboss-esb.xml中定義了action,咱們看下MyJMSListenerAction.

 

public class MyJMSListenerAction extends AbstractActionLifecycle

{

   protected ConfigTree _config;

         

   public MyJMSListenerAction(ConfigTree config) { _config = config; } 

         

    public Message playWithMessage(Message message) throws Exception {

       Body msgBody = message.getBody();

       String contents = msgBody.get().toString();

       StringBuffer sb = new StringBuffer();

       sb.append("\nBEFORE**\n");

       sb.append(contents);

       sb.append("\nAFTER**\n");

       msgBody.add(sb.toString());

       return message;

   }

} 咱們只是截取其中的一部分來講明,通常來講每一個Action都要繼承AbstractActionLifecycle類,而後輸入/輸出參數都必須是ESB的Message. 方法名能夠隨便定義. 你只須要在jboss-esb.xml的action的process屬性中寫相對應的方法名就能夠. 若是不寫,默認是process方法. 這裏的ConfigTree是個很重要的屬性,咱們很常常的會在Action配置其餘的信息,那麼 全部的信息均可以經過ConfigTree來獲取到.好比說在某個Action中配置靜態路由信息等等.也正是因爲Action中你能夠隨意的配置你本身的信息,增長了不少的靈活性和擴展性. <3> esb文件目錄結構 咱們先看下部署在server下的.esb包的文件目錄,通常是包括如下些東西. /META-INF/jboss-esb.xml /META-INF/deployment.xml 在這裏定義對其餘包或者服務的依賴,或者配置classloader. jbm-queue-service.xml (optional) 這裏是定義啓動所須要的Queue **.jar (optional) 放些所須要的第三方包

所須要的些classes文件 三、客戶端調用服務 目前在JBossESB中,通常有兩種方式來調用service. 一種是經過Gateway listener, 另一種是直接經過ServiceInvoker的API來調用. ①經過Gateway來調用服務 回到咱們的例子,咱們經過JMS Gateway來訪問ESB的服務.

public class SendJMSMessage {

             

  public void setupConnection() throws JMSException, NamingException

    {

        InitialContext iniCtx = new InitialContext();

        Object tmp = iniCtx.lookup("ConnectionFactory");

        QueueConnectionFactory qcf = (QueueConnectionFactory) tmp;

        conn = qcf.createQueueConnection();

        que = (Queue) iniCtx.lookup("queue/quickstart_helloworld_action_Request");

        session = conn.createQueueSession(false, QueueSession.AUTO_ACKNOWLEDGE);

        conn.start();

        System.out.println("Connection Started");

    }

             

             

    public void sendAMessage(String msg) throws JMSException { 

        QueueSender send = session.createSender(que);       

        ObjectMessage tm = session.createObjectMessage(msg);

         tm.setStringProperty(StoreMessageToFile.PROPERTY_JBESB_FILENAME, "HelloWorldActionTest.log");

        send.send(tm);       

 

        send.close();

    }

      

   

    public static void main(String args[]) throws Exception

    {                  

        SendJMSMessage sm = new SendJMSMessage();

        sm.setupConnection();

        sm.sendAMessage(args[0]);

        sm.stop();

    }

}

應該說,這是一個很普通發送JMS消息送到一個指定的Queue. 注意,我這裏並無所有拷貝這個SendJMSMessage類. 只是拷貝出重要的部分.(若是想要看完整的,請參考helloworld_action例子下面的代碼) ②利用ServiceInvoker直接發送ESB Message 在helloworld_action例子中,沒有直接SendESBMessage的客戶端來調用,可是咱們能夠看下helloworld的sample下面的,由於是同樣的.

public class SendEsbMessage

{

    public static void main(String args[]) throws Exception

    {

//      Setting the ConnectionFactory such that it will use scout

        System.setProperty("javax.xml.registry.ConnectionFactoryClass","org.apache.ws.scout.registry.ConnectionFactoryImpl");

       

        if (args.length < 3)

        {

            System.out.println("Usage SendEsbMessage <category> <name> <text to send>");

        }

       

        Message esbMessage = MessageFactory.getInstance().getMessage();

        esbMessage.getBody().add(args[2]); 

        new ServiceInvoker(args[0], args[1]).deliverAsync(esbMessage);

       

    }  

}

正如咱們以前所說的,客戶端用ServiceInvokerAPI大大簡化了調用服務的過程. 咱們在jboss-esb.xml中看到每一個service都會有service-category和service-name的屬性. 在ServiceInvoker中,用戶只須要提供這兩個屬性,就能調用到ESB的服務,固然了,還須要juddi.properties文件. 這也是爲何咱們的 sample下面通常會有這個文件. ServiceInvoker的使用 ServiceInvoker是個至關重要的API,應該說在ESB service之間服務的互相調用,就是用ServiceInvoker來完成的. 由於ServiceInvoker對Courier等進行了一層的抽象封裝. 因此用ServiceInvoker來調用服務,是能夠支持fail-over等高級特性的. 四、小結 咱們結合以前的概念,來看下這個例子的調用過程. 這裏咱們假設是經過JMS Gateway來調用ESB服務的. (1). 從JMS Gateway listener接收到JMS Message.而後把JMS message 轉成 ESB Message. (2). 使用ServiceInvoker API發送 ESB Message到指定的service.

(3). ESBAwareListener接收到ESB Mesage後,找到對應的service,把Message提交給ActionProcessingPipeline來處理. 咱們這裏講述了一個簡單的調用oneway服務的一個過程. 3、 Jboss ESB的功能點及實例介紹   一、簡單的測試經過Jboss ESB服務器進行消息轉發的實例      (1)消費者端的代碼(即要訪問Jboss ESB服務器端的代碼,訪問者端的代碼) 該類的路徑在VSS上是: Jboss ESB實例\實例1\book\src\org\jboss\seam\example\booking package org.jboss.seam.example.booking;

import java.util.Hashtable; import javax.jms.JMSException; import javax.jms.ObjectMessage; import javax.jms.Queue; import javax.jms.QueueConnection; import javax.jms.QueueConnectionFactory; import javax.jms.QueueSender; import javax.jms.QueueSession; import javax.naming.Context; import javax.naming.InitialContext; import javax.naming.NamingException;

import org.jboss.soa.esb.message.format.MessageFactory; import org.jboss.soa.esb.message.format.MessageType; import org.apache.log4j.Logger; import org.jboss.soa.esb.message.Message; import org.jboss.soa.esb.message.format.MessageFactory; import org.jboss.soa.esb.message.format.MessageType;

import org.jboss.soa.esb.client.ServiceInvoker;

 

public class TestESB { QueueConnection conn; QueueSession session; Queue que;     private ServiceInvoker serviceInvoker;

@SuppressWarnings("unchecked") public void setupConnection() throws JMSException, NamingException

{ Hashtable properties1 = new Hashtable();           properties1.put(Context.INITIAL_CONTEXT_FACTORY,                   "org.jnp.interfaces.NamingContextFactory");           properties1.put(Context.URL_PKG_PREFIXES,           "org.jboss.naming:org.jnp.interfaces");           properties1.put(Context.PROVIDER_URL, "jnp://127.0.0.1:1099");           InitialContext iniCtx = new InitialContext(properties1);          Object tmp = iniCtx.lookup("ConnectionFactory");           QueueConnectionFactory qcf = (QueueConnectionFactory) tmp;  

        conn = qcf.createQueueConnection();           que = (Queue) iniCtx.lookup("queue/esb-tb-bankRequestQueue");//("queue/esb-tb-bankRequestQueue");//("queue/quickstart_helloworld_action_Request");         session = conn.createQueueSession(false, QueueSession.AUTO_ACKNOWLEDGE);           conn.start();           System.out.println("Connection Started");

}

public void stop() throws JMSException { conn.stop(); session.close(); conn.close(); }

public void sendAMessage(String msg) throws JMSException { QueueSender send = session.createSender(que); ObjectMessage tm = session.createObjectMessage(msg); send.send(tm); send.close(); }

public static void main(String args[]) throws Exception { TestESB sm = new TestESB();

sm.setupConnection(); sm.sendAMessage("yuexiangcheng");

sm.stop(); } 這是一個帶有main()函數的主方法,目的就是爲了測試。 properties1.put(Context.PROVIDER_URL, "jnp://127.0.0.1:1099"); 這句代碼中的IP地址,表示Jboss ESB服務器的IP地址。 iniCtx.lookup("queue/esb-tb-bankRequestQueue"); 這句代碼中的 queue/esb-tb-bankRequestQueue表示Jboss ESB服務器上暴露的服務接口。

     (2)Jboss ESB服務器端的代碼。          該實例的代碼在VSS的路徑是:         Jboss ESB實例\實例1\HelloESB          Jboss ESB服務器上主要的代碼有兩部分。          ①jboss-esb.xml          代碼以下: <?xml version="1.0"?> <jbossesb xmlns="http://anonsvn.labs.jboss.com/labs/jbossesb/trunk/product/etc/schemas/xml/jbossesb-1.0.1.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://anonsvn.labs.jboss.com/labs/jbossesb/trunk/product/etc/schemas/xml/jbossesb-1.0.1.xsd http://anonsvn.labs.jboss.com/labs/jbossesb/trunk/product/etc/schemas/xml/jbossesb-1.0.1.xsd">     <providers>           <jms-provider name="JBossMQ" connection-factory="ConnectionFactory">                                     <jms-bus busid="quickstartGwChannel">                   <jms-message-filter                       dest-type="QUEUE"                       dest-name="queue/quickstart_helloworld_action_Request"                   />               </jms-bus>               <jms-bus busid="quickstartEsbChannel">                   <jms-message-filter                       dest-type="QUEUE"

                      dest-name="queue/B"                   />               </jms-bus>

                                          <!--加被嶽鄉成 --> <jms-bus busid="creditAgencyRequest"> <jms-message-filter dest-type="QUEUE" dest-name="queue/esb-tb-creditAgencyQueue" /> </jms-bus> <jms-bus busid="bankResponseGateway"> <jms-message-filter dest-type="QUEUE" dest-name="queue/esb-tb-bankGatewayResponseQueue"/> </jms-bus>

<jms-bus busid="bankResponseListener"> <jms-message-filter dest-type="QUEUE" dest-name="queue/esb-tb-bankResponseQueue"/>

</jms-bus>

          </jms-provider>       </providers>             <services>                   <service category="HelloWorld_ActionESB"                  name="SimpleListener"                  description="Hello World" >             <listeners>                 <jms-listener name="JMS-Gateway"                     busidref="quickstartGwChannel"                                             is-gateway="true"                 />                 <jms-listener name="JMS-ESBListener"                               busidref="quickstartEsbChannel"                 />                            </listeners>             <actions mep="OneWay">             <action name="action2"                     class="org.jboss.soa.esb.actions.SystemPrintln"                     />                <action name="displayAction"                class="org.jboss.soa.esb.samples.quickstart.helloworldaction.MyJMSListenerAction"                process="displayMessage">

               <property name="exceptionMethod" value="exceptionHandler"/>                </action>      <action name="playAction"      class="org.jboss.soa.esb.samples.quickstart.helloworldaction.MyJMSListenerAction"      process="playWithMessage">                                 <property name="exceptionMethod" value="exceptionHandler"/>      </action>                <action name="notificationAction"                class="org.jboss.soa.esb.actions.Notifier">                <property name="okMethod" value="notifyOK" />

               <property name="notification-details">       <NotificationList type="OK">            <target class="NotifyConsole" />     <target class="NotifyQueues">            <messageProp name="quickstart" value="hello_world_action" />           <queue jndiName="queue/quickstart_helloworld_action_Response"/>      </target>           </NotificationList>

       </property>      </action>                </actions>         </service>

                        <!--加被嶽鄉成 -->     <service category="tbCreditAGency" name="creditagency" description="Credit Agency Service"> <listeners> <jms-listener name="trailblazer-jmscreditagency"   busidref="creditAgencyRequest"   maxThreads="1"/>   </listeners> <actions>

<action class="org.jboss.soa.esb.samples.quickstart.testbyyuexiangcheng.CreditAgencyActions" process="processCreditRequest" name="fido"> </action> </actions> </service> <service category="tbJmsbank" name="jmsbankreplies" description="Trailblazer Bank Reply Service"> <listeners> <jms-listener name="trailblazer-jmsbank" busidref="bankResponseGateway" maxThreads="1" is-gateway="true"/> <jms-listener name="trailblazer-jmsbankreplies"

  busidref="bankResponseListener"   maxThreads="1"/> </listeners>

<actions> <action class="org.jboss.soa.esb.samples.quickstart.testbyyuexiangcheng.BankResponseActions" process="processResponseFromJMSBank" name="pepe"/> </actions> </service>                               </services> </jbossesb>     上面紅色部分表示Jboss ESB服務器上暴露的上面要調用的服務的接口的過程。     當通道接收到消息時,就會被攔截,就會轉到上面綠色區域定義的類中去處理。 ②Action類

該類的代碼在VSS上的路徑爲: Jboss ESB實例\實例1\HelloESB\src\org\jboss\soa\esb\samples\quickstart\testbyyuexiangcheng

package org.jboss.soa.esb.samples.quickstart.testbyyuexiangcheng;

import java.util.Random;

import org.apache.log4j.Logger; import org.jboss.soa.esb.actions.AbstractActionLifecycle; import org.jboss.soa.esb.helpers.ConfigTree; import org.jboss.soa.esb.message.Message;

import org.jboss.soa.esb.message.format.MessageFactory; import org.jboss.soa.esb.message.format.MessageType; import org.jboss.soa.esb.util.Util;

public class CreditAgencyActions extends AbstractActionLifecycle { protected ConfigTree _config;

private static Logger _logger = Logger.getLogger(CreditAgencyActions.class);

public CreditAgencyActions(ConfigTree config) { _config = config; }

public Message noOperation(Message message) { return message; }

public Message processCreditRequest(Message message) throws Exception{

_logger.debug("message received: " + Util.serialize(message) );

String csvData = (String) message.getBody().get(); _logger.debug("csv data received: " + csvData);

//generate a random score between 1 and 10 Random rand = new Random(); int n = 10; int score = rand.nextInt(n+1);

//send back the reply                 Message replyMessage = MessageFactory.getInstance().getMessage(MessageType.JBOSS_XML); _logger.info("CreditAgency sending back a credit score of " + score); replyMessage.getBody().add(Integer.toString(score));

return replyMessage; }

public Message debugMessage(Message message) throws Exception{

_logger.debug("message received in processCreditRequest with message: " + Util.serialize(message));

return message; } } 二、 讀取外部文檔的數據,發送到Jboss ESB服務器上而且進行數據轉換。 該實例的工程在VSS上的路徑是: Jboss ESB實例\實例2\James 該實例主要要注意三點: ①在工程中要提供一個要讀取的文件,好比該實例中的SampleOrder.csv文件。 該文件在VSS上的路徑爲: Jboss ESB實例\實例2\James\src\test

固然Jboss ESB還能夠讀取多種類型的文件,好比.xml文檔等。

②調用者端的代碼 該類在VSS的路徑以下: Jboss ESB實例\實例2\James\src\test

package test;

import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.util.Hashtable;

import javax.jms.JMSException; import javax.jms.ObjectMessage;

import javax.jms.Queue; import javax.jms.QueueConnection; import javax.jms.QueueConnectionFactory; import javax.jms.QueueSender; import javax.jms.QueueSession;

import javax.naming.Context;

import javax.naming.InitialContext; import javax.naming.NamingException;

import org.jboss.soa.esb.util.FileUtil;

public class testCvsMassage {     QueueConnection conn;     QueueSession session;     Queue que;             public void setupConnection() throws JMSException, NamingException     {    

    Hashtable properties1 = new Hashtable();           properties1.put(Context.INITIAL_CONTEXT_FACTORY,           "org.jnp.interfaces.NamingContextFactory");           properties1.put(Context.URL_PKG_PREFIXES,           "org.jboss.naming:org.jnp.interfaces");           properties1.put(Context.PROVIDER_URL, "jnp://127.0.0.1:1099");   //        InitialContext iniCtx = new InitialContext(properties1); 

//        Object tmp = iniCtx.lookup("ConnectionFactory");   //        QueueConnectionFactory qcf = (QueueConnectionFactory) tmp;  

//        conn = qcf.createQueueConnection();   //        que = (Queue) iniCtx.lookup("queue/esb-tb-bankRequestQueue");//("queue/esb-tb-bankRequestQueue");//("queue/quickstart_helloworld_action_Request"); //        session = conn.createQueueSession(false, QueueSession.AUTO_ACKNOWLEDGE);   //        conn.start();   //        System.out.println("Connection Started");       InitialContext iniCtx = new InitialContext(properties1);     Object tmp = iniCtx.lookup("ConnectionFactory");     QueueConnectionFactory qcf = (QueueConnectionFactory) tmp;     conn = qcf.createQueueConnection();     que = (Queue) iniCtx.lookup("queue/quickstart_transform_CSV2XML_gw");     session = conn.createQueueSession(false, QueueSession.AUTO_ACKNOWLEDGE);     conn.start();     System.out.println("Connection Started");     }         public void stop() throws JMSException     {         conn.stop();         session.close();         conn.close();     }         public void sendAMessage(String fileName) throws JMSException, FileNotFoundException, IOException {    

        QueueSender send = session.createSender(que);         ObjectMessage tm;         File file = new File(fileName);                 if(!file.exists()) {         throw new IllegalArgumentException("Input message file [" + file.getAbsolutePath() + "] not found.");         }

                String message = FileUtil.readTextFile(file);

                tm = session.createObjectMessage(message);         tm.setStringProperty("jbesbfilename", "transformedmessageCSV2XML.log");         send.send(tm);                send.close();                 System.out.println("*** Switch back to the ESB Java console now to see '" + fileName + "' before and after the transformation...");

    }                public static void main(String args[]) throws Exception     {                testCvsMassage sm = new testCvsMassage();     sm.setupConnection();     sm.sendAMessage("SampleOrder.csv");     sm.stop();     }     } 上面的這句代碼sm.sendAMessage("SampleOrder.csv");表示讀取SampleOrder.csv文件中的內容。    ③Jboss ESB端的代碼    該代碼在VSS上的路徑爲:    Jboss ESB實例\實例2\HelloESB\src\META-INF    Ⅰ、jboss-esb.xml     <?xml version="1.0"?> <jbossesb xmlns="http://anonsvn.labs.jboss.com/labs/jbossesb/trunk/product/etc/schemas/xml/jbossesb-1.0.1.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://anonsvn.labs.jboss.com/labs/jbossesb/trunk/product/etc/schemas/xml/jbossesb-1.0.1.xsd http://anonsvn.labs.jboss.com/labs/jbossesb/trunk/product/etc/schemas/xml/jbossesb-1.0.1.xsd">     <providers>

          <jms-provider name="JBossMQ" connection-factory="ConnectionFactory">                      

              <jms-bus busid="quickstartGwChannel">                   <jms-message-filter                       dest-type="QUEUE"                       dest-name="queue/quickstart_helloworld_action_Request"

                  />               </jms-bus>               <jms-bus busid="quickstartEsbChannel">

                  <jms-message-filter                       dest-type="QUEUE"                       dest-name="queue/B"

                  />               </jms-bus>                                           <!--加被嶽鄉成 --> <jms-bus busid="creditAgencyRequest"> <jms-message-filter dest-type="QUEUE" dest-name="queue/esb-tb-creditAgencyQueue" /> </jms-bus> <jms-bus busid="bankResponseGateway"> <jms-message-filter dest-type="QUEUE" dest-name="queue/esb-tb-bankGatewayResponseQueue"/> </jms-bus> <jms-bus busid="bankResponseListener"> <jms-message-filter dest-type="QUEUE" dest-name="queue/esb-tb-bankResponseQueue"/> </jms-bus> <!--加被嶽鄉成 --> <jms-bus busid="quickstartCSVGwChannel">

<jms-message-filter dest-type="QUEUE" dest-name="queue/quickstart_transform_CSV2XML_gw" /> </jms-bus>

<jms-bus busid="quickstartCSVEsbChannel"> <jms-message-filter dest-type="QUEUE" dest-name="queue/quickstart_transform_CSV2XML_esb" />

</jms-bus>

 

          </jms-provider>       </providers>             <services>                   <service category="HelloWorld_ActionESB"                  name="SimpleListener"

                 description="Hello World" >             <listeners>                 <jms-listener name="JMS-Gateway"                     busidref="quickstartGwChannel"                                             is-gateway="true"                 />                 <jms-listener name="JMS-ESBListener"                               busidref="quickstartEsbChannel"

                />                            </listeners>

            <actions mep="OneWay">             <action name="action2"                     class="org.jboss.soa.esb.actions.SystemPrintln"                     />                <action name="displayAction"                class="org.jboss.soa.esb.samples.quickstart.helloworldaction.MyJMSListenerAction"                process="displayMessage">                <property name="exceptionMethod" value="exceptionHandler"/>

               </action>      <action name="playAction"      class="org.jboss.soa.esb.samples.quickstart.helloworldaction.MyJMSListenerAction"      process="playWithMessage">                                 <property name="exceptionMethod" value="exceptionHandler"/>      </action>                <action name="notificationAction"                class="org.jboss.soa.esb.actions.Notifier">                <property name="okMethod" value="notifyOK" />                <property name="notification-details">       <NotificationList type="OK">            <target class="NotifyConsole" />     <target class="NotifyQueues">            <messageProp name="quickstart" value="hello_world_action" />           <queue jndiName="queue/quickstart_helloworld_action_Response"/>      </target>           </NotificationList>        </property>      </action>   

            </actions>         </service>

                        <!--加被嶽鄉成 -->     <service category="tbCreditAGency" name="creditagency" description="Credit Agency Service"> <listeners> <jms-listener name="trailblazer-jmscreditagency"   busidref="creditAgencyRequest"   maxThreads="1"/>   </listeners> <actions> <action class="org.jboss.soa.esb.samples.quickstart.testbyyuexiangcheng.CreditAgencyActions" process="processCreditRequest" name="fido"> </action> </actions> </service> <service category="tbJmsbank" name="jmsbankreplies" description="Trailblazer Bank Reply Service"> <listeners> <jms-listener name="trailblazer-jmsbank" busidref="bankResponseGateway" maxThreads="1" is-gateway="true"/> <jms-listener name="trailblazer-jmsbankreplies"   busidref="bankResponseListener"

  maxThreads="1"/> </listeners> <actions> <action class="org.jboss.soa.esb.samples.quickstart.testbyyuexiangcheng.BankResponseActions" process="processResponseFromJMSBank" name="pepe"/> </actions> </service>         <!--加被嶽鄉成 -->      <service category="QuickstartTransformCSV" name="SimpleListener"  description="Hello World"> <listeners>

<jms-listener name="CSVJMS-Gateway" busidref="quickstartCSVGwChannel" is-gateway="true"/> <jms-listener name="CSVquickstart" busidref="quickstartCSVEsbChannel"/> </listeners>

<actions mep="OneWay">                     <!--

                    Note that with this quickstart, the transformation is broken into 2 transforms; CSV to XML                     and XML to XML.  These 2 transformations could easly be merged into a single transform, saving                     on XML processing.                     -->

                    <action name="print-before" class="org.jboss.soa.esb.actions.SystemPrintln"> <property name="message" value="[transform_CSV2Smooks_Intermediate_format] Message before CVS to XML transformation" />             </action>

                    <!--                     Transform. 1: Source CSV to Canonical XML...                     --> <action name="transform-from-csv" class="org.jboss.soa.esb.smooks.SmooksAction">                         <property name="smooksConfig" value="/smooks-res.xml" />             <property name="messageProfile" value="source-csv" />                 </action>

<action name="print-after-csv-tranform" class="org.jboss.soa.esb.actions.SystemPrintln"> <property name="message" value="[transform_CSV2Smooks_Intermediate_format] Message after CVS to XML transformation" />             </action>

                    <!--                     Transform. 2: Canonical XML to target XML...                     -->

                    <action name="transform-to-xml" class="org.jboss.soa.esb.smooks.SmooksAction">                         <property name="smooksConfig" value="/smooks-res.xml" />                         <property name="messageProfile" value="canonical-xml" />                     </action>

<action name="print-after-xml-transform" class="org.jboss.soa.esb.actions.SystemPrintln">             <property name="message" value=">>>> Message after Smooks intermediate xml -> target xml : " /> </action>

</actions>

</service>                </services> </jbossesb>     上面綠色區域的代碼表示Jboss ESB服務器把.cvs文件轉換爲.xml文件的過程。 <action name="transform-from-csv" class="org.jboss.soa.esb.smooks.SmooksAction">這句代碼中的class="org.jboss.soa.esb.smooks.SmooksAction"是Jboss ESB提供的。 Jboss ESB提供了好多關於數據轉換的例子,請詳細參考。

三、 基於內容的路由 關於內容的路由,我在這裏就不詳細說了,請詳細參考: jbossesb-4.4.GA\samples\quickstarts下的

四、 Jboss ESB的業務流 關於Jboss ESB的業務流,我在這裏也不詳細說了,請詳細參考: jbossesb-4.4.GA\samples\quickstarts下的

 

五、 以JMS爲消息在Jboss ESB上的一個應用。

該實例的源碼在VSS上的路徑是: SOA\ JMS在Jboss ESB中的應用 這個實例包括三個部分<1>Jboss ESB服務器端(192.168.1.101 esb文件夾下的工程)。<2>服務消費者端(192.168.1.111文件夾下的工程)。<3>服務提供者端(192.168.1.121文件夾下的工程)。

   ①Jboss ESB服務器端    Ⅰ、Jboss-esb.xml文件    該文件在VSS上的路徑爲:

  JMS在Jboss ESB中的應用\192.168.1.101 esb\Medicare_esb\src\META-INF    <?xml version = "1.0" encoding = "UTF-8"?> <jbossesb xmlns="http://anonsvn.labs.jboss.com/labs/jbossesb/trunk/product/etc/schemas/xml/jbossesb-1.0.1.xsd" parameterReloadSecs="5">

    <providers>           <jms-provider name="JBossMQ" connection-factory="ConnectionFactory">               <jms-bus busid="quickstartGwChannel">                   <jms-message-filter                       dest-type="QUEUE"                       dest-name="queue/quickstart_transform_pojo_gw"                    />               </jms-bus>               <jms-bus busid="quickstartEsbChannel">                   <jms-message-filter                       dest-type="QUEUE"                       dest-name="queue/quickstart_transform_pojo_esb"

                  />               </jms-bus>

          </jms-provider>       </providers>             <services>         <service         category="MyTransformationServicesESB"         name="MyFirstTransformationServiceESB"         description="ESB: Takes XML in and produces a POJO">             <listeners>                 <jms-listener name="JMS-Gateway"                     busidref="quickstartGwChannel"                     is-gateway="true"                 />                 <jms-listener name="jmsTransformer"                               busidref="quickstartEsbChannel"                 />             </listeners>             <actions mep="OneWay">

                <action name="displayBeforeTransformer"                   class="org.jboss.soa.esb.samples.medicare.MyJMSListenerAction"

                   process="displayMessage"                 />  

                <action name="returnToSender"                 class="org.jboss.soa.esb.samples.medicare.MyJMSListenerAction" process="sendResponse" />             <!--              <action name="receiveMsg"                 class="org.jboss.soa.esb.samples.medicare.ReceiveMessage" process="displayMessage" />            

            <action name="receiveMsg"

                class="org.jboss.soa.esb.samples.medicare.ReceiveMessage" process="sendResponse" />   -->                                       </actions>         </service>       </services>

     </jbossesb> Ⅱ、 在Jboss ESB服務器上的Action      在VSS上的路徑爲:      JMS在Jboss ESB中的應用\192.168.1.101 esb\Medicare_esb\src\org\jboss\soa\esb\samples\medicare      這個文件夾下的內容就是消息的攔截器,負責對消息的攔截。詳細內容請查看相關的代碼。

②消費者端的代碼。

  該工程在VSS上的路徑爲:   JMS在Jboss ESB中的應用\192.168.1.121   相關的代碼請詳細參考該工程。 ③提供者端的代碼。

  該工程在VSS上的路徑爲: JMS在Jboss ESB中的應用\192.168.1.111   相關的代碼請詳細參考該工程。 六、 以Web Service爲基礎在Jboss ESB上的一個應用。     該工程在VSS上的路徑爲:     SOA\SOA(V1.2) 這個實例也包括三個部分<1>Jboss ESB服務器端(Esb Service(192.168.1.101)文件夾下的工程)。<2>服務消費者端(Request endpoint(192.168.1.112)文件夾下的工程)。<3>服務提供者端(Respose endpoint(192.168.1.111)文件夾下的工程)。 服務消費者端和服務提供者端我已經在另外一個文檔中《Web Service簡介及開發實例》中作了詳細的介紹。 如今我只簡單的討論一下再Jboss ESB服務器端的代碼。 ①先看Jboss-esb.xml文件 該文件在VSS上的路徑爲: SOA(V1.2)\Esb Service(192.168.1.101)\WebService\src\META-INF <?xml version = "1.0" encoding = "UTF-8"?>

<jbossesb         xmlns="http://anonsvn.labs.jboss.com/labs/jbossesb/trunk/product/etc/schemas/xml/jbossesb-1.0.1.xsd"         parameterReloadSecs="5">

    <providers>         <jms-provider name="JBossMQ" connection-factory="ConnectionFactory">

            <jms-bus busid="quickstartGwChannel">                 <jms-message-filter dest-type="QUEUE" dest-name="queue/quickstart_webservice_producer_gw"/>

            </jms-bus>             <jms-bus busid="quickstartEsbChannel">                 <jms-message-filter dest-type="QUEUE" dest-name="queue/quickstart_webservice_producer_esb"/>

            </jms-bus>         </jms-provider>

        <jbr-provider name="JBR-Http" protocol="http" >             <jbr-bus busid="Http-1" port="8765" />         </jbr-provider>

        <jbr-provider name="JBR-Socket" protocol="socket" host="localhost">             <jbr-bus busid="Socket-1" port="8888" />

        </jbr-provider>

 

    </providers>

    <services>

        <service category="MyServiceCategory" name="MyWSProducerService" description="WS Frontend speaks natively to the ESB">

            <listeners>

                <jms-listener name="JMS-Gateway" busidref="quickstartGwChannel" is-gateway="true"/>                 <jbr-listener name="Http-Gateway" busidref="Http-1" is-gateway="true"/>                 <jbr-listener name="Socket-Gateway" busidref="Socket-1" is-gateway="true"/>

                <jms-listener name="JMS-ESBListener" busidref="quickstartEsbChannel"/>             </listeners>             <actions>                 <action name="print-before" class="org.jboss.soa.esb.actions.SystemPrintln">                     <property name="message"                               value="[Quickstart_webservice_producer] BEFORE invoking jbossws endpoint"/>                 </action>                 <action name="JBossWSAdapter" class="org.jboss.soa.esb.actions.soap.SOAPProcessor">                     <property name="jbossws-endpoint" value="GoodbyeWorldWS"/>                 </action>                 <action name="print-after" class="org.jboss.soa.esb.actions.SystemPrintln">

                    <property name="message"

                              value="[Quickstart_webservice_producer] AFTER invoking jbossws endpoint"/>                 </action> <action name="testStore" class="org.jboss.soa.esb.actions.TestMessageStore"/>             </actions>         </service>

    </services>

</jbossesb> ②Jboss ESB服務器上的Action類,代碼以下: 該類在VSS上的路徑爲: SOA(V1.2)\EsbService(192.168.1.101)\WebService\src\org\jboss\soa\esb\samples\quickstart\webserviceproducer\webservice 代碼以下:     package org.jboss.soa.esb.samples.quickstart.webserviceproducer.webservice;

import java.io.BufferedReader; import java.io.ByteArrayOutputStream; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; import java.util.ArrayList; import java.util.List;

 

import javax.jws.WebMethod; import javax.jws.WebParam; import javax.jws.WebResult; import javax.jws.WebService; import javax.xml.soap.MessageFactory; import javax.xml.soap.Name; import javax.xml.soap.SOAPBody; import javax.xml.soap.SOAPConnection; import javax.xml.soap.SOAPConnectionFactory; import javax.xml.soap.SOAPConstants; import javax.xml.soap.SOAPElement;

import javax.xml.soap.SOAPEnvelope; import javax.xml.soap.SOAPException; import javax.xml.soap.SOAPFactory; import javax.xml.soap.SOAPMessage; import javax.xml.soap.SOAPPart; import javax.xml.transform.Source; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerConfigurationException; import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerFactory; import javax.xml.transform.TransformerFactoryConfigurationError; import javax.xml.transform.stream.StreamResult;

/** * @author

*/ @WebService(name = "GoodbyeWorldWS", targetNamespace="http://webservice_producer/goodbyeworld") public class GoodbyeWorldWS {

public static final String INDEXOFOBJECTSTART = "<Hotel>"; public static final String INDEXOFOBJECTEND = "</Hotel>"; public static final int BJECTSTARTFLAGLENGTH = INDEXOFOBJECTSTART.length(); public static final int BJECTENDFLAGLENGTH = INDEXOFOBJECTEND.length();

    @WebMethod     @WebResult(name="ListHotel")     public String sayGoodbye(@WebParam(name="message") String message){           try {

            //傳送參數須要建立Name

            SOAPFactory soapFactory = SOAPFactory.newInstance();                    //Next, create the actual message             MessageFactory messageFactory = MessageFactory.newInstance();             SOAPMessage message1 = messageFactory.createMessage();                         //Create objects for the message parts                        SOAPPart soapPart =     message1.getSOAPPart();             SOAPEnvelope envelope = soapPart.getEnvelope();             SOAPBody body =         envelope.getBody();             //Populate the body             //Create the main element and namespace

            SOAPElement bodyElement =                       body.addChildElement(envelope.createName("getHotelObject" ,                                                                     "serch",                                        "http://tower/ehr_DEV"));             bodyElement.setEncodingStyle(SOAPConstants.URI_NS_SOAP_ENCODING);                         //傳送參數新建一個Name對象             Name name = soapFactory.createName("arg0");

 

            SOAPElement symbol = bodyElement.addChildElement(name);             symbol.addTextNode(message);             //Add content             //Save the message             message1.saveChanges();             //Send the message and get a reply                        //Set the destination             //Send the message            

            List<String> destinationList = readTxtFile("D:/webServiceConfig.txt");                         String resultString = getResultString(destinationList,message1);                         if("".equals(resultString)){             return "";             }else{

            return resultString;             }        } catch(Exception e) {

               System.out.println(e.getMessage());            } return "";

    }    

   

    public static List<String> readTxtFile(String fileName){         String read;

        FileReader fileread;         List<String> l = new ArrayList<String>();         try {             fileread = new FileReader(fileName);             BufferedReader bufread = new BufferedReader(fileread);

            try {                 while ((read = bufread.readLine()) != null) {

                l.add(read);                 }             } catch (IOException e) {             }         } catch (FileNotFoundException e) {

            e.printStackTrace();         }         return l;     }             public static String getResultString(List<String> destinationList,SOAPMessage message){     try {     String resultString = "";             for(int i = 0;i<destinationList.size();i++){

            String destination = destinationList.get(i);             SOAPConnectionFactory soapConnFactory = SOAPConnectionFactory.newInstance();                 SOAPConnection connection =  soapConnFactory.createConnection();

            SOAPMessage reply = connection.call(message, destination);             String stringBady = getSOAPMessageStringBady(reply);             resultString = resultString + stringBady;             connection.close();             }             return resultString; } catch (UnsupportedOperationException e) { e.printStackTrace(); } catch (SOAPException e) { e.printStackTrace(); } return "";     }

        public static String getSOAPMessageStringBady(SOAPMessage reply) {          try { String sb = "";         Source source = reply.getSOAPPart().getContent();         Transformer transformer = TransformerFactory.newInstance().newTransformer();         ByteArrayOutputStream myOutStr = new ByteArrayOutputStream();         StreamResult res = new StreamResult();         res.setOutputStream(myOutStr);         transformer.transform(source,res);         String temp = myOutStr.toString().trim();         int indexOfObjectStart = temp.indexOf(INDEXOFOBJECTSTART);         if(indexOfObjectStart==-1){         return sb;         }else{             int indexOfObjectEnd = temp.lastIndexOf(INDEXOFOBJECTEND);             sb = temp.substring(indexOfObjectStart,indexOfObjectEnd+OBJECTENDFLAGLENGTH);             return sb;         } } catch (TransformerConfigurationException e) { e.printStackTrace(); } catch (TransformerFactoryConfigurationError e) { e.printStackTrace(); } catch (SOAPException e) { e.printStackTrace(); } catch (TransformerException e) { e.printStackTrace(); }

return "";       }

}

相關文章
相關標籤/搜索