Автопроводка услуги в валидатор - PullRequest
11 голосов
/ 27 августа 2010

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

@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, и я могу убедиться, что вызывается его конструктор.

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

Ответы [ 2 ]

13 голосов
/ 27 августа 2010

Весной вам нужно получить 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()) {   
        ...
    }
}

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

0 голосов
/ 27 августа 2010

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

...