Spring:未调用自定义验证器

Posted

技术标签:

【中文标题】Spring:未调用自定义验证器【英文标题】:Spring: custom validator is not being called 【发布时间】: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 方法,但从未执行过验证方法。

谁能帮帮我?

【问题讨论】:

我尝试了一些方法,但无法重现您所看到的行为。你能发布一个完整的(最小的)配置来重现这个吗? 【参考方案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);

【讨论】:

以上是关于Spring:未调用自定义验证器的主要内容,如果未能解决你的问题,请参考以下文章

Spring Security:未调用自定义 UserDetailsS​​ervice(使用 Auth0 身份验证)

Grails 3.2.4:未调用自定义身份验证过滤器

Angular 4:未调用自定义验证器

未调用 Spring Security 自定义登录表单

Spring Security 自定义 AuthenticationProvider 验证方法调用了两次

Spring-security/Grails 应用程序 - 未调用自定义 WebSecurity 配置