Jersey 方法拦截器

如果我们需要控制用户对接口的访问,例如登陆控制,权限控制等,就需要使用方法拦截器。
    由于Jersey中的AOP是基于HK2框架实现的,所以对应的拦截器的功能也是由HK2框架实现。
    现在我们模拟实现一个登陆拦截器的功能。
3.1 创建自定义注解
  1. @Documented
  2. @Target({ElementType.METHOD, ElementType.TYPE})
  3. @Retention(RetentionPolicy.RUNTIME)
  4. public @interface LoginTest {
  5. }
 
3.2 方法拦截器
  1. @LoginTest
  2. public class LoginTestMethodInterceptor implements MethodInterceptor {
  3. @Override
  4. public Object invoke(MethodInvocation methodInvocation) throws Throwable {
  5. return "没有权限访问";
  6. }
  7. }
    
3.3 方法拦截器的绑定
    Jersey在调用方法拦截器的时候,需要InterceptionService的实现。
   该接口中有三个方法,在执行对应的接口方法之前会调用getMethodInteceptors()方法,获取对应的拦截器,并执行拦截器。
public class JerseyInterceptor implements InterceptionService {
private static Map<Annotation, MethodInterceptor> map = new HashMap<>();
static{
Annotation[] annotations = LoginTestMethodInterceptor.class.getAnnotations();
for(Annotation annotation : annotations){
map.put(annotation, new LoginTestMethodInterceptor());
}
}
@Override
public Filter getDescriptorFilter() {
return new Filter() {
public boolean matches(Descriptor descriptor) {
return true;
}
};
}
@Override
public List<MethodInterceptor> getMethodInterceptors(Method method) {
Annotation[] annotations = method.getAnnotations();
List<MethodInterceptor> list = new ArrayList<>();
for (Annotation annotation :annotations){
if(map.get(annotation) != null){
list.add(map.get(annotation));
}
}
return list;
}
@Override
public List<ConstructorInterceptor> getConstructorInterceptors(Constructor<?> constructor) {
return null;
}
}
上面代码可以看到,我们是将注解与拦截器绑定,通过方法上的注解,获取方法对应的拦截器,并执行拦截器。 我们创建的拦截服务实现,需要与拦截服务进行绑定,这时需要AbstracctBinding对象的实现‘。
public class JerseyBinding extends AbstractBinder {
@Override
protected void configure() {
this.bind(JerseyInterceptor.class).to(InterceptionService.class).in(Singleton.class);
}
}

为了使绑定生效,我们需要定义特征类,用于注册该绑定

 
  1. public class JerseyFeature implements Feature {
  2. @Override
  3. public boolean configure(FeatureContext context) {
  4. context.register(new JerseyBinding());
  5. return true;
  6. }
  7. }
同样我们需要在ResourceConfig中注册该特征类
  1. register(JerseyFeature.class);
3,4 测试
    测试接口如下
 
  1. @Path("/test")
  2. public class TestResource {
  3. @Path("/1")
  4. @GET
  5. public String test1(){
  6. return "不带拦截器";
  7. }
  8. @Path("/2")
  9. @GET
  10. @LoginTest
  11. public String test2(){
  12. return "不带拦截器";
  13. }
  14. }
我们访问test/1的时候可以看到不带拦截器,访问test/2的时候可以看到没有访问权限

发表评论

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