【问题标题】:jax-rs method parameters as CDI beansjax-rs 方法参数作为 CDI bean
【发布时间】:2012-12-29 09:33:57
【问题描述】:

我有如下简单的 JAX-RS bean:

@Path('/client')
class ClientResource {

    @POST
    public Response post(Client client) {
        ...
    }

}

Client 正在从 json 响应正文创建。 是否可以让Client 类成为 CDI 感知 bean?我希望能够做这样的事情:

class Client {

    @Inject
    private Validator validator;

    public String clientName;    

    public validate() {
       // use validator here
    }
}

默认情况下我得到validator null,所以客户端似乎没有被管理。

我正在使用带有 RESTEasy 的 JBoss 作为 Jax-RS 实现。

编辑

我想我可以提供来自 JSON 的自定义映射器,但它似乎有很多样板代码。

【问题讨论】:

    标签: json jax-rs java-ee-6 cdi bean-validation


    【解决方案1】:

    这应该可以正常工作。 bean val 可能不可用。尝试创建生产者或注入其他东西。

    【讨论】:

    • 不幸的是,无论我注入什么,评估为null。我怀疑这个 Client 实例是由新的绕过 CDI 生命周期创建的,我不知道如何避免这种情况。
    • 是的,你可能是对的。这可能在 Java EE 7 中得到修复,但我不确定。当然,现在这对你没有帮助。
    【解决方案2】:

    您是否使用 JAXB 进行解组?我不熟悉 RESTEasy,虽然我看到它可以使用 JAXB,但我不知道这是否是唯一的选择。

    如果您使用的是 JAXB,那么它的 Unmarshaller 支持 Unmarshal Event Callbacks。它可以调用正在解组的对象上的方法,或者更好的是,调用单独的event listener。您可以注册一个引用 CDI BeanManager(通过简单的 @Inject 或通过 JNDI java:comp/BeanManager 获得)的侦听器,并使用它来注入新解组的对象。

    我绝不是 CDI 专家,但实验表明这似乎注入了一个已经创建的对象:

    public class Injector<T> {
    
        private final BeanManager beanManager;
        private final InjectionTarget<T> injectionTarget;
        private final Bean<T> bean;
    
        public Injector(BeanManager beanManager, Class<T> cl) {
            this.beanManager = beanManager;
            injectionTarget = beanManager.createInjectionTarget(beanManager.createAnnotatedType(cl));
            bean = resolve(beanManager.getBeans(cl));
        }
    
        private Bean<T> resolve(Set<Bean<?>> beans) {
            @SuppressWarnings("unchecked")
            Bean<T> bean = (Bean<T>) beanManager.resolve(beans);
            return bean;
        }
    
        public CreationalContext<T> inject(T obj) {
            CreationalContext<T> creationalContext = beanManager.createCreationalContext(bean);
            injectionTarget.inject(obj, creationalContext);
            return creationalContext;
        }
    
    }
    

    该代码采用某个类的现有实例并将依赖项注入其中。这是对 CDI 的一种不规范的使用,但它似乎可以工作(此外,我相信它是完全有效且受支持的)。

    注意,调用代码需要保留返回的CreationalContext,并在对象完成后调用其release方法。

    【讨论】:

      猜你喜欢
      • 2018-12-11
      • 2015-05-05
      • 1970-01-01
      • 2013-12-07
      • 2019-03-01
      • 1970-01-01
      • 2013-03-31
      • 1970-01-01
      • 2019-06-01
      相关资源
      最近更新 更多