【问题标题】:Inject Service in ConstraintValidator [Bean Validator - JSR 303] Spring在 ConstraintValidator 中注入服务 [Bean Validator - JSR 303] Spring
【发布时间】:2012-11-01 06:42:27
【问题描述】:

下午好,

我在 Bean Validator (JSR 303) 中注入服务时遇到问题。我将执行验证,但我需要在我的数据库中验证此记录;

当我使用我的服务时,它会抛出 NullPointerException;

例外:

Exception in thread "main" javax.validation.ValidationException: HV000028: Unexpected exception during isValid call.
at org.hibernate.validator.internal.engine.ConstraintTree.validateSingleConstraint(ConstraintTree.java:294)
at org.hibernate.validator.internal.engine.ConstraintTree.validateConstraints(ConstraintTree.java:164)
at org.hibernate.validator.internal.engine.ConstraintTree.validateConstraints(ConstraintTree.java:125)
at org.hibernate.validator.internal.metadata.core.MetaConstraint.validateConstraint(MetaConstraint.java:86)
at org.hibernate.validator.internal.engine.ValidatorImpl.validateConstraint(ValidatorImpl.java:442)
at org.hibernate.validator.internal.engine.ValidatorImpl.validateConstraintsForDefaultGroup(ValidatorImpl.java:387)
at org.hibernate.validator.internal.engine.ValidatorImpl.validateConstraintsForCurrentGroup(ValidatorImpl.java:351)
at org.hibernate.validator.internal.engine.ValidatorImpl.validateInContext(ValidatorImpl.java:303)
at org.hibernate.validator.internal.engine.ValidatorImpl.validate(ValidatorImpl.java:133)
at net.pontoall.hemisphere.core.validation.impl.TesteValidator.main(TesteValidator.java:25)



Caused by: java.lang.NullPointerException
at net.pontoall.hemisphere.core.validation.impl.UsuarioValidatorImpl.doCheckLogin(UsuarioValidatorImpl.java:48)
at net.pontoall.hemisphere.core.validation.impl.UsuarioValidatorImpl.isValid(UsuarioValidatorImpl.java:26)
at net.pontoall.hemisphere.core.validation.impl.UsuarioValidatorImpl.isValid(UsuarioValidatorImpl.java:1)
at org.hibernate.validator.internal.engine.ConstraintTree.validateSingleConstraint(ConstraintTree.java:291)
... 9 more

注释:

@Target(value = ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = UsuarioValidatorImpl.class)
public @interface UsuarioValidator {

String message() default "{net.pontoall.hemisphere.validation.UsuarioValidator.message}";

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

Class<? extends Payload>[] payload() default {};

}

ValidatorImpl:

public class UsuarioValidatorImpl implements ConstraintValidator<UsuarioValidator, Usuario> {

@Autowired
private IUsuarioService service;

@Override
public void initialize(UsuarioValidator arg0) {

}

@Override
public boolean isValid(Usuario entidade, ConstraintValidatorContext ctx) {
    try {
        return (this.doCheckLogin(entidade, ctx) && this.doCheckEmail(entidade, ctx));
    } catch (HemisphereException e) {
        e.printStackTrace();
        return false;
    }
}

private boolean doCheckLogin(Usuario entidade, ConstraintValidatorContext ctx) throws HemisphereException {
    ctx.buildConstraintViolationWithTemplate("{net.pontoall.hemisphere.validation.UsuarioValidator.login.message}").addConstraintViolation();

    if (entidade.getId() == null) {
        // Novo Usuário
        Usuario original = service.buscarPorLogin(entidade.getLogin());

        if (original == null) {
            return true;
        }

        return false;

    } else {

        Usuario original = service.obter(entidade.getId());
        if (original == null) {
            return true;
        } else {
            if (original.getLogin().equals(entidade.getLogin()) && original.getId().equals(entidade.getId())) {
                return true;
            }
        }

        return false;
    }
}

private boolean doCheckEmail(Usuario entidade, ConstraintValidatorContext ctx) {
    ctx.buildConstraintViolationWithTemplate("{net.pontoall.hemisphere.validation.UsuarioValidator.email.message}").addConstraintViolation();

    if (entidade.getId() == null) {
        // Novo Usuário
        Usuario original = service.buscarPorEmail(entidade.getEmail());

        if (original == null) {
            return true;
        }

        return false;

    } else {

        Usuario original = service.obter(entidade.getId());
        if (original == null) {
            return true;
        } else {
            if (original.getEmail().equals(entidade.getEmail()) && original.getId().equals(entidade.getId())) {
                return true;
            }
        }

        return false;
    }
}
}

【问题讨论】:

  • 你在使用Spring MVC吗,如果是,请你也显示一下Spring MVC的配置

标签: spring validation bean-validation


【解决方案1】:

如果您想连接依赖关系,请构建ConstraintValidatorFactory 或使用SpringConstraintValidatorFactory

【讨论】:

    【解决方案2】:

    您必须编写一个自定义ConstraintValidatorFactory。不过,仅供参考,Bean Validation 1.1 将允许注入 ConstraintValidatorFactory

    【讨论】:

      【解决方案3】:

      您应该在 Spring 应用程序上下文中设置 LocalValidatorFactoryBean,以便您可以通过依赖注入检索 Validator(和 ValidatorFactory)实例。

      默认情况下,像这样获得的验证器使用SpringConstraintValidatorFactory,它为约束验证器实现提供依赖注入服务,正如 Pangea 所指出的那样。

      【讨论】:

        【解决方案4】:

        我通过“just”“让它工作”(spring-boot:2.5.7):

        @Component // mandatory!!! (or one of its descendants) to enable `@Autowired` 
        @Scope("request") // not mandatory, but probably "good" for "validation"
        public class UsuarioValidatorImpl implements ConstraintValidator<..., ...> ...
        

        或者,您可以在 @Configuration 类中定义 @Bean public UsuarioValidator ... 方法....

        但是自动连接(任何)两个对象的关键:两者都必须是spring-managed!!

        【讨论】:

          猜你喜欢
          • 2013-06-09
          • 1970-01-01
          • 2011-03-23
          • 1970-01-01
          • 2016-01-20
          • 1970-01-01
          • 1970-01-01
          • 2011-07-24
          • 2013-11-23
          相关资源
          最近更新 更多