Glassfish 4.0中的Bean-Validation 1.1 - CDI注入不按预期工作

chz*_*gla 9 glassfish java-ee cdi bean-validation

根据Glassfish 4.0 wiki,Glassfish 4.0应包含JSR349 Bean Validation 1.1: GF4 wiki链接

根据JSR349规范,CDI Injection应该开箱即用:Bean Validation 1.1.CDI集成

所以我相应地更改了我的pom.xml:

<dependency>
        <groupId>javax.validation</groupId>
        <artifactId>validation-api</artifactId>
        <version>1.1.0.Final</version>
        <scope>provided</scope>
 </dependency>
Run Code Online (Sandbox Code Playgroud)

并尝试将CDI Bean注入ConstraintValidator:

public class UniqueEmaiValidator implements ConstraintValidator<UniqueEmail, String> {

    @Inject
    private UserAccountService accountService;

    @Override
    public void initialize(UniqueEmail constraintAnnotation) {
    }

    @Override
    public boolean isValid(String value, ConstraintValidatorContext context) {
         return !accountService.userExistsByEmail(value);
    }
}
Run Code Online (Sandbox Code Playgroud)

但是,在测试应用程序(使用arquillian-glassfish-remote-3.1 1.0.0.CR4运行Arquillian 1.1.1.)时,验证将始终失败,因为它userAccountService为null,因此NullPointerException最终会抛出 .

我错过了什么使Bean Validation 1.1工作?

编辑:

A)可以确认它不是由Arquillian远程测试引起的 - 也会抛出NPEx.在服务器上运行时

B)在GlassFish Server Open Source Edition 4.0上运行(build 89)

C)我使用Hibernate Validator的5.0.1.FINAL显式重新构建了bean-validation.jar.的mvn package输出:

[INFO] Building Validation API (JSR 349) version 1.1.0.Final, Hibernate Validator version 5.0.1.Final and its dependencies repackaged as OSGi bundle 2.1.92

启动GlassFish服务器后,我会收到以下信息:

INFO:   GlassFish Server Open Source Edition  4.0  (89) startup time : Felix (5,736ms), startup services(2,078ms), total(7,814ms)
INFO:   HV000001: Hibernate Validator 5.0.1.Final
Run Code Online (Sandbox Code Playgroud)

所以我认为重建工作确实有效.但是,它没有解决我的NullPointerException问题:/

D)@Gunnar

这是使用@Constraint注释的实体类:

@Entity
public class UserAccount extends AbstractEntity implements VisibilitySettings {

  @UniqueEmail
  private String email;
  [...] 
}
Run Code Online (Sandbox Code Playgroud)

注释本身:

@Constraint(validatedBy = {UniqueEmailValidator.class})
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface UniqueEmail {

    String message() default "{validator.security.useraccount.emailexists}";

    Class<?>[] groups() default {};

    Class<? extends Payload>[] payload() default {};
}
Run Code Online (Sandbox Code Playgroud)

相应的ConstraintValidator:

public class UniqueEmailValidator implements ConstraintValidator<UniqueEmail, String> {

    @Inject
    private UserAccountService accountService;

    @Override
    public void initialize(UniqueEmail constraintAnnotation) {
    }

    @Override
    public boolean isValid(String value, ConstraintValidatorContext context) {
        return !accountService.userExistsByEmail(value);
    }
}
Run Code Online (Sandbox Code Playgroud)

UserAccountService注释注释@ApplicationScoped @Transactional

Gun*_*nar 3

通过 手动引导验证器时,CDI 集成无法开箱即用Validation.buildDefaultValidatorFactory()

当通过 JPA 将验证作为实体生命周期的一部分执行时,CDI 集成应该可以工作;如果没有,则 Bean 验证如何集成到 GlassFish 中可能仍存在问题。如果确实如此,您可以通过配置自定义约束验证器工厂来解决该问题,在该工厂中META-INF/validation.xml创建 CDI 托管验证器实例。

为此,您可以使用Hibernate Validator 的 CDI 集成提供的工厂作为起点。请注意,虽然通过 XML 配置,工厂需要一个默认构造函数;为了满足该要求,您可以获取对 via JNDI 的引用BeanManager