当前位置: 首页 > 知识库问答 >
问题:

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

朱淮晨
2023-03-14

我注意到,在Spring中,当声明使用@Component注释的自定义验证器bean时,JSR-303验证被完全忽略。有趣的是,自定义验证器甚至不需要任何类填写或使用。Spring扫描其组件的事实似乎足以让Spring在对象绑定期间跳过JSR-303验证。从自定义验证器中删除@组件,然后重新启动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的错误?

请参阅GitHub上的Spring Boot演示项目

共有1个答案

施彬郁
2023-03-14

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

然而,您真正的问题是,通过创建这样的验证器bean,Spring不会创建defaultValidatorbean(它是LocalValidatoryBean),也不会创建methodValidationPostProcessorbean(验证方法参数所需的)。这是人们在使用Spring时遇到的一个常见问题:一旦您做了一些干扰自动配置过程的事情,就必须手动定义。解决方案很简单:创建一个定义这些bean的配置类。例子:

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

    @Bean public MethodValidationPostProcessor methodValidationPostProcessor() {
        return new MethodValidationPostProcessor();
    }
}
 类似资料:
  • 我们有一个带有JSR注释的简单bean 我们有一个Spring控制器 我们的问题是,当调用changePassword时,验证器忽略组(PasswordChange.Class)并只验证组中不存在的firstName和lastName。 知道吗?非常感谢你抽出时间。

  • 编写自定义约束时,一个验证器实现可以验证多个注释。例如,我有几个注释,它们规定了不同的@size注释,但我希望它们都指向同一个验证器类,该类执行一些全局检查,即所有注释都必须与某个正则表达式匹配。据我所知,该实现采用了一种注释类型。 一个注释 验证器

  • 我正在用Spring和Thymeleaf填表: MyForm如下所示: 正如您所看到的,我做了一个自定义注释,它应该检查输入值是否可以解析为: 现在在我的Controller类中,我正在执行以下操作: 但是,当试图将放入文本字段以测试验证时,获取: 下面是我读到的示例,并希望用自定义验证器进行扩展:http://viralpatel.net/blogs/spring-mvc-hashmap-for

  • 我的bean中有两个字段 当字段key=“A”,“value”应该跟在其他“key”的特定Regex后面时,它可以是任何内容。 如何根据键定义此值验证。

  • 我有一个可以创建和编辑组的应用程序。每个团体都有一个独特的头衔。当有人试图创建新组时,我会检查是否有具有该标题的组,如果有,则验证失败。问题是,当有人试图编辑组而不更改标题时,根据我的自定义验证,有一个组具有该标题(有人正在编辑的标题),而我的验证失败,因此用户无法保存该组。所以我想问一下,是否有人能解决这个问题。非常感谢您的回答! 我的班级 我的验证器接口 我的验证器

  • 问题内容: 我有如下测试: 具有以下输出: 但是,我希望注释可以被覆盖,并且不会出现警告。 有没有办法做到这一点? 编辑:我发现一个错误似乎与此有关,但我最终运行4.2.0,仍然得到上述行为。 问题答案: 实际上,JSR-303不支持覆盖验证注释。相反,子类中重写方法的注释将 累积 应用:从规范的3.3节开始: