【问题标题】:Spring: custom validator is not being calledSpring:未调用自定义验证器
【发布时间】:2013-11-15 09:54:18
【问题描述】:

我正在查看有关 Spring 自定义验证器的其他问题,但不幸的是,我无法通过建议的答案解决我的问题。

我的问题如下:我有一个实体 (Account),我创建了一个自定义验证器 (AccountValidator),我在控制器 (RegisterController) 中使用它,但它从未使用默认验证器调用。

我是不是忘记了什么?我附上部分代码以帮助更好地理解我的问题。

验证器:

public class AccountValidator implements Validator{

    @Override
    public boolean supports(Class<?> clazz) {
        return (Account.class).isAssignableFrom(clazz);
    }

    @Override
    public void validate(Object target, Errors errors) {

    //Validation code

    }

}

控制器:

@Controller
@RequestMapping(value = "/register")
public class RegisterController {

    @Autowired
    private AccountValidator accountValidator;

    @InitBinder
    public void initBinder(WebDataBinder binder) {
        binder.setDisallowedFields("id");
        binder.setValidator(accountValidator);
    }

    @RequestMapping(method = RequestMethod.GET)
    @ModelAttribute
    public Account register(Locale currentLocale){
        Account account = new Account();
        return account;
    }

    @RequestMapping(method = RequestMethod.POST)
    public String handleRegister(@Valid @ModelAttribute Account account, BindingResult result){
        if(result.hasErrors()){
            return "/register";
        }
        return "home";
    }
}

我在日志中检查了我的调试消息,并且正在调用 initBinder 方法,但从未执行过验证方法。

谁能帮帮我?

【问题讨论】:

  • 我尝试了一些方法,但无法重现您所看到的行为。你能发布一个完整的(最小的)配置来重现这个吗?

标签: java spring validation spring-mvc web


【解决方案1】:

我遇到了同样的问题,我通过在上下文 xml 文件中声明类 AccountValidator 并使用 @validated 代替 @valid 来修复它。

【讨论】:

    【解决方案2】:

    查看源代码后,我能找到WebDataBinder 不调用您的Validator 的唯一原因是您的变量是null。该字段

    @Autowired
    private AccountValidator accountValidator;
    

    必须是null。我不知道你是怎么到那里的,如果 Spring 不能自动装配一个字段,它会抱怨。


    目前,我无法告诉您为什么在使用 WebDataBinder 注册时没有调用 Validator,但解决方法如下:

    摆脱

    binder.setValidator(accountValidator);
    

    并在处理程序方法中添加Validator 调用

    @RequestMapping(method = RequestMethod.POST)
    public String handleRegister(@Valid @ModelAttribute Account account, BindingResult result){
        accountValidator.validate(account, result);
        if(result.hasErrors()){
            return "/register";
        }
        return "home";
    }
    

    Spring 将执行默认验证(基于您的验证提供程序,例如 Hibernate),然后您应用您的自定义验证。

    【讨论】:

    • 我不想显式调用验证方法。本来以为在initBinder中配置,用@Valid注解应该就够了,但是不行……
    • @r.rodriguez 我能找到的唯一原因是你的accountValidatornull。你能发布你的配置吗?
    • 我刚查了一下,不是null
    【解决方案3】:

    我遇到了同样的问题,结果发现我遇到了一个 SQL 异常,似乎绕过了我的验证器,因为我的方法使用了 @Transactional 注释。

    【讨论】:

      【解决方案4】:

      我想你想使用binder.addValidator(accountValidator); 而不是binder.setValidator(accountValidator);

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-06-03
        • 2016-12-04
        • 2018-01-19
        • 2015-01-02
        • 1970-01-01
        • 2014-09-24
        • 1970-01-01
        • 2020-09-22
        相关资源
        最近更新 更多