#1. CXF 拦截器
CXF拦截器类似Struts2拦截器,通过拦截对信息进行特殊处理,如日志记录,Soap消息处理,消息的压缩处理等,CXF拦截器分为客户端拦截器链和服务器拦截器链,CXF默认现实多种拦截器,且已经在发布,请求的时候默认添加在拦截器链中,我们也可自定义拦截器,同时可在<jaxws:client>和<jaxws:server>或<jaxws:endpoint>种配置
1. 创建拦截器(继承AbstractPhaseInterceptor类或子类AbstractSoapInterceptor)
public class OutFirstInterceptor extends AbstractPhaseInterceptor<Message>{ //可通过Phase类的常量指定拦截器何时有效 @Override public void handleFault(Message arg0) { System.out.println("OutFirstInterceptor#handleFault()错误拦截处理..."); } @Override public void handleMessage(Message arg0) throws Fault { System.out.println("OutFirstInterceptor#handleMessage()消息拦截处理..."); } public OutFirstInterceptor(){ //此处指定该拦截器在发送的时候有效 super(Phase.SEND); } public OutFirstInterceptor(String phase){ //在给定参数时有效 super(phase); } } public class InFirstInterceptor extends AbstractPhaseInterceptor<Message>{ //可通过Phase类的常量指定拦截器何时有效 @Override public void handleFault(Message arg0) { System.out.println("InFirstInterceptor#handleFault()错误拦截处理..."); } @Override public void handleMessage(Message arg0) throws Fault { System.out.println("InFirstInterceptor#handleMessage()消息拦截处理..."); } public InFirstInterceptor(){ //此处指定该拦截器在发送的时候有效 super(Phase.RECEIVE); } public InFirstInterceptor(String phase){ //在给定参数时有效 super(phase); } }
2. 拦截器的配置(客户端和服务器端)
<jaxws:server>或<jaxws:endpoint>配置服务端与上面配置客户端拦截器相同,<jaxws:server>为cxf的,因java使用Endpoint.publish()发布服务,固增加<jaxws:endpoint><jaxws:client id="localClient" serviceClass="ws.IService" address="http://localhost:8080/ws/IService"> <!-- 输入拦截器配置 --> <jaxws:inInterceptors> <ref bean="inMessageInterceptor"/> <ref bean="localInFirstInterceptor"/> </jaxws:inInterceptors> <!-- 输出拦截器配置 --> <jaxws:outInterceptors> <ref bean="outMessageInterceptor"/> <ref bean="localOutFirstInterceptor"/> </jaxws:outInterceptors> <!-- 配置处理器 --> </jaxws:client> <bean id="inMessageInterceptor" class="org.apache.cxf.interceptor.LoggingInInterceptor" /> <bean id="outMessageInterceptor" class="org.apache.cxf.interceptor.LoggingOutInterceptor"/> <bean id="localInFirstInterceptor" class="ws.InFirstInterceptor"/> <bean id="localOutFirstInterceptor" class="ws.OutFirstInterceptor"/>
#2. Feature(拦截器栈)
Feature即拦截器栈,用于绑定多个拦截器,简化拦截器繁杂的配置
1. 创建Feature
2. Feature的配置(客户端和服务器端)public class LocalFeature extends AbstractFeature{ //用于简化配置,捆绑多个拦截器,继承AbstractFeature或实现Feature接口,重写initializeProvider方法 @Override protected void initializeProvider(InterceptorProvider provider, Bus bus) { provider.getInInterceptors().add(new InFirstInterceptor()); provider.getOutInterceptors().add(new OutFirstInterceptor()); } }
<jaxws:client id="localClient" serviceClass="ws.IService" address="http://localhost:8080/ws/IService"> <!-- 输入拦截器配置 <jaxws:inInterceptors> <ref bean="inMessageInterceptor"/> <ref bean="localInFirstInterceptor"/> </jaxws:inInterceptors>--> <!-- 输出拦截器配置 <jaxws:outInterceptors> <ref bean="outMessageInterceptor"/> <ref bean="localOutFirstInterceptor"/> </jaxws:outInterceptors>--> <!-- 配置拦截器栈,绑定多个拦截器 --> <jaxws:features> <ref bean="localFeature"/> </jaxws:features> </jaxws:client> <bean id="localFeature" class="ws.LocalFeature"/>
<jaxws:server>或<jaxws:endpoint>配置服务端与上面配置客户端相同
#3. CXF 获取HTTP对象
@WebService(endpointInterface="ws.IService") public class ServiceImpl implements IService{ @Resource WebServiceContext wsc; @Override public String login(String name, String pwd) { //cxf 获取 http 对象使用下面3种任意一种方式 //方式1 注入WebServiceContext后获取MessageContext MessageContext context = wsc.getMessageContext(); HttpServletRequest req = (HttpServletRequest)context.get(AbstractHTTPDestination.HTTP_REQUEST); HttpServletResponse resp = (HttpServletResponse)context.get(AbstractHTTPDestination.HTTP_RESPONSE); ServletContext servletContext = (ServletContext)context.get(AbstractHTTPDestination.HTTP_CONTEXT); //方式2 //HttpServletRequest req = (HttpServletRequest)context.get(MessageContext.SERVLET_REQUEST); //方式3 //Message message = PhaseInterceptorChain.getCurrentMessage(); //HttpServletRequest req = (HttpServletRequest)message.get(AbstractHTTPDestination.HTTP_REQUEST); System.out.println("请求ip为: "+req.getRemoteAddr()+"--当前时间--"+new Date().getTime()); if(name.equals("123") && pwd.equals("456")){ return "登录成功"; }else{ return "用户名或密码失败"; } } }
#4. Handler
1. 创建Handler
2. Handler 的配置(客户端和服务器端)/*JAX-WS的Handler和Servlet的Filter相似,可以对所有WebServicer进行拦截,在Handler中可以记录日志、权限控制、对请求的SOAP消息进行加密,解密等。JAX-WS提供两个Handler接口, LogicalHandler和SOAPHandler。LogicalHandler处理的是Message Payload,只能够访问消息单元中的SOAP消息体。SOAPHandler处理的是整个SOAP消息(包含SOAP header和SOAP body),可以访问整个SOAP消息。 如果依次声明了H1,H2,H3,H4几个Handler,对于进站的Message,则依次通过H1,H2,H3,H4,然后到Endpoint。对于出站的消息,则依次通过H4,H3,H2,H1. 所以,整个消息经过的路径应该是H1,H2,H3,H4,Endpoint,H4,H3,H2,H1. */ public class LocalHandler implements Handler<MessageContext>{ //调用webService inbound和outbound时都会调用,一次webService调用 会调用该方法两次 //如果返回ture,继续调用下一个handler,返回false,则直接返回message @Override public boolean handleMessage(MessageContext context) { System.out.println("LocalHandler#handleMessage()---11111"); return true; } //当handlerMessage发生异常时,会调用,如果返回ture,继续调用下一个handler,返回false,则直接返回message @Override public boolean handleFault(MessageContext context) { System.out.println("LocalHandler#handleFault()---22222"); return false; } //webService调用结束时会调用,通常会做释放资源的操作 @Override public void close(MessageContext context) { System.out.println("LocalHandler#close()---333333"+"--当前时间--"+new Date().getTime()); } }
<jaxws:server>或<jaxws:endpoint>配置服务端与上面配置客户端相同<jaxws:client id="localClient" serviceClass="ws.IService" address="http://localhost:8080/ws/IService"> <!-- 配置处理器 --> <jaxws:handlers> <ref bean="localHandler"/> </jaxws:handlers> <!-- 配置拦截器栈,绑定多个拦截器 --> <jaxws:features> <ref bean="localFeature"/> </jaxws:features> <!-- <jaxws:properties> <entry key="mtom_enabled" value="true"></entry> </jaxws:properties>--> </jaxws:client> <bean id="localHandler" class="ws.LocalHandler"/> <bean id="localFeature" class="ws.LocalFeature"/>