Spring:未调用自定义验证器

r.r*_*uez 7 java validation spring spring-mvc web

我正在查看有关 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

    }

}
Run Code Online (Sandbox Code Playgroud)

控制器:

@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";
    }
}
Run Code Online (Sandbox Code Playgroud)

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

谁能帮我?

Sot*_*lis 0

查看源代码后,我能找到WebDataBinder不调用您的唯一原因Validator是您的变量是null. 这个领域

@Autowired
private AccountValidator accountValidator;
Run Code Online (Sandbox Code Playgroud)

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


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

摆脱

binder.setValidator(accountValidator);
Run Code Online (Sandbox Code Playgroud)

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";
}
Run Code Online (Sandbox Code Playgroud)

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