Автоматическое подключение службы к валидатору

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

@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 было пусто . Почему он не подключается автоматически? Сначала я думал, что это потому, что я не аннотировал валидатор с помощью @Component , но у меня все еще остается та же проблема, даже после того, как я ее аннотировал. Класс UsernameService уже аннотирован с помощью @Service , и я могу убедиться, что его конструктор вызывается.

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

11
задан Vivin Paliath 27 August 2010 в 19:02
поделиться

2 ответа

В Spring вам необходимо получить 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"/>

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

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

Для этого также требуется в конфиг.

13
ответ дан 3 December 2019 в 08:53
поделиться

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

0
ответ дан 3 December 2019 в 08:53
поделиться
Другие вопросы по тегам:

Похожие вопросы: