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

时间:2014-02-23 03:21:17

标签: 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 framework 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 config:

@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]
    )

2 个答案:

答案 0 :(得分:20)

  1. 除了LocalValidatorFactoryBean之外,还需要配置MethodValidationPostProcessor。
  2. 要验证的类必须在其上有@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;
      }
    }
    
  3. ...

    @Service
    @Validated
    public class SpringBarista extends Barista {
    

    参考手册中谈到与JSR-303集成的部分很方便地省略了这两个关键点,没有BV没有启动。这只是让我进行了6个小时的调试和头发撕裂我做了医生所说的一切但是BV根本就没有启动。我最终不得不通过Spring源代码进行调试来理解这一点。必须有一个更简单的方法,我不能成为唯一有这个问题的人。为他们创建了一个JIRA SPR-11473来更新文档。

答案 1 :(得分:0)

要进行弹簧验证以启动混合参数,需要在其前面添加@Valid注释。

由于JSR303不支持参数约束,因此您的方法可能无效。

  

约束注释可以针对以下任何ElementTypes:

     

受约束属性的字段

     

约束吸气剂的方法

     

约束豆的TYPE

     

ANNOTATION_TYPE用于构成其他约束的约束

http://beanvalidation.org/1.0/spec/#constraintsdefinitionimplementation