小编典典

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

spring-boot

我注意到在@Component声明带有注解的自定义Validator
bean时,Spring会完全忽略JSR-303验证。有趣的是,所述自定义验证器甚至不必由任何类填充或使用。Spring扫描其组件的事实似乎足以使Spring在对象绑定期间完全跳过JSR-303验证。@Component从定制Validator中删除并重新启动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
    }
}

我为这个问题and之以鼻,无法弄清楚为什么我的JSR-303对象没有得到验证,但是我设法缩小了范围,并使用包含上述类的Spring
Boot项目来复制它。这是为什么?我在这里缺少什么还是这是Spring的错误?


编辑

在GitHub上查看演示Spring Boot项目


阅读 251

收藏
2020-05-30

共1个答案

小编典典

因此,您的代码中存在许多问题。首先,您的自定义验证程序不支持任何功能,因此永远不会被调用。您可能意识到了,所以我将由您自己解决。

但是,您真正的问题是,通过创建像这样的验证器bean,Spring既不会创建该defaultValidatorbean(是LocalValidatorFactoryBean),也不会创建该methodValidationPostProcessorbean(用于验证方法参数)。这是人们在Spring中遇到的一个常见问题:一旦您做一些事情来干扰自动配置过程,就必须手动定义。解决方案很简单:创建一个定义这些bean的配置类。例:

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

    @Bean public MethodValidationPostProcessor methodValidationPostProcessor() {
        return new MethodValidationPostProcessor();
    }
}
2020-05-30