java - 当自定义 validator 使用 @Component 注释时,JSR-303 验证将被忽略

标签 java spring validation spring-boot bean-validation

我注意到,当声明使用 @Component 注释的自定义 Validator bean 时,Spring 中完全忽略 JSR-303 验证。有趣的是,所述自定义 validator 甚至不需要由任何类填写或使用。事实上,Spring 扫描其组件似乎足以使 Spring 在对象绑定(bind)期间完全跳过 JSR-303 验证。从自定义 validator 中删除 @Component 并重新启动 Web 应用程序可以按预期启用 JSR-303 验证。使用 @Component 注解自定义 validator 有其用途,例如具有 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 错误?

<小时/>

编辑

See demo Spring Boot project on GitHub

最佳答案

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

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

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

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

关于java - 当自定义 validator 使用 @Component 注释时,JSR-303 验证将被忽略,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44188422/

相关文章:

多次调用 Spring 安全自定义过滤器

java - Spring 启动 JPA : Many to Many relation as its own class?

java - 从对象中检索 bean 属性值

validation - Grails:约束:数据库允许空值,但表单不能为空

java - 使用 += 构建从 null 开始的字符串的紧凑方法

java - 运行程序之前我需要满足的条件

java - 如何获取包含在我的源目录中的文件?

php - 在 cakephp 模型中验证比较两个字段

javascript - jquery.validate 验证禁用字段

java - 不使用基本 Activity 的 Ormlite 设置