spring - 使用 Spring 的 JSR-303 bean 验证没有启动

标签 spring bean-validation hibernate-validator

我已经按照文档( http://docs.spring.io/spring/docs/4.0.x/spring-framework-reference/html/validation.html )中给出的内容配置了一个 JSR-303 自定义验证器,并在类路径上使用了 LocalValidatorFactoryBean 和 Hibernate 验证器。然而,我的验证器只是拒绝启动。我在这里放置了一个简单的测试项目( https://github.com/abhijitsarkar/java/tree/master/spring-jsr-303 ),以及一个失败的单元测试。如果您决定看一看,只需克隆它并运行gradlew clean test从根目录。
我正在使用 Spring 框架 4.0.2.RELEASE 和 Hibernate 验证器 5.0.3.Final。

验证中的方法:

public Coffee serve(@ValidOrder(Coffee.Blend.class) final String blend) {

ValidOrder 注释:
@Documented
@Constraint(validatedBy = {OrderValidator.class})
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD,
        ElementType.FIELD,
        ElementType.ANNOTATION_TYPE,
        ElementType.CONSTRUCTOR,
        ElementType.PARAMETER})
@NotNull
public @interface ValidOrder {

OrderValidator 验证器:
public class OrderValidator implements ConstraintValidator<ValidOrder, String> {

Spring 配置:
@Configuration
@ComponentScan(basePackages = "name.abhijitsarkar.coffeehouse")
@EnableAspectJAutoProxy
public abstract class AppConfig {

    @Bean
    public LocalValidatorFactoryBean validator() {
        return new LocalValidatorFactoryBean();
    }
}

依赖项:
dependencies {
    compile(
            [group: 'javax.inject', name: 'javax.inject', version: injectApiVersion],
            [group: 'javax.validation', name: 'validation-api', version: beanValidationApiVersion],
            [group: 'javax.annotation', name: 'javax.annotation-api', version: annotationApiVersion],
            [group: 'org.springframework', name: 'spring-beans', version: springVersion],
            [group: 'org.springframework', name: 'spring-context', version: springVersion],
            [group: 'org.springframework', name: 'spring-aop', version: springVersion],
            [group: 'org.aspectj', name: 'aspectjrt', version: aspectjVersion]
    )
    runtime(
            [group: 'org.hibernate', name: 'hibernate-validator', version: hibernateValidatorVersion],
            [group: 'javax.el', name: 'javax.el-api', version: elVersion],
            [group: 'org.glassfish.web', name: 'javax.el', version: glassfishElVersion],
            [group: 'org.aspectj', name: 'aspectjweaver', version: aspectjVersion]
    )

最佳答案

  • 除了 LocalValidatorFactoryBean 之外,还需要配置 MethodValidationPostProcessor。
  • 要验证的类必须具有 @Validated其他方法的注释不会搜索内联约束注释。
    @Configuration
    @ComponentScan(basePackageClasses = {SpringPackageComponentScanMarker.class})
    @EnableAspectJAutoProxy
    public abstract class AppConfig {
    
    @Bean
    public MethodValidationPostProcessor methodValidationPostProcessor() {
        final MethodValidationPostProcessor methodValidationPostProcessor = new MethodValidationPostProcessor();
        methodValidationPostProcessor.setValidator(validator());
    
        return methodValidationPostProcessor;
    }
    
    @Bean
    public LocalValidatorFactoryBean validator() {
        final LocalValidatorFactoryBean localValidatorFactoryBean = new LocalValidatorFactoryBean();
    
        return localValidatorFactoryBean;
      }
    }
    

  • ...
    @Service
    @Validated
    public class SpringBarista extends Barista {
    

    引用手册中讨论与 JSR-303 集成的部分方便地省略了这 2 个关键点,否则 BV 不会启动。这只是导致我进行了 6 小时的调试和头发撕裂,我做了文档所说的一切,但 BV 只会简单地没有开始。我最终不得不通过 Spring 源代码进行调试才能理解这一点。必须有一种更简单的方法,我不能是唯一遇到这个问题的人。创建了 JIRA SPR-11473让他们更新文档。

    关于spring - 使用 Spring 的 JSR-303 bean 验证没有启动,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21963784/

    相关文章:

    jsf-2 - Bean 验证在 JSF2.2 (Majorra 2.2.5) 下不起作用

    java - 如何正确抛出 MethodArgumentNotValidException

    spring - 订单 <表单 :error path ="*"/> messages so their order isn't random

    java - 将默认 hibernate 消息委托(delegate)给约束组合中的验证失败

    私有(private)方法上的 Javax 验证不会被触发

    java - 编码密码看起来不像 BCrypt

    java - 为 @ExceptionHandler 中的每个异常生成正确的状态

    java - Spring @async 注释可能无法触发的原因是什么?

    java - 谁能告诉我学习 spring 的最好方法是什么

    validation - 有没有一种方法可以使用 Hibernate 进行嵌套约束验证,而无需使用 @Valid 注释?