作者:清華大學 戴鳳軍 原帖地址已找不到
WS-Addressing協議
主要包括三部分內容,一是EndpointReference定義,實際上一個定義了一個服端點的模型。二是MAP屬性的定義,即消息尋址需要設定和支持的相關屬性,三是協議的綁定方式,即如何將協議綁定到現有的協議實現之上如WSDL和SOAP。
主要用來解決以下問題:一是實現與底層傳輸的隔離,通過將尋址信息放在SOAP頭部從而擺脫了對底層協議尋址的依賴。二是結合實現基于消息的路由,可以根據ReplyTo屬性實現基于消息的路由。三是實現有狀態的會話,基于MessageID和RelatesTO屬性實現對會話狀態保存機制,從而提供有狀態的服務。
下面基于以上內容對Axis2和CXF關于WS-Addressing的實現情況進行簡單的對比
一、AXIS2
支持情況:
支持的版本:submission(2004.8)和final (2005.8)兩個版本。
 
EndPointReferance在Axis2里是一個核心概念,它通過EndpointReference類型來實現,它所提供的方法完全支持WS-Addressing協議所定義infoset中所有元素的操作。在Axis2中對服務的定位全部是基于EndPointReferance的。
MDP所定義的屬性和相應的操作接口都提供了實現。
WSDL addressing-binding在目前版本中沒有明確支持,但在一個開發成員的郵件中顯示目前已經準備提供支持,但尚無發布相應模塊。SOAP -binding在Axis2內核中得到完全的支持。需要明確引入Addresing模塊才能處理,事實上僅僅在輸入輸出流中打開了相關的處理選項。
 
使用方法:
1.服務端:
在服務端默認情況下Addressing處理是已經嵌入的。加入Addressing需要將Addressing.mar模塊放到module目錄下,可以有以下幾種方式:
一是通過在Axis2.xml配置文件中添加<module ref="addressing"/>,并在相應的管道如in flow和in faultflow中添加AddressingBasedDispatcher即可(注:Axis2中默認已經添加相應內容)
二是在管理控制臺Engage相應addressing模塊。在axis2.xml 配置文件中添加以下模塊引用<module ref="addressing"/>
2.客戶端:
在客戶總端有兩種方式加入Addressing處理模塊:
一是在程序中顯示加入。如下所示:(注意需要將Addressing.mar放到可訪問路徑下)
stub._getServiceClient().engageModule(new
javax.xml.namespace.QName( org.apache.axis2.Constants.MODULE_ADDRESSING ) );
 
二是在axis2.xml 配置文件中添加以下模塊引用<module ref="addressing"/>(需要建立相應的ConfigurationContexst)
 
其它說明:
在Axis2中對服務進行定位時,根據以下四個信息來定位:HTTP request uri、SOAPAction、QName of the first child of SOAP Body element、WS-Addressing is enabled the address of To EPR。而且上述為默認的順序,可以通過更改配置文件重新更改順序。在啟用Addressing時,SOAP頭部信息的相關內容會自動覆蓋重復的內容。
 
Axis2中設置Addressing Properties是通過MessageContext來自動實現的,可以通過在MessageContext中設置相應的選項信息。在服務端, AddressingBasedDispatcher根據在消息頭部信息中取得的屬性信息來填充到MessageContext中,包括from、replyto、messagID等信息,并在返回時自動根據這些信息在返回頭部中加入上述信息。
在客戶可以通過兩種方式來加入,一個使用ServiceClient,通過如下方式來加入的:
Options options = new Options();
options.setTo(new      EndpointReference("http://address-to-webservice.org/MyService/MyOperation"));
ServiceClient sender = new ServiceClient();
sender.setOptions(options);
 
這樣如果在嵌入Addressing處理模塊時,并自動在頭部加入相應的TO信息,其中MessageID由內部自動生成保證不會重復。
在默認情況下消息頭 部僅包括destination URL (To address) 和action ,其它可選參數都沒有添加,如需要添加可以加入以下語句以提供支持。 options.setProperty(INCLUDE_OPTIONAL_HEADERS, Boolean.TRUE);
 
測試代碼說明:
1.測試環境:Axis2 2.1.1Tomcat 6.0 .Eclipse 3.2.
2.BaseTest
目的:
l        測試對底層協議的無關性,包括TCPHTTPLOCAL
l        測試同步和異步調用的支持。
l        測試對單、雙通道的支持。
測試程序說明:服務端MyService2.aar。放置到Catalina_HOME/WebApps/Axis2/Service下即可,是一個Web服務。僅用到一個Echo方法。客戶端則包括了一個測試主程序BaseTest和一個小工具類ClientUtilBaseTest根據用戶輸入選擇傳輸協議、調用方式(同步或異步)及是否打開單獨的監聽端口。ClientUtil則是輔助類,用來生成OMElement對象。其中用到EndpointReference屬性設置等及Addresing等方法。
測試結果:全部通過。
 
3.RoutingTest.
目的:
l        測試基于SOAP頭部信息的路由功能。
l        測試MessageID的關聯功能,即能否實現有狀態的交互。
l        測試out_onlyin_out操作。
l        測試服務端配置。
測試程序說明:服務端包括兩個服務:PostOffice.aarPublisher.aar。分別用來模擬郵局訂閱服務和出版社郵購服務。客戶端則為RoutingTest.java。主要提供兩個操作。一個是向郵局發送訂閱請求,些為單向,不需要回復,因為郵局可能需要等待出版社確認有無此書。二是讀者向郵局查詢自己訂閱的情況,郵局接到消息后,根據replyto設定的地址,將消息不是返回給讀者,而是自動向出版社轉發,由出版社給出相應的訂閱結果信息。基于流程如下圖所示:
 
                      subScribe (MessageId: A)
Client -------------------------------------------------> PostOffice
           
             getInfo (MessageId: B, RelatesTo:null)
Client -----------------------------------------------à PostOffice
           
           printPublishInfo (MessageId: C, RelatesTo: B)   
PostOffice ---------------------------------------------->Publisher 
 
            returnInfo (MessageId: D, RelatesTo: B)   
Publisher ---------------------------------------------->Client 
        
注意上面第四步沒有實現,因為,需要在客戶端運行一個服務,鑒于例子的復雜性。且其路由方式和第三步是相同的所以略去,僅由publisher打印出確認信息結果。
測試結果。Axis2可以根據頭部信息將相應的消息路由到其它服務結點,實現了完全基于Addresing頭部信息的路由。此外,在轉發的同時,能夠對消息ID號進行關聯。單向消息傳遞也支持很好,可以根據需要在出現異常時返回異常信息或將異常重定向到其它結點。
提示,為了更準確看到整個消息內容,可以使用Axis2下來的SOAPMonitor工具,需要在Axis2配置文件中打開監控模塊,并將SOAP_Moinitor.jar文件解壓放到Axis根據目錄下即可。輸入http://localhost:8080/axis2/SOAPMonitor可看到實時信息。
 
提示:在客戶端將Axis2下的jar包和Addressing1.1.mar回到路徑下能運行。
 
CXF
支持情況:
支持的版本: submission(2004.8)和core 1.0(2006.5)兩個版本。
 
通過EndpointReference類型支持WS-Addressing定義infoset中所有元素的操作。
MDP所定義的屬性屬性都定義了相應的操作接口。
WSDL addressing-binding得到明確支持,
SOAP addressing-binding在CXF中得到支持,但需要嵌入Addresing Interceptor才能處理。
使用方法:
1.服務端和客戶端可以有以下幾種方式:
 
一是通過在配置文件中添加下面的內容在BUS上加入Addressing Interceptor。
 <cxf:bus>
        <cxf:features>
            <wsa:addressing/>
        </cxf:features>
</cxf:bus>
二是在通過spring配置文件加入
三是程序中顯示加入
例子再說吧:
測試結果:
對異步支持較好,但是目前路由及messageId自動關聯沒有通過。原因….
目前只支持SOAP1.1而Axis2支持SOAP1.1和SOAP1.2