作者:清华大学 戴凤军 原帖地址已找不到
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