下面是xfire客戶端呼叫的流程分析圖,本文後續部分將圍繞該圖展開。
服務模型是xfire中非常重要的概念之一,包含了服務的介面資訊、操作資訊、binding資訊等諸多服務呼叫過程中需要的資訊。因此在進行服務呼叫之前首先要建立服務模型。建立服務模型的工作是由服務工廠servicefactory完成的,使用者需要為服務工程提供服務介面、名稱、命名空間等一些資訊,其中服務介面是必須的,其他為可選資訊。
client是xfire客戶端的核心組成部分,間接的代表了乙個服務。當為具體某個服務配置***(handler,有很多種譯法如***、處理器、過濾器等,本文統一用***)時,其實是將***資訊應用到client例項上。client可以手工建立也可以由xfireproxyfactory建立,無論通過哪種方式,client在初始化過程中最重要的一步都是在out***堆疊中增加乙個outmessagesender***。該***負責最終將服務呼叫通過http傳送到服務提供者並返回處理結果。本文後續部分還會對outmessagesender做更加詳細的講解。
xfireproxy,xfire soap客戶端**實現,使用者呼叫服務時(如hello.echo("tony"))就是通過該物件的invoke方法來執行。實際上,xfireproxy只是將呼叫**到client例項,最終執行服務的還是client例項。
client例項的invoke方法在執行時,生成了乙個invocation物件,該物件構造了一次完整的呼叫資訊,包括outmessage、messagecontext等。同時invocation還負責構造乙個***管道(handlerpipeline),該管道包含了本次呼叫需要執行的所有***,當然也包括outmessagesender。這些***會分不同的階段來執行,這也是xfire乙個特性。xfire預設定義了很多階段(phase),每個階段都會有若干***被呼叫。
***(handler)是xfire中最為重要的概念,一次服務呼叫就是由若干***組合完成的。xfire預設提供了很多預定義的***,使用者也可以定義自己的***。基本上,通過***可以影響xfire執行過程中的任何步驟,你可以為所欲為:)
***有兩個重要的概念,乙個是階段(phase),乙個是順序(order)。這兩個因素共同決定了***的執行順序。可以在三個不同的地方配置***:
n xfire例項:全域性***,對所有通道上的所有服務起作用
n transport:通道特定的***,只對該通道(如http、jms)起作用
n 具體服務:服務特定的***,只對該服務起作用
其實,具體服務上的***最終是配置到client上。對於同乙個階段上的***,執行順序為"具體服務-->transport-->xfire例項"。千萬不要忽視這些順序,這對你正確的使用***非常有幫助。
這是整個呼叫鏈中最後的一環,也是最關鍵的一步。outmessagehandler,前文已經有所提及,是乙個特殊的***,在client初始化時建立並加入呼叫鏈中。該***處於***呼叫鏈的phase.send階段,基本上也是最後的階段。outmessagehandler從當前呼叫的訊息上下文(messagecontext)中獲取請求的服務位址uri以及soap訊息,然後通過http將soap請求傳送到遠端伺服器(針對http通道,如果是jms通道則傳送到指定的目的地)。最終將遠端伺服器的響應逐級返回給呼叫者。
前文很多地方都提到handler非常重要,那麼具體有那些應用場景呢?本部分通過兩個案例逐步演示handler的應用。
一、簡單安全驗證
這是乙個非常典型的應用場景,假設a公司對外提供了乙個旅程資訊查詢服務,該服務通過xfire對外發布。但是a公司只希望其合作夥伴才能使用該服務,那麼a公司可以為該服務配置乙個handler,該handler從soap的訊息頭中獲取認證字串,只有通過驗證的請求才被執行。下面是簡單的示例**,真實情況要比這複雜得多。
publicvoidinvoke(messagecontext context)throwsexception
unknown macro:
/ }對於a公司的合作夥伴,要想呼叫該服務,必須在其soap的訊息頭中包含上面**中的驗證字串,否則服務將被拒絕。下面是簡單的示例**:
publicvoidinvoke(messagecontext context)throwsexception
unknown macro:
二、查詢真實服務
這是乙個比較特殊的應用場景:假設a公司已經初步實現soa,擁有乙個服務註冊中心,所有的xfire服務都在該中心註冊。客戶端在呼叫服務時需要動態的從該服務註冊中心獲取當前的服務位址及版本。通過其他方式肯定也可以實現該需求,但是通過handler來實現會非常的幽雅,而且對應用不需要做任何變動。我們先來看一下handler的**:
publicvoidinvoke(messagecontext context)throwsexception
unknown macro:
privatevoidlookuprealserviceuri(messagecontext context)
unknown macro:
*catch* (+exception+ e)
unknown macro:
/ context.getoutmessage().seturi(uri);/ }
正如**所示,只需要從context中獲取當前請求的服務uri位址,然後用當前請求環境資訊及服務uri位址到服務註冊中心查詢真實的服務,並重新設定服務的位址。
本文粗略的介紹了xfire客戶端的呼叫流程,並著重講解了handler的擴充套件機制及其應用場景,力求讀者能夠通過本文對xfire能有更加深入的了解和掌握。文中難免存在不足之處,歡迎任何形式的交流。
XFire客戶端開發
引入 xfire相關的類庫 1.使用wsdl生成靜態客戶端 訪問任意語言編寫的web service 2.使用介面生成靜態客戶端 必須拿到服務端的介面class檔案 遠端 工廠 xfireproxyfactory factory new xfireproxyfactory 建立服務模型 servic...
xfire 客戶端 超時異常
今天碰到個問題,xfire客戶端呼叫遠端的webservice伺服器,在異常日誌stdout中打了些read timeout 後,從jconsole觀察到resin的執行緒數量直線上公升,直到把所有執行緒都佔滿,後來看到是xfire的xfireclientfactorybean的 getclient...
10 2 2 客戶端流程分析
客戶端主要包括以下主要函式過程 初始化 ssl演算法函式 連線並接收伺服器訊息執行緒函式 向伺服器傳送訊息函式。1 初始化 ssl演算法 此過程的 新增在 oninitdialog 方法中。處理過程如下 1 初始化 openssl 演算法庫ssl load error strings ssleay ...