将服务自动装配到验证器中

时间:2010-08-27 19:02:30

标签: spring validation hibernate-validator autowired spring-3

这个例子有点人为;我简化了它以删除无关的细节,并专注于我遇到的问题。我有一个看起来像这样的验证器:

@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例外。我在验证程序中添加了一个断点,并看到usernameServicenull。为什么不进行自动装配?最初我认为这是因为我没有用@Component注释验证器,但即使在注释它之后我仍然遇到同样的问题。 UsernameService类已经使用@Service进行了注释,我可以验证它的构造函数是否被调用。

我是Spring的新手,所以我甚至不确定将服务连接到验证器是否可以。我做错了什么?

2 个答案:

答案 0 :(得分:12)

在Spring中,您需要通过ValidatorFactory而不是Validator获取LocalValidatorFactoryBean(或Validation.buildDefaultValidatorFactory()本身),如in the reference所述。

@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 @Valid注释的Spring MVC自动验证:

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

配置中还需要<mvc:annotation-driven/>

答案 1 :(得分:0)

您必须自动装配或将其注入控制器,而不是创建新的验证器。来自未作为验证者注入的服务的NPE不是由spring创建/管理的。