【发布时间】:2016-04-26 08:41:30
【问题描述】:
我目前正在重构一个 Jersey Web App,并希望将一些横切关注点捆绑在他们自己的类中,并使用注释来拦截方法。例如,有很多方法我需要检查用户是否是他想要更改的实体的所有者(在我的情况下这是一个项目)。因此,在拦截器中,我需要进行数据库调用,尽管注入适当的 DAO 将是最好的方法。
目前我的拦截器是这样的:
public class ProjectOwnerCheckInterceptor implements MethodInterceptor {
@Inject
private EntityManager em;
@Inject
private UserProvider userProvider;
@Inject
private RMUserDAO rmUserDAO;
@Inject
private ProjectDAO projectDAO;
public ProjectOwnerCheckInterceptor() {
// TODO Auto-generated constructor stub
}
@Override
public Object invoke(MethodInvocation arg0) throws Throwable {
// First of all let's get the annotation
ProjectOwnerCheck check = arg0.getMethod().getAnnotation(ProjectOwnerCheck.class);
// if there is no check, then just proceed!
if (check == null)
arg0.proceed();
long projectId = (long) arg0.getArguments() [check.projectIdIndex()];
// Handling ownership!!
Project project = getProjectOrThrow(projectId);
return arg0.proceed();
}
}
自定义注释很简单。我需要添加一些小信息,方法中的 entityId 必须检查哪个参数位置,因为参数和类型的数量会有所不同:
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.METHOD })
public @interface ProjectOwnerCheck {
int projectIdIndex() default -1;
}
为了让 Jersey/HK2 知道如何处理拦截器,我创建了一个实现 InterceptionService 的过滤器:
public class HK2InterceptorFilter implements InterceptionService {
private final static MethodInterceptor PROJECT_CHECK_METHOD_INTERCEPTOR = new ProjectOwnerCheckInterceptor();
private final static List<MethodInterceptor> PROJECT_CHECK_METHOD_LIST = Collections
.singletonList(PROJECT_CHECK_METHOD_INTERCEPTOR);
public HK2InterceptorFilter() {
// TODO Auto-generated constructor stub
}
@Override
public Filter getDescriptorFilter() {
return BuilderHelper.allFilter();
}
@Override
public List<MethodInterceptor> getMethodInterceptors(Method method) {
if (method.isAnnotationPresent(ProjectOwnerCheck.class))
return PROJECT_CHECK_METHOD_LIST;
return null;
}
@Override
public List<ConstructorInterceptor> getConstructorInterceptors(Constructor<?> constructor) {
// TODO Auto-generated method stub
return null;
}
}
我在我的 JerseyApplication 类中绑定了那个过滤器:
register(new AbstractBinder() {
@Override
protected void configure() {
try {
bind(HK2InterceptorFilter.class).to(InterceptionService.class).in(Singleton.class);
bind(getPasswordStorage()).to(PasswordStorage.class);
bind(getDocumentService()).to(DocumentService.class);
bind(UserManagementAccessor.getUserProvider()).to(UserProvider.class);
} catch (Exception e) {
throw new InternalServerErrorException(e);
}
}
});
在我的拦截器中设置断点时,我可以看到它已正确实例化并且方法被调用。但是我完全想念的是我需要检查的所有@Inject 字段。我是否遗漏了什么,或者这在 HK2 中是不可能的。我曾经和 Guice 一起工作,它正在工作(我 - 由于应用程序的代码库非常大,但时间有限 - 绑定到 HK2:))。
提前感谢您的所有帮助!
PS:
我使用的是 Jersey 2.17
【问题讨论】:
标签: java jersey jersey-2.0 interceptor hk2