【问题标题】:Spring Custom Validator Injection NullPointerExceptionSpring 自定义验证器注入 NullPointerException
【发布时间】:2018-01-15 07:16:50
【问题描述】:

我在尝试使用 Spring 定义自定义约束验证时遇到问题。

我的代码在我的GitHub 上可用。

这里的问题。我有一个对登录有验证约束的实体:

@Entity
public class User {

  @Id
  @GeneratedValue(strategy=GenerationType.AUTO)
  private Long id;

  @UniqueLogin
  private String login;
  [...]
}

这里是注解定义:

@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = UniqueLoginValidator.class)
public @interface UniqueLogin {
  String message() default "{loginIsNotUnique}";
  Class<?>[] groups() default {};
  Class<? extends Payload>[] payload() default {};
}

还有自定义验证器:

public class UniqueLoginValidator implements ConstraintValidator<UniqueLogin, String> {

   @Autowired
   private UserRepository userRepository;

   public boolean isValid(String login, ConstraintValidatorContext context) {
      return userRepository.countByLogin(login) == 0;
   }
}

当我调用repository.save(new User("Kim")); 时,我在UniqueLoginValidator 的注入userRepository 上得到了一个NullPointerException

我假设 Spring 正确地注入了自定义验证器,我必须告诉他。但是,我不知道怎么做。我已经尝试过通过 Stack Overflow 和 Google 找到的一些东西,但没有运气。

任何帮助将不胜感激。

【问题讨论】:

  • 尝试将 UserRepository 移动到 UniqueLoginValidator 的构造函数。然后您的代码将在初始化时失败,您将看到问题。它可以是例如扫描包问题或其他问题。
  • 试图这样做,但得到了Caused by: java.lang.NoSuchMethodException: be.groups.sandbox.customconstraintinjection.UniqueLoginValidator.&lt;init&gt;(),因为没有更多的空构造函数。我认为可能是在 Spring 上下文之外工作的休眠验证使存储库为空。

标签: java spring validation


【解决方案1】:

我遇到了类似的问题,但我能够在自定义验证器中注入 Spring Bean

Spring 框架自动检测所有实现ConstraintValidator 接口的类,实例化它们,并连接所有依赖项。

我正在使用 Spring Boot 2.0。 注意UniqueFieldValidator没有使用任何spring bean注解

示例代码

public class UniqueFieldValidator implements ConstraintValidator<UniqueField, Person> {

    @Autowired
    PersionList personRepository;


    @Override
    public boolean isValid(Person object, ConstraintValidatorContext context) {
        log.info("Validating Person for Duplicate {}",object);
        return personRepository.isPresent(object);
    }

} 

@Documented
@Constraint(validatedBy = UniqueFieldValidator.class)
@Target({ ElementType.METHOD,ElementType.ANNOTATION_TYPE,ElementType.PARAMETER })
@Retention(RetentionPolicy.RUNTIME)
public @interface UniqueField {

    String message() default "Duplicate Name";

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

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

用法

@Component
@Validated
public class PersonService {

    @Autowired
    PersionList personRepository;

    public void addPerson(@UniqueField Person person) {
        personRepository.add(person);
    }
}

【讨论】:

    【解决方案2】:

    经过几次搜索和讨论,似乎将 bean 注入 Bean Validation Constraint 并不是一个好习惯。

    这就是为什么 Hibernate 上下文不知道 Spring 上下文的原因。

    【讨论】:

    • 我必须说 - 这完全不能回答你自己的问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-24
    • 2013-01-04
    • 1970-01-01
    • 1970-01-01
    • 2017-07-27
    • 2011-06-13
    相关资源
    最近更新 更多