本文介绍了使用@Component注释自定义Validator时,将忽略JSR-303验证的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我注意到,当声明了使用 @Component 注释的自定义Validator bean时,在Spring中完全忽略了JSR-303验证。有趣的是,自定义验证器甚至不必填写或使用任何类。由Spring扫描的组件似乎足以使Spring在对象绑定期间完全跳过JSR-303验证。从自定义Validator中删除 @Component 并重新启动Web应用程序可以按预期启用JSR-303验证。使用 @Component 注释自定义验证器有其用途,例如具有Spring Autowire依赖关系。

I've noticed that JSR-303 validation is completely ignored in Spring when a custom Validator bean annotated with @Component is declared. Interestingly enough said custom validator doesn't even have to filled in or used by any of the classes. The fact that its component scanned by Spring appears to be enough to make Spring skip JSR-303 validation during object binding altogether. Removing @Component from custom Validator and restarting web application enables JSR-303 validation as expected. Annotating custom validators with @Component has its uses eg to have Spring Autowire dependencies.

考虑下面的简单示例:

/* Simple JSR-303 annotated User object */
public class User {

    @NotNull @Size(min = 2, max = 5)
    protected String username;

    @Size(min = 2, max = 32)
    protected String firstName;

    @Size(min = 2, max = 32)
    protected String lastName;

    @NotNull @Past @DateTimeFormat(pattern="dd/MM/yyyy")
    protected Date dateOfBirth;

    @NotNull @Email
    protected String email;

    protected String phone;

    //getters and setters
}



/* Controller example */
@RestController
public class UserController {

    @PostMapping("/users/register")
    public ResponseEntity postUser(@Valid @RequestBody User user, BindingResult result) {
        if (result.hasErrors()) {
            return new ResponseEntity(result.getAllErrors(), HttpStatus.INTERNAL_SERVER_ERROR);
        }
        return new ResponseEntity(user, HttpStatus.CREATED);
    }

}



/* Custom validator (doesn't even have to be in use) */
@Component //commenting out @Component annotation enables JSR-303 again
public class SomeValidator implements Validator {

    @Override
    public boolean supports(Class<?> clazz) {
        //just an example
        return false;
    }

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

我在这个问题上摸不着头脑,无法弄清楚为什么我的JSR-303对象没有经过验证但我设法缩小范围并使用包含上述类的Spring Boot项目复制它。
为什么?我在这里遗漏了什么或者这是一个Spring bug吗?

I was scratching my head over this one and couldn't figure out why my JSR-303 objects weren't validated but I managed to narrow it down and replicate this with a Spring Boot project containing above classes.Why is that? Am I missing something here or is this a Spring bug?

推荐答案

因此,代码中存在许多问题。首先,您的自定义验证器不支持任何内容,因此永远不会调用它。您可能已经意识到这一点,所以我将由您来解决它。

So there are a number of problems going on in your code. First, your custom validator doesn't support anything, so it's never going to be invoked. You probably realize that, so I'll leave it up to you to fix it.

然而,您真正的问题是通过创建类似的验证器bean,Spring不会创建 defaultValidator bean(这是一个 LocalValidatorFactoryBean ),也不会创建 methodValidationPostProcessor bean(验证方法参数所需)。这是人们遇到的常见问题:一旦你做了一些事情来扰乱自动配置过程,你必须手动定义。解决方案很简单:创建一个定义这些bean的配置类。示例:

Your real problem, though, is that by creating a validator bean like that, Spring will not create the defaultValidator bean (which is a LocalValidatorFactoryBean) nor will it create the methodValidationPostProcessor bean (which is needed to validate method parameters). This is a common problem people run into with Spring: once you do something to disturb the auto-configure process, you have to define things manually. The solution is simple: create a config class that defines these beans. Example:

@Configuration
public class ValidationConfig {
    @Bean public LocalValidatorFactoryBean defaultValidator() {
        return new LocalValidatorFactoryBean();
    }

    @Bean public MethodValidationPostProcessor methodValidationPostProcessor() {
        return new MethodValidationPostProcessor();
    }
}

这篇关于使用@Component注释自定义Validator时,将忽略JSR-303验证的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-06 13:16