Вопрос

Этот пример поврежден; Я упростил его, чтобы удалить посторонние детали и сосредоточиться на проблеме, у меня есть. У меня есть валидатор, который выглядит так:

@Component
public class UniqueUsernameValidator implements ConstraintValidator<UniqueUsername, String> {

    @Autowired
    UsernameService usernameService;

    @Override
    public void initialize(UniqueUsername uniqueUsername) {
    }

    @Override
    public boolean isValid(String s, ConstraintValidatorContext constraintValidatorContext) {
        return !usernameService.exists(s);
    }   
}

Я называю валидатора от моего контроллера, как это:

@RequestMapping
public void checkUsername(Model model, User user) {
    ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
    Validator validator = factory.getValidator();

    Set<ConstraintViolation<User>> constraintViolations = validator.validateProperty(user, "username");
    model.addAttribute("error", constraintViolations.size() > 0);
}

Тем не менее, я продолжаю получать NullPointerException исключение. Я добавил точку останова в моем валидатере и увидел, что usernameService было null. Отказ Почему это не получает отключение? Изначально я думал, что это потому, что я не аннотировал валидатор с @Component, Но у меня все еще есть та же проблема даже после аннотации. То UsernameService класс уже аннотирован с @Service И я могу проверить, что его конструктор вызывается.

Я новичок до весны, поэтому я даже не уверен, если это нормально, чтобы провозить услугу в валидатор. Что я делаю неправильно?

Это было полезно?

Решение

Весной вам нужно получить ValidatorFactory (или Validator сама) через LocalValidatorFactoryBean вместо Validation.buildDefaultValidatorFactory(), как описано в ссылке.

@Autowired
Validator validator;

@RequestMapping 
public void checkUsername(Model model, User user) { 
    Set<ConstraintViolation<User>> constraintViolations = validator.validateProperty(user, "username"); 
    model.addAttribute("error", constraintViolations.size() > 0); 
} 

-

<bean id="validator"
    class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"/>

РЕДАКТИРОВАТЬ: Но, возможно, лучший способ сделать это для использования автоматической проверки весны MVC с @Valid Аннотация:

@RequestMapping  
public void checkUsername(Model model, @Valid User user, BindingResult result) {  
    if (result.hasErrors()) {   
        ...
    }
}

Это также требует <mvc:annotation-driven/> на конфиге.

Другие советы

Вместо того, чтобы создать новый валидатор, вы должны авторизовать или ввести его для контроллера. То NPE От службы, не вводимого, поскольку ваш валидатор не создается / управляется весной.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top