一、有关调用CXF拦截器
1、拦截器概述
Interceptor是CXF架构中一个很有特色的模式。你可以在不对核心模块进行修改的情况下,动态添加很多功能。这对于CXF这个以处理消息为中心的服务框架来说是非常有用的,CXF通过在Interceptor中对消息进行特殊处理,实现了很多重要功能模块,例如:日志记录,Soap消息处理,消息的压缩处理。
在Interceptor定义了两个方法,一个处理消息 handleMessage, 一个是处理错误 handleFault。别看Interceptor这么简单,这里需要提醒注意的是,在实行具体的Interceptor的这两个方法中,千万别调用Interceptor内部的成员变量。这是由于Interceptor是面向消息来进行处理的,每个Interceptor都有可能运行在不同的线程中,如果调用了Interceptor中的内部成员变量,就有在Interceptor中造成临界资源的访问的情况,而这时的Interceptor也就不是线程安全的Interceptor了。
单个的Interceptor功能有限,CXF要实现一个SOAP消息处理,需要将许许多多的Interceptor组合在一起使用。因此设计了 InterceptorChain,在我看了InterceptorChain就像是一个Interceptor的小队长。 小队长有调配安置Interceptor的权力(add,remove),也有控制消息处理的权力(doInterceptor,pause,resume,reset,abort),同时也有交付错误处理的权力( {get|set}FaultObserver)。更有意思的是为灵活控制Interceptor的处理消息顺序(doInterceptStartingAt,doInterceptorStartingAfter),这也是InterceptorChain比较难理解的地方。
2、拦截器部署
①编写interceptor,在编写自己的拦截器时通常需要继承AbstractSoapInterceptor和AbstractPhaseInterceptor<Message>其中一个。但是两者有所区别:如果继承AbstractSoapInterceptor,则在你编写的拦截器中处理消息的方法(handleMessage)中处理的是消息为SoapMessage;如果继承AbstractPhaseInterceptor<Message>,则在你编写的拦截器中处理消息的方法(handleMessage)中处理的消息为Message。
②编写完interceptor后,需要在Spring XML中配置加载拦截器,配置如下:
通常需要用的拦截器有如下:一般消息的输入/输出,错误消息的输入/输出,以日志为例,配置如下:
注意:在实现自己的拦截器中要注意构造函数,在构造函数中我们要调用父级的构造函数(子类总会调用父类的构造器 //默认是调用无参数的构造器。)并且需要指定该拦截器在哪个阶段被激发(例:super(Phase.RECEIVE)—在接受到数据时),如不指定在什么时候激发,即使配置完成,拦截器也不会被激发发挥作用。这里会多次强调。
二、有关CXF 中的Handler
1、概述
熟悉AXIS编写WebService接口的人对Handler应用比较熟悉,在进行对接口的日志、安全等处理时常用到Handler。在CXF中也有Handler这个功能。
在Handler中可以通过SOAPMessageContext获取到SOAPEnvelope,因此在Handler中也可以进行添加日志、用户授权处理、其他安全方面的处理例如:数字签名、加密等,当然这些是基于XML加密和签名实现的。
2、Handler的部署
①编写Handler。在编写Handler时,通常需要继承实现SOAPHandler<SOAPMessageContext>接口,在继承实现这个接口时,会引入多个常用的方法,其中publicboolean handleMessage(SOAPMessageContext context)和publicboolean handleFault(SOAPMessageContext context)最为常用,第一个为对消息的处理,第二个为对错误消息的处理。
②编写完成Handler后,需要在Spring配置文件中添加Handler,是他能够在系统运行是能够运营。配置如下:
三、CXF拦截器和Handler的区别
两者没有太多差别,都是在消息处理的某些阶段处理对应的消息包。Handler是JAXWS中定义的扩展接口,而Interceptor是CXF 内部消息处理的核心部件。Interceptor可以调用Handler,而Handler不能调用Interceptor。例如CXF中有一个SOAPHandlerInterceptor就负责调用对应的SOAPHandler。
四、在CXF中有关继承intercepter的注意事项:
a)如果要实现一个自己的interceptor,需要继承CXF 中interceptor的抽象类,常用抽象类有AbstractSoapInterceptor和AbstractPhaseInterceptor<Message>在具体实现中可以根据自己的具体需要继承其中的一个。
B)在实现自己的拦截器中,根据需要继承其中一个,但是要注意构造函数,在构造函数中我们要调用父级的构造函数(子类总会调用父类的构造器 //默认是调用无参数的构造器。)并且需要指定该拦截器在哪个阶段被激发(例:super(Phase.RECEIVE)—在接受到数据时)。
评论