Jersey 方法拦截器
如果我们需要控制用户对接口的访问,例如登陆控制,权限控制等,就需要使用方法拦截器。
由于Jersey中的AOP是基于HK2框架实现的,所以对应的拦截器的功能也是由HK2框架实现。
现在我们模拟实现一个登陆拦截器的功能。
3.1 创建自定义注解
@Documented
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface LoginTest {
}
3.2 方法拦截器
@LoginTest
public class LoginTestMethodInterceptor implements MethodInterceptor {
@Override
public Object invoke(MethodInvocation methodInvocation) throws Throwable {
return "没有权限访问";
}
}
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);
}
}
为了使绑定生效,我们需要定义特征类,用于注册该绑定
public class JerseyFeature implements Feature {
@Override
public boolean configure(FeatureContext context) {
context.register(new JerseyBinding());
return true;
}
}
同样我们需要在ResourceConfig中注册该特征类
register(JerseyFeature.class);
3,4 测试
测试接口如下
@Path("/test")
public class TestResource {
@Path("/1")
@GET
public String test1(){
return "不带拦截器";
}
@Path("/2")
@GET
@LoginTest
public String test2(){
return "不带拦截器";
}
}
我们访问test/1的时候可以看到不带拦截器,访问test/2的时候可以看到没有访问权限