Cxf拦截器
目录
拦截器是Cxf的基础,Cxf中很多的功能都是由内置的拦截器来实现的,拦截器在Cxf中由Interceptor表示。Cxf的拦截器包括入拦截器和出拦截器,所有的入拦截器或出拦截器构成了一个拦截器链,它们可以作用在Server端也可以作用在Client端。当需要使用拦截器链处理消息的时候,Cxf会确保对应的消息被拦截器链里面的每一个拦截器都执行一遍。拦截器链在Cxf中由InterceptorChain接口表示,有兴趣的朋友可以看一下org.apache.cxf.phase.PhaseInterceptorChain类的public synchronized boolean doIntercept(Message message)方法,它是拦截器链拦截Message的实现。当客户端发送一个请求到服务端时会经过客户端的出拦截器和服务端的入拦截器;当服务端对客户端的请求进行响应时对应的响应消息会经过服务端的出拦截器和客户端的入拦截器。
1.1 自定义拦截器
Cxf的拦截器是通过org.apache.cxf.interceptor.Interceptor<T extends Message>接口表示的,其中共定义了两个方法,具体如下。
public interface Interceptor<T extends Message> {
void handleMessage(T message) throws Fault;
void handleFault(T message);
}
Cxf在正常调用InterceptorChain的时候会依次调用其中包含的Interceptor的handleMessage方法,当调用某一个Interceptor出错时,将依次回调已经回调过的Interceptor的handleFault方法,而且它们的调用顺序与调用handleMessage的顺序是反的。
通常我们在实现自定义Interceptor的时候不会直接实现Interceptor接口,而且Cxf也不允许我们直接实现Interceptor接口,暂时对它没有支持。Interceptor有一个子接口PhaseInterceptor,顾名思义就是分阶段的拦截器。Cxf将消息的发送、接收的过程分为很多个阶段,如send、receive、read、write等,具体可以参考类org.apache.cxf.phase.Phase,其中定义了Cxf支持的所有拦截阶段的常量。Cxf要求我们在定义一个拦截器的时候必须指定当前拦截器需要作用的阶段。Cxf已经为我们提供了一个实现了PhaseInterceptor接口的抽象实现类org.apache.cxf.phase.AbstractPhaseInterceptor<T extends Message>,而且建议我们通过继承AbstractPhaseInterceptor来实现自定义拦截器。AbstractPhaseInterceptor中没有定义默认的空构造方法,所以子类在实现的时候必须在构造方法中调用父类的某一个构造方法。以下是一个非常简单的继承自AbstractPhaseInterceptor的自定义拦截器的实现。
public class LogInterceptor extends AbstractPhaseInterceptor<Message> {
private static final Logger logger = Logger.getLogger(LogInterceptor.class);
public LogInterceptor() {
super(Phase.RECEIVE);//针对Receive这个阶段进行拦截
}
@Override
public void handleMessage(Message message) throws Fault {
logger.info(message.toString());
}
}
1.2 配置拦截器
自定义的拦截器配置好后我们需要进行相应的配置,好让Cxf知道我们需要在什么地方使用我们的自定义拦截器。拦截器的配置可以通过代码进行程序化的配置,也可以通过注解进行配置,还可以通过Cxf的配置文件进行配置。拦截器链InterceptorChain由许多Interceptor组成,Cxf中定义了一个接口InterceptorProvider,通过该接口可以获取到与当前对象绑定的拦截器链里面的所有拦截器,当我们需要往某对象现有的拦截器链里面添加拦截器的时候我们就可以往通过InterceptorProvider获取到的对应拦截器列表中添加相应的拦截器来实现。InterceptorProvider的定义如下。
public interface InterceptorProvider {
List<Interceptor<?extends Message>>getInInterceptors();
List<Interceptor<?extends Message>>getOutInterceptors();
List<Interceptor<?extends Message>>getInFaultInterceptors();
List<Interceptor<?extends Message>>getOutFaultInterceptors();
}
1.2.1程序化配置
程序化配置就是直接通过实现了InterceptorProvider接口的对象获取到对应的拦截器列表,然后往其中添加Interceptor即可。实现了InterceptorProvider接口的类很多,包括EndpointImpl、CxfBusImpl、ServiceImpl、ClientImpl等,想了解更多实现了InterceptorProvider接口的类可以查看Cxf的API文档(http://cxf.apache.org/javadoc/latest-2.7.x/org/apache/cxf/interceptor/InterceptorProvider.html)。以下是一段将我们自定义的LogInterceptor添加到服务端所发布的服务的拦截器链中的示例代码。
public class Server {
private final static String ADDRESS = "http://localhost:8080/test/jaxws/services/HelloWorld";
public static void main(String args[]) {
HelloWorldImplhw = new HelloWorldImpl();
Interceptor<Message>logInterceptor = new LogInterceptor();
JaxWsServerFactoryBean jwsFactory = new JaxWsServerFactoryBean();
jwsFactory.setAddress(ADDRESS); //指定WebService的发布地址
jwsFactory.setServiceClass(HelloWorld.class);//WebService对应的类型
jwsFactory.setServiceBean(hw);//WebService对应的实现对象
jwsFactory.getInInterceptors().add(logInterceptor);//往入拦截器链里面添加拦截器
//往出拦截器链里面添加拦截器
jwsFactory.getOutInterceptors().add(logInterceptor);
//往错误处理的入拦截器链中添加拦截器
jwsFactory.getInFaultInterceptors().add(logInterceptor);
//往错误处理的出拦截器链中添加拦截器
jwsFactory.getOutFaultInterceptors().add(logInterceptor);
jwsFactory.create();
}
}
使用其它方式在服务端发布Service或者在Client端需要往某个对象的拦截器链中添加拦截器的用法和上述示例中的类似。有一点需要注意的是,我们实现的PhaseInterceptor是必须指定要拦截的阶段的,我们如果往一个拦截器链里面添加一个根本不会发生的阶段,那么对应的拦截器是不会被执行的,如往出拦截器链里面添加一个Receive阶段的拦截器。如果希望添加我们的拦截器到所有的服务端服务或客户端,那么我们就可以创建一个Bus对象,然后往Bus对象的对应拦截器链中添加对应的拦截器,再在创建服务端和客户端时指定使用的Bus为我们自己创建的那个。示例代码如下。
public class Client {
private final static String ADDRESS = "http://localhost:8080/test/jaxws/services/HelloWorld";
public static void main(String args[]) throwsHelloWorldException {
//获取默认的bus
Bus bus = BusFactory.getDefaultBus();
//往bus的入拦截器链中添加拦截器
bus.getInInterceptors().add(new LogInterceptor());
JaxWsProxyFactoryBean jwpFactory = new JaxWsProxyFactoryBean();
jwpFactory.setBus(bus);//指定bus
jwpFactory.setAddress(ADDRESS);
jwpFactory.setServiceClass(HelloWorld.class);
HelloWorldhw = (HelloWorld)jwpFactory.create();
String response = hw.sayHi("world");
System.out.println(response);
}
}
在上述代码中我们通过BusFactory.getDefaultBus()方法获取了一个默认的Bus对象,实际上在Cxf的很多类的内部构造中需要获取Bus的时候,如果没有指定Bus对象,都会通过BusFactory的getDefaultBus()方法获取,所以如果是在一个Service发布的代码中通过上述方式获取到一个默认的Bus对象,然后往其中加入对应的拦截器的话,那很可能会给其它Service也加上;如果每一个Service的发布都是同样的逻辑的话,那对应的Bus上的拦截器就会同时有多个对象存在。
1.2.2注解配置
Cxf为四种类型的拦截器都提供了对应的注解,以方便用户直接在SEI上进行配置,对应的注解如下。
Ø org.apache.cxf.interceptor.InInterceptors
Ø org.apache.cxf.interceptor.InFaultInterceptors
Ø org.apache.cxf.interceptor.OutInterceptors
Ø org.apache.cxf.interceptor.OutFaultInterceptors
每个注解都对应有两个属性,String[]类型的interceptors和Class<? extends Interceptor<? extends Message>>[]类型的classes,其中interceptors用来指定需要配置的拦截器的全名称,而classes则用来指定需要配置的拦截器的类。以下是一个在SEI上通过@InInterceptor配置了入拦截器LogInterceptor的示例。
@InInterceptors(classes={LogInterceptor.class})
@WebService
public interface HelloWorld {
public String sayHi(String who);
}
如果在配置的时候既使用了classes属性配置,又使用了interceptors属性配置,那么两个配置都会生效。如下代码就相当于我们配置了两个自定义的拦截器LogInterceptor到HelloWorld服务的入拦截器链中。
@InInterceptors(classes={LogInterceptor.class}, interceptors={"com.tiantian.cxftest.interceptor.LogInterceptor"})
@WebService
public interface HelloWorld {
public String sayHi(String who);
}
使用注解的方式配置其它拦截器的方式是类似的。使用注解在服务端的SEI上配置的拦截器会作用在服务端,如果客户端与服务端不在一起,需要单独在客户端上配置拦截器,也可以直接在客户端对应的SEI上通过上述四个注解进行配置,方法是一样的。
1.2.3Cxf配置文件配置
Cxf配置文件是Cxf与Spring进行整合时使用的,不管是使用simple约束还是jaxws约束,它们都为四种类型的拦截器配置定义对应的元素配置,具体如下。
Ø inInterceptors
Ø inFaultInterceptors
Ø outInterceptors
Ø outFaultInterceptors
使用的时候如果是在服务端进行配置,则只需要配置在server标签下即可,如果是在客户端进行配置,则只需要在client标签下配置即可,用法是一样的。下面是在服务端配置拦截器的示例。
<beansxmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:jaxws="http://cxf.apache.org/jaxws"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd">
<bean id="logInterceptor" class="com.tiantian.cxftest.interceptor.LogInterceptor"/>
<jaxws:server address="/HelloWorld">
<jaxws:serviceBean>
<bean class="com.tiantian.cxftest.sample.jaxws.HelloWorldImpl"/>
</jaxws:serviceBean>
<!--入拦截器 -->
<jaxws:inInterceptors>
<ref bean="logInterceptor"/>
</jaxws:inInterceptors>
<!--入出错拦截器 -->
<jaxws:inFaultInterceptors>
<ref bean="logInterceptor"/>
</jaxws:inFaultInterceptors>
<!--出拦截器 -->
<jaxws:outInterceptors>
<ref bean="logInterceptor"/>
</jaxws:outInterceptors>
<!--出出错拦截器 -->
<jaxws:outFaultInterceptors>
<ref bean="logInterceptor"/>
</jaxws:outFaultInterceptors>
</jaxws:server>
</beans>
如果我们需要通过配置文件的方式给所有的服务端或客户端都加上相同的拦截器,那么我们就可以在对应的Bus上配置对应的拦截器。如果需要在Bus上配置拦截器,我们首先得引入Cxf的core Schema,之后我们就可以通过core Schema中的定义的bus标签来配置一个Bus对象及其对应的拦截器了。示例如下。
<beansxmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:jaxws="http://cxf.apache.org/jaxws"
xmlns:cxf="http://cxf.apache.org/core"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd
http://cxf.apache.org/core http://cxf.apache.org/schemas/core.xsd">
<bean id="logInterceptor" class="com.tiantian.cxftest.interceptor.LogInterceptor"/>
<!--可以通过其bus属性指定需要使用的Bus,不指定则使用默认的 -->
<jaxws:server address="/HelloWorld">
<jaxws:serviceBean>
<bean class="com.tiantian.cxftest.sample.jaxws.HelloWorldImpl"/>
</jaxws:serviceBean>
</jaxws:server>
<!--默认Bus对象 -->
<cxf:bus id="bus">
<!--入拦截器 -->
<cxf:inInterceptors>
<ref bean="logInterceptor"/>
</cxf:inInterceptors>
<!--入出错拦截器 -->
<cxf:inFaultInterceptors>
<ref bean="logInterceptor"/>
</cxf:inFaultInterceptors>
<!--出拦截器 -->
<cxf:outInterceptors>
<ref bean="logInterceptor"/>
</cxf:outInterceptors>
<!--出出错拦截器 -->
<cxf:outFaultInterceptors>
<ref bean="logInterceptor"/>
</cxf:outFaultInterceptors>
</cxf:bus>
</beans>
如果一个Server或Client没有指定使用的Bus,则将使用默认的那一个。如果需要指定则可以通过它们的bus属性进行指定。
1.3 日志拦截器
在前文我们自己定义了一个日志拦截器LogInterceptor,其实一般我们大可不必定义自己的日志拦截器。因为Cxf已经为我们提供了两个日志拦截器。一个是针对入拦截器链的LoggingInInterceptor,一个是针对出拦截器链的LoggingOutInterceptor,分别对应于Receive和Send阶段,它们输出来的日志信息也是比较详细的,对开发工作比较有帮助。有兴趣的朋友可以去查看一下它们的源码。
除了日志拦截器以外,Cxf还内置了很多的Interceptor实现,有兴趣的朋友可以去查看一下Cxf的API文档http://cxf.apache.org/javadoc/latest-2.7.x/org/apache/cxf/interceptor/Interceptor.html。
1.4 参考文档
Ø http://cxf.apache.org/docs/interceptors.html
Ø http://cxf.apache.org/javadoc/latest-2.7.x/
(注:本文是基于Cxf2.7.6版本所写)
(注:原创文章,转载请注明出处。原文地址:http://elim.iteye.com/blog/2248620)
相关推荐
标题:“CXF拦截器(Interceptor)的使用” 描述:“讲解了cxf实现拦截器的原因、核心API及使用方法” 在深入探讨CXF拦截器的使用之前,我们首先需要理解其在CXF框架中的核心作用与价值。Apache CXF是一个开源框架,...
1. **CXF拦截器基础**:CXF的拦截器是基于JAX-WS规范的Handler Chain模型,分为In-bound(请求进来时触发)和Out-bound(响应出去时触发)两类。拦截器可以通过在服务配置中指定,或者通过编程方式动态添加。 2. **...
**CXF拦截器理论与应用** 在Web服务领域,Apache CXF是一个强大的开源框架,它提供了构建和消费SOAP和RESTful服务的能力。拦截器是CXF框架中的一个重要组成部分,允许开发者在服务调用的生命周期中插入自定义逻辑,...
通过学习和理解这些示例,开发者可以更好地利用CXF拦截器来扩展和定制自己的Web服务,提高应用程序的灵活性和可维护性。无论是客户端还是服务器端,拦截器都是一个强大的工具,能够帮助我们控制和优化服务通信的每个...
本篇文章将深入探讨如何使用CXF来开发具有权限控制功能的Web Service,并通过拦截器实现这一目标。 首先,我们需要理解Web Service拦截器的概念。在CXF中,拦截器是处理消息生命周期中的关键组件,它们可以在消息...
在Java世界中,Apache CXF是一个广泛使用的开源框架,它允许开发者创建和消费Web服务。在Web服务开发中,拦截器扮演着至关重要的角色,...总的来说,理解并熟练运用CXF拦截器对于任何CXF开发者来说都是一项重要的技能。
CXF拦截器是一种AOP(面向切面编程)的概念,它们是执行特定任务的独立单元,可以在消息传递的生命周期中不同阶段被调用。拦截器可以用来处理如认证、授权、日志记录、性能监控、数据转换等任务,增强了服务的功能和...
本篇将深入探讨CXF框架中的拦截器(Interceptor)及其在"webservice的cxf框架拦截器demo"中的应用。 拦截器在CXF中是一种强大的工具,它允许开发者在消息发送或接收的过程中插入自定义的行为。这在处理认证、日志...
在本项目中,"spring集成cxf客户端和服务器端demo(含自定义拦截器)"是一个实战案例,展示了如何在Spring框架下与Apache CXF服务进行整合,实现客户端和服务端的交互,并利用拦截器来增强功能。以下是这个项目涉及的...
在开发基于CXF的Web服务时,为了确保系统的安全性和数据的完整性,通常需要对请求进行权限检查。本文将深入探讨如何为CXF服务器...在学习和应用这些知识时,结合实际案例和实践操作将有助于更好地掌握CXF拦截器的使用。
CXF是一个流行的开源框架,它支持SOAP和RESTful两种Web Service风格,并提供了丰富的功能,包括安全、拦截器等。本节我们将深入探讨如何为CXF客户端添加自定义拦截器以实现权限控制。 首先,理解拦截器的概念是至关...
【标题】:“CXF框架在Web服务中的应用:拦截器示例” 【描述】:本压缩包“webservice的cxf框架拦截器demo.rar”提供了一个关于如何在Apache CXF框架下实现Web服务拦截器的实际操作示例。CXF是一个开源的服务框架...
首先,我们需要理解CXF拦截器的概念。拦截器是CXF提供的一种机制,它允许我们在Web服务调用的生命周期中的不同阶段插入自定义逻辑,如消息的发送和接收。这为我们提供了在服务执行前、后或过程中进行额外操作的机会...
本文将深入探讨"CXF拦截器-权限控制-登录校验"这一主题。 首先,我们需要了解什么是拦截器。在CXF框架中,拦截器是实现业务逻辑和基础架构之间解耦的一种方式。它们可以插入到服务调用的生命周期中,在消息发送前或...
在IT安全领域,IP黑白名单拦截器是一种常见的技术手段,用于增强网络安全,防止恶意或不受信任的IP地址访问系统资源。以下将详细讲解基于Java实现的IP黑白名单拦截器及其核心概念。 首先,我们来看标题提及的“ip...
"CXF3.1.16 +Spring4 +MyBatis + Maven自定义拦截器 WebService实例源码下载" 这个标题揭示了该项目的核心技术栈,包括: 1. CXF 3.1.16:这是一个开源的服务框架,用于构建和开发服务,支持SOAP和RESTful Web服务...
**标题:“CXF和Spring整合,并且添加拦截器”** 在Java世界中,Apache CXF是一个流行的开源服务框架,用于创建和消费Web服务。它支持多种Web服务规范,包括SOAP、RESTful API以及WS-*标准。另一方面,Spring框架是...
本文根据java代理实现CXF拦截器异常时只能进入fault拦截器而不能继续向下执行的问题。 利用java代理让RMI具有拦截器的功能。
【标题】"cxfSecurity.rar" 是一个与Apache CXF框架相关的压缩文件,它涉及到在Web服务(Webservice)环境中实现安全加密以及使用拦截器(Interceptors)的技术。Apache CXF是一个开源的服务框架,用于构建和开发...
CXF 自定义拦截器实现的 webservice安全机制实例工程, 带jar包 ,代码注释详细 内有说明文档, 由于资源过大 ,所以客户端jar包 删除掉了, 只需要把服务端的jar 拷贝到 客户端即可 , 小弟刚刚研究完 CXF 安全 。...