【问题标题】:Autowiring a service into a validator将服务自动装配到验证器中
【发布时间】:2011-04-04 23:28:45
【问题描述】:

这个例子有点做作;我已经对其进行了简化,以删除无关的细节并专注于我遇到的问题。我有一个看起来像这样的验证器:

@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 新手,所以我什至不确定是否可以将服务连接到验证器。我做错了什么?

【问题讨论】:

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


    【解决方案1】:

    在 Spring 中,您需要通过LocalValidatorFactoryBean 而不是Validation.buildDefaultValidatorFactory() 获取ValidatorFactory(或Validator 本身),如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 MVC 的自动验证和 @Valid 注释:

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

    这也需要配置中的&lt;mvc:annotation-driven/&gt;

    【讨论】:

    • 非常感谢!这正是我一直在寻找的。我正在浏览参考文档,但我正在寻找诸如“将服务自动装配到约束中”之类的东西。再次感谢!
    • 我喜欢使用@Valid 进行编辑。希望我能多次投票:)
    • 非常感谢,您的回答帮我节省了时间!
    【解决方案2】:

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

    【讨论】:

    • 如果我直接自动连接验证器,我需要ConstraintValidatorContext 来调用isValid。我怎么得到它?在我看来,这也有点笨拙。有没有更好的方法来做我想做的事情?
    猜你喜欢
    • 2014-11-08
    • 1970-01-01
    • 2022-01-01
    • 2015-05-05
    • 2015-03-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多