CXF拦截器..为什么要使用拦截器...
WebService发布之后 , 只要获取到URL , 貌似任何人都可以访问呢.. 这样子就引申出一个安全的问题(安全问题后面再说)
CXF的拦截器是CXF功能最主要的扩展点。通过自定义的Interceptor,可以改变请求和响应的一些消息处理,其中最基本的原理还是一个动态代理
Interceptor是CXF架构中一个很有特色的模式。你可以在不对核心模块进行修改的情况下,动态添加很多功能。这对于CXF这个以处理消息为中心的服务框架来说是非常有用的,CXF通过在Interceptor中对消息进行特殊处理,实现了很多重要功能模块,例如:日志记录,Soap消息处理,消息的压缩处理。
参考 : http://lavasoft.blog.51cto.com/62575/167288/
这里提供完整的CXF加入拦截器的项目工程代码
CXF使用Endpoint发布WenService并加入拦截器
CXF发布WenService并加入拦截器
关于Jar包 , 将下载下来的CXF安装包中lib全部导入...(简单粗暴)
1. 第一种
工程截图
接口
package com.cxf.interceptor.server.inter; import javax.jws.WebService; @WebService public interface CXFDemoInterface { public String sayHello(String username); }
接口实现方法
package com.cxf.interceptor.server.inter; public class CXFDemoImpl implements CXFDemoInterface { @Override public String sayHello(String username) { System.out.println("server : " + username); return "hello : " + username; } }
拦截器实现方法
package com.cxf.interceptor.server.interceptor; import org.apache.cxf.interceptor.Fault; import org.apache.cxf.message.Message; import org.apache.cxf.phase.AbstractPhaseInterceptor; public class MessageInterceptor extends AbstractPhaseInterceptor<Message> { public MessageInterceptor(String phase) { super(phase); // TODO Auto-generated constructor stub } @Override public void handleMessage(Message message) throws Fault { System.out.println("----- 进入拦截器 -----"); System.out.println("message : " + message); if (null != message.getDestination()) { System.out.println(message.getId() + " # " + message.getDestination().getMessageObserver()); } if (null != message.getExchange()) { System.out.println(message.getExchange().getInMessage() + " # " + message.getExchange().getInFaultMessage()); System.out.println(message.getExchange().getOutMessage() + " # " + message.getExchange().getOutFaultMessage()); } System.out.println("----- 离开拦截器 -----"); } }
发布主方法
package com.cxf.interceptor.server; import org.apache.cxf.endpoint.Server; import org.apache.cxf.jaxws.JaxWsServerFactoryBean; import org.apache.cxf.phase.Phase; import com.cxf.interceptor.server.inter.CXFDemoImpl; import com.cxf.interceptor.server.interceptor.MessageInterceptor; public class CXFServerStart { public static void main(String[] args) { String address = "http://localhost:8088/CXFDemo/sayHello"; JaxWsServerFactoryBean factory = new JaxWsServerFactoryBean(); factory.setServiceClass(CXFDemoImpl.class); factory.setAddress(address); factory.setServiceBean(new CXFDemoImpl()); factory.getInInterceptors().add(new MessageInterceptor(Phase.RECEIVE)); factory.getOutInterceptors().add(new MessageInterceptor(Phase.SEND)); Server server = factory.create(); server.start(); System.out.println("CXF发布成功 , address : " + address); } }
客户端
cxf自动生成客户端代码就不说了..之前的文章中都详细介绍过...
Client代码
package com.cxf.client; import java.util.Arrays; import org.apache.cxf.endpoint.Client; import org.apache.cxf.interceptor.LoggingInInterceptor; import org.apache.cxf.interceptor.LoggingOutInterceptor; import org.apache.cxf.jaxws.endpoint.dynamic.JaxWsDynamicClientFactory; public class CXFClient { public static void main(String[] args) throws Exception { JaxWsDynamicClientFactory factory = JaxWsDynamicClientFactory.newInstance(); Client client = factory.createClient("http://localhost:8088/CXFDemo/sayHello?wsdl"); client.getInInterceptors().add(new LoggingInInterceptor()); client.getOutInterceptors().add(new LoggingOutInterceptor()); Object[] objArr = client.invoke("sayHello", "Java"); System.out.println(Arrays.toString(objArr)); System.out.println(objArr[0]); } }
启动服务端 , 接着启动客户端.. 运行...
服务端控制台打印信息
客户端控制台打印信息
这里有必要说下 客户端打印的信息 , 很有意思,通过打印信息 , 可以通过HttpPost 向客户端推送数据
二月 21, 2017 11:54:06 下午 org.apache.cxf.jaxb.JAXBUtils logGeneratedClassNames 信息: Created classes: com.cxf.interceptor.server.inter.ObjectFactory, com.cxf.interceptor.server.inter.SayHello, com.cxf.interceptor.server.inter.SayHelloResponse 警告: [options] 未与 -source 1.5 一起设置引导类路径 1 个警告 二月 21, 2017 11:54:07 下午 org.apache.cxf.services.CXFDemoImplService.CXFDemoImplPort.CXFDemoInterface 信息: Outbound Message --------------------------- ID: 1 Address: http://localhost:8088/CXFDemo/sayHello Encoding: UTF-8 Content-Type: text/xml Headers: {Accept=[*/*], SOAPAction=[""]} Payload: <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><ns2:sayHello xmlns:ns2="http://inter.server.interceptor.cxf.com/"><arg0>Java</arg0></ns2:sayHello></soap:Body></soap:Envelope> -------------------------------------- 二月 21, 2017 11:54:07 下午 org.apache.cxf.services.CXFDemoImplService.CXFDemoImplPort.CXFDemoInterface 信息: Inbound Message ---------------------------- ID: 1 Response-Code: 200 Encoding: UTF-8 Content-Type: text/xml;charset=UTF-8 Headers: {Content-Length=[236], content-type=[text/xml;charset=UTF-8], Server=[Jetty(7.5.4.v20111024)]} Payload: <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><ns2:sayHelloResponse xmlns:ns2="http://inter.server.interceptor.cxf.com/"><return>hello : Java</return></ns2:sayHelloResponse></soap:Body></soap:Envelope> -------------------------------------- [hello : Java] hello : Java
Payload: <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><ns2:sayHello xmlns:ns2="http://inter.server.interceptor.cxf.com/"><arg0>Java</arg0></ns2:sayHello></soap:Body></soap:Envelope>这个<soap>标签中的内容
就是客户端向服务端发送信息时候的消息头.. 因为WebService就是基于HTTP的...
所以想通过HttpPost调用WebService的时候 , 可以通过这个...
不过注意 , 这个消息头 不是通用的..
第二种 , 就直接看代码吧.. 只是发布的方式不同而已 , 其他的都是一样的...