首页 文章

使用@Component注释自定义Validator时,将忽略JSR-303验证

提问于
浏览
2

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

考虑下面的简单示例:

/* 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吗?


编辑

See demo Spring Boot project on GitHub

1 回答

  • 2

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

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

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

相关问题