【问题标题】:RESTEasy, CDI, embedded Jetty, bean validation is ignoredRESTEasy、CDI、嵌入式 Jetty、bean 验证被忽略
【发布时间】:2014-03-08 19:27:27
【问题描述】:

我有一个 Groovy 项目,我在其中使用 RESTEasy 和 Weld 并部署到嵌入式 Jetty。我似乎无法工作的是bean验证。 RESTEasy 文档说添加 resteasy-validator-provider-11 以及休眠验证器依赖项 (hibernate-validator, hibernate-validator-cdi, javax.el-api, javax.el) 就足够了。但是 RESTEasy 简单地忽略了 bean 验证。我奇怪地还在日志中收到以下消息:

plugins.validation.ValidatorContextResolver - Unable to find CDI supporting ValidatorFactory. Using default ValidatorFactory

根据 [this][1] post 上的建议,我尝试在 META-INF/validation.xml 中注册 Hibernate InjectingConstraintValidatorFactory,但这取决于注入的 BeanManager 并在运行时崩溃。

代码可以在这里找到https://github.com/abhijitsarkar/groovy/tree/master/movie-manager/movie-manager-web

日志要点在这里:https://gist.github.com/anonymous/8947319

我在阳光下尝试了一切,但没有任何成功。请帮忙。

【问题讨论】:

  • 在不了解细节的情况下很难说这里有什么问题。一般来说,我认为你最好使用像 WildFly 这样的 EE 容器,它为你集成了所有这些开箱即用的技术,所以你不必自己解决这个问题。
  • @Gunnar 我正在避免使用 EE 容器,因为我想使用嵌入式容器创建一个可执行的战争,而 Jetty 符合要求。我在我的帖子中添加了更多细节。请帮忙。我在阳光下尝试了一切,但没有成功。

标签: groovy cdi resteasy bean-validation embedded-jetty


【解决方案1】:

要在没有 EE 的情况下执行此操作,我相信您需要分叉现有的 InjectingConstraintValidatorFactory,但不要使用 bean 管理器的注入,而是使用 CDI 1.1 类 CDI 来获取对 bean 管理器的引用,例如CDI.current().getBeanManager()。 http://docs.jboss.org/cdi/api/1.1/javax/enterprise/inject/spi/CDI.html

您确实需要使用 CDI 1.1 才能执行此操作(所以 Weld 2+,我相信 2.1.1 是最新的)。这是一个示例 impl,基于:https://github.com/hibernate/hibernate-validator/blob/master/cdi/src/main/java/org/hibernate/validator/internal/cdi/InjectingConstraintValidatorFactory.java

    public class InjectingConstraintValidatorFactory implements ConstraintValidatorFactory {
        // TODO look for something with better performance (HF)
        private final Map<Object, DestructibleBeanInstance<?>> constraintValidatorMap =
                Collections.synchronizedMap( new IdentityHashMap<Object, DestructibleBeanInstance<?>>() );

        private final BeanManager beanManager;

        public InjectingConstraintValidatorFactory() {
            this.beanManager = CDI.current().getBeanManager();
            Contracts.assertNotNull( this.beanManager, "The BeanManager cannot be null" );
        }

        @Override
        public <T extends ConstraintValidator<?, ?>> T getInstance(Class<T> key) {
            DestructibleBeanInstance<T> destructibleBeanInstance = new DestructibleBeanInstance<T>( beanManager, key );
            constraintValidatorMap.put( destructibleBeanInstance.getInstance(), destructibleBeanInstance );
            return destructibleBeanInstance.getInstance();
        }

        @Override
        public void releaseInstance(ConstraintValidator<?, ?> instance) {
            DestructibleBeanInstance<?> destructibleBeanInstance = constraintValidatorMap.remove( instance );
            destructibleBeanInstance.destroy();
        }
    }

【讨论】:

  • 这样做了,没用。 BeanManager 仍然为空。使用 Weld 2.1.2.Final。 @Inject public InjectingConstraintValidatorFactory(BeanManager beanManager) { if (beanManager == null) { this.beanManager = CDI.current().getBeanManager(); } else { this.beanManager = beanManager; } Contracts.assertNotNull(this.beanManager, "The BeanManager cannot be null" ); }
  • 不要使用@Inject构造函数,使用无参数构造函数。
  • 请看我上面的回答。
【解决方案2】:

我终于解决了这个问题。事实证明,validation.xml 并不是真正需要的,resteasy-cdi 模块在注册 BeanManager 方面做得很好。我遗漏并且没有在任何地方明确记录的是,如果在方法上放置注释,验证引擎只会“决定”应该验证的内容。我在一个方法上放置了一个@NotNull,它正在验证返回类型,而不是参数。在某些情况下可以使用validationAppliesTo 元素,但@NotNull 没有它。当我将它从方法移到参数时,它开始工作。 现在我遇到了一个我认为是 Weld 错误的问题,但我会单独发布这个问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-01-31
    • 2015-09-09
    • 1970-01-01
    • 1970-01-01
    • 2014-08-30
    • 2016-04-18
    • 1970-01-01
    • 2013-06-05
    相关资源
    最近更新 更多