Jersey 过滤器

Jersey的过滤器分为:

ContainerRequestFilter: 请求阶段的过滤

ContainerResponseFilter: 响应阶段的过滤

一、使用注解名称绑定

1.1 创建绑定的注解

使用@NameBinding注解,可以定义一个运行时的自定义注解,该注解可以用于定义类级别名称和泪的方法。例如,我们定义一个用户访问的注解。

@NameBinding            //标识名称绑定的注解
@Target({ElementType.TYPE, ElementType.METHOD}) //表示该注解可以使用在类和方法上。
@Retention(value = RetentionPolicy.RUNTIME)
public @interface UserLogger {
}

上面代码我们定义了一个名称绑定注解UserLogger。

1.2 注解绑定过滤器

创建了注解之后,我们需要将注解和Jersey中的Provider 组件绑定,示例中我们使用的是过滤器。

@Provider
@UserLogger
@Priority(Priorities.USER)
public class LoggerFilter implements ContainerRequestFilter ,ContainerResponseFilter{
@Override
public void filter(ContainerRequestContext requestContext) throws IOException {
System.out.println("访问请求日志过滤器执行了>>>>>>>>>>>>");
}
@Override
public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext) throws IOException {
System.out.println("访问响应日志过滤器执行了>>>>>>>>>>>");
}
}

@Provider 注解Jersey注解,Jersey扫描到该注解,就会创建对应的组件对象。 @UserLogger 就是我们自定义的名称绑定注解 @Priority 是用于表示该过滤器的执行顺序,其中参数为long类型,对于请求过滤器,该数值越小越先执行,响应过滤器则相反。 ContainerRequestFilter 为请求过滤器 ContainerResponseFilter 为响应过滤器 在请求和响应的过滤方法中,我们简单的打印输出。 需要注意的是,我们创建了过滤器之后需要在Jersey中进行声明,我们在Jerysey的ResourceConfig 子类中,注册该过滤器,注册有两种方式,一种是扫描包的形式,这时需要在过滤器上加上@Provider注解,另一种是直接注册该过滤器。

packages("com.xxxx.xxxx.xxxx.filter"); //扫描包的形式 过滤器所在的包

register(LoggerFilter.class); //直接注册过滤器

1.3 注解绑定接口

上面我们创建好注解和过滤器之后,需要将在我们需要使用过滤器的接口方法上使用注解。

@Path("/test")
public class TestResource {
@GET
@Path("/1")
public String test1(){
return "不带过滤器";
}
@GET
@Path("/2")
@UserLogger
public String test2(){
return "带过滤器";
}
}

我们创建了两个接口,一个路径是/test/1 没有使用过滤器,一个路径是/test/2使用注解,按照我们的设计,当访问./test/1时,日志过滤器不起作用,访问/test/2时日志过滤器起作用。

二、动态绑定

上面介绍的名称保定的形式需要通过自定义注解的形式来实现过滤器绑定,而动态绑定则不需要新增注解,而是需要编码的形式,实现动态绑定。动态绑定需要实现动态特征接口javax.ws.rs.container,DynamiFeature,定义扩展点方法,请求方法类型等匹配信息,在运行期,一旦Provider匹配到当前处理类或方法,面向切面的Provider方法就是触发。

2.1 实现动态绑定特征

public class LoggerDynaimcFeature implements DynamicFeature {
@Override
public void configure(ResourceInfo resourceInfo, FeatureContext context) {
String name = resourceInfo.getResourceMethod().getName();
if("test2".equals(name)){
context.register(LoggerFilter.class);
}
}
}

上面的代码实现的是当我们访问的是test2方法时,就会注册LoggerFilter,实现该过滤器的方法。    我们需要在同样我们需要注册该动态特征来    

  1. register(LoggerDynaimcFeature .class);

   这时我们重新启动项目时,分别访问test/1和test/2,就会看到只有test2时,日志过滤器才会起作用。    三. 名称绑定和动态绑定对比    动态绑定相比于名称绑定,不需要自定义注解,使用纯编码的形式实现。    名称绑定相比于动态绑定使用范围更广,因为我们使用注解的方式,可以对任意资源,任意方法进行控制。而使用动态绑定的形式,我们需要在动态特征类进行对应的匹配,适用范围较窄。

发表评论

电子邮件地址不会被公开。 必填项已用*标注