当注释具有参数时,CDI拦截器不起作用

时间:2013-03-29 18:27:21

标签: java tomcat annotations cdi interceptor

我正在尝试实现@Restricted注释,以便用户只能在登录并具有特定角色时才能访问控制器方法。我在使用JSF和CDI的Tomcat 7上,所以没有EJB。只要注释接口未指定任何参数,就会调用拦截器。只要我添加@Nonbinding Role value() default Role.ADMIN;参数,拦截器和控制器方法都不会执行。也没有错误或例外。这是我的代码,我真的不知道它有什么问题:

注释:

@InterceptorBinding
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.TYPE, ElementType.METHOD })
public @interface Restricted {
    @Nonbinding Role value() default Role.ADMIN; // ###
}

拦截器:

@Interceptor
@Restricted
public class RoleBasedRestrictingInterceptor implements Serializable {
    @Inject
    ISecurityManager security;

    @AroundInvoke
    public Object intercept(final InvocationContext ctx) throws Exception {
        final Restricted annotation = ctx.getClass().getAnnotation(Restricted.class);
        log.info("Intercepted, required role is: {}", annotation.value()); // ###
        log.info("User is logged in: {}", security.isLoggedIn());
        return ctx.proceed();
    }
}

控制器:

@Named("manageUsers")
@SessionScoped
public class ManageUsersBacking extends implements Serializable {   
    @Restricted(Role.ADMIN) // ###
    public void testRestricted() {
        log.info("testRestricted()");
    }
}

###次出现标记必须更改或删除的内容,以使其再次起作用。拦截器在WEB-INF/beans.xml中正确定义,因为它在我的注释中没有角色参数。

16:04:33.772 [http-apr-8080-exec-11] INFO  c.m.s.RoleBasedRestrictingInterceptor - User is logged in: true
16:04:33.772 [http-apr-8080-exec-11] INFO  c.m.c.admin.ManageUsersBacking - testRestricted()

3 个答案:

答案 0 :(得分:4)

经历了漫长的故事[1] ...今天我重新审视了这个特殊问题并注意到它与CDI无关:

ctx.getClass().getAnnotation(Restricted.class)

显然,我的例子中没有类级注释。所以getAnnotation()返回null。相反,我应该使用以下内容:

ctx.getMethod().getAnnotation(Restricted.class)

虽然我不知道为什么没有例外。也许其他一些事情正在发生,我再也无法重现了......

[1] ...我将我的申请迁移到了TomEE,这是一个痛苦的屁股,并花了我一个多星期。我仍然需要在生产中部署TomEE,在Apache代理后面,所以仍有一些配置需要完成。如果它最终成功,它可能值得付出努力,因为我还有一些其他的CDI问题(例如,使用Weld + Resteasy + Tomcat将CDI bean注入JAX-RS服务不起作用)现在不见了我也喜欢EJB和容器管理的事务。但是,当有人试图将小部件甚至Java EE的一部分与Tomcat一起使用时,我不认为赞美TomEE是个好主意。它的许多API实现意味着在各种环境(甚至Java SE)中工作,这是一件好事。因此,如果您不需要TomEE的某些高级Java EE功能,我不建议这样做。一些问题将会消失,但其他问题将会出现。而且您不能再在不同的API实现中自由选择。但是,这不是针对TomEE的声明。习惯Tomcat我真的很喜欢TomEE的想法。

答案 1 :(得分:1)

如果你切换到TomEE,你不需要依赖(maven)实现,只需api(使用org.apache.openejb:javaee-api:6.0-4,提供范围

答案 2 :(得分:0)

听起来你的设置正确(beans.xml和拦截器)。你使用哪种CDI实现?如果您正在使用Tomcat,您是否考虑过使用TomEE?