当注释有参数CDI拦截器不工作 [英] CDI interceptor does not work when annotation has parameter

查看:147
本文介绍了当注释有参数CDI拦截器不工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想实现一个 @Restricted 标注,以确保的方式,用户只能访问他们,当他们被记录,并有一定的控制器方法角色。我在Tomcat 7的使用JSF和CDI,所以没有EJB。拦截器会被调用,只要注释界面不指定任何参数。只要我添加了一个 @Nonbinding角色值()默认Role.ADMIN; 参数,无论是拦截还是控制器方法执行。没有错误或异常无论是。这里是我的code,我真的不知道什么是错的:

注释:

@InterceptorBinding
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE,ElementType.METHOD})
公共@interface限制{
    @Nonbinding角色值()默认Role.ADMIN; // ###
}

拦截器:

@Interceptor
@Restricted
公共类RoleBasedRestrictingInterceptor实现Serializable {
    @注入
    ISecurityManager安全;    @AroundInvoke
    公共对象拦截(最终InvocationContext CTX)抛出异常{
        最终限制注释= ctx.getClass()getAnnotation(Restricted.class)。
        log.info(截获,所需作用是:{},annotation.value()); // ###
        log.info(用户已经登录:{},security.isLoggedIn());
        返回ctx.proceed();
    }
}

控制器:

@Named(manageUsers)
@SessionScoped
公共类ManageUsersBacking扩展实现Serializable {
    @Restricted(Role.ADMIN)// ###
    公共无效testRestricted(){
        log.info(testRestricted());
    }
}

### 标记出现什么已被更改或删除,使其重新工作。该拦截器在正确定义WEB-INF / beans.xml文件,因为它没有工作在我标注的作用参数。

  16:04:33.772 [HTTP-APR-8080-EXEC-11] INFO c.m.s.RoleBasedRestrictingInterceptor  - 用户已经登录:真
16:04:33.772 [HTTP-APR-8080-EXEC-11] INFO c.m.c.admin.ManageUsersBacking - testRestricted()


解决方案

一个漫长的故事后,[1] ...今天,我重新审视这个特殊的问题,并发现它没有任何关系与CDI:

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

显然,在我的例子中,没有一流水平的注解。所以getAnnotation()返回。相反,我应该用以下内容:

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

虽然我不知道为什么在没有任何例外。也许一些其他的事情怎么回事,我无法再重现,因为...

[1] ...我迁移我的应用程序TomEE,这是一个痛苦的屁股,把我一个多星期。而且我还需要在生产中部署TomEE,背后的一个Apache代理,所以有些配置仍然要做。如果最后的作品了,它的可能的已经值得的,因为我也有一些其他的CDI问题(如注射CDI豆成JAX-RS服务使用焊接+ RestEasy的+ Tomcat的没有工作)的现在都没有了。我也很喜欢EJB和容器管理的事务的东西。但我不认为这是一个好主意,赞美TomEE每当有人试图用小零件或Java EE的使用Tomcat一起连一个子集。它的许多API实现都的意味着的在不同环境中(即使是Java SE的)工作,这是一个很好的事情。所以,如果你不需要为TomEE一些高级的Java EE的功能,我不建议这招。有些问题会消失,但别人会出现。你不能再不同的API实现之间自由选择。然而,这不是针对TomEE的声明。被用来到Tomcat我真的很喜欢TomEE的想法。

I'm trying to implement a @Restricted annotation, to secure controller methods in a way that users can only access them, when they are logged in and have a certain role. I'm on Tomcat 7 using JSF and CDI, so no EJB. The interceptor gets called as long as the annotation interface does not specify any parameters. As soon as I add a @Nonbinding Role value() default Role.ADMIN; parameter, neither the interceptor nor the controller method execute. No errors or exceptions either. Here is my code, I really don't know what's wrong with it:

Annotation:

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

Interceptor:

@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();
    }
}

Controller:

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

The ### occurrences mark what has to be changed or removed to make it work again. The interceptor is properly defined in WEB-INF/beans.xml, since it works without the role parameter in my annotation.

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()

解决方案

After a long story [1] ... Today I revisited this particular problem and noticed it had nothing to do with CDI:

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

Obviously, there is no class level annotation in my example. So getAnnotation() returns null. Instead I should have used the following:

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

Though I don't know why there where no exceptions whatsoever. Maybe some other things were going on, that I can no longer reproduce because ...

[1] ... I migrated my application to TomEE, which was a pain in the ass and took me more than a week. And I still need to deploy TomEE in production, behind an Apache proxy, so some configuration has still to be done. If it finally works out, it might have been worth the effort, for I also had some other CDI issues (e.g. injecting CDI beans into JAX-RS services did not work using Weld + Resteasy + Tomcat) that are now gone. I also like the EJB and container managed transaction stuff. But I don't think it's a good idea to praise TomEE whenever someone tries to use small parts or even a subset of Java EE together with Tomcat. Many of its API implementations are meant to work in various environments (even Java SE) and that is a good thing. So if you don't need TomEE for some of its advanced Java EE features, I can not recommend this move. Some problems will be gone, but others will emerge. And you can no longer choose freely among different API implementations. However, this is not a statement against TomEE. Being used to Tomcat I really love the idea of TomEE.

这篇关于当注释有参数CDI拦截器不工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆