JSR-303使用Spring的bean验证不起作用

JSR-303使用Spring的bean验证不起作用,spring,bean-validation,hibernate-validator,Spring,Bean Validation,Hibernate Validator,我已经按照文档()中给出的配置了JSR-303自定义验证器,并在类路径上配置了LocalValidatoryFactoryBean和Hibernate验证器。然而,我的验证器只是拒绝启动。我在这里建立了一个非常简单的测试项目(),还有一个失败的单元测试。如果您决定看一看,只需克隆它并运行 gradlew clean test从根目录。 我使用的是SpringFramework4.0.2.RELEASE和HibernateValidator5.0.3.Final 正在验证的方法: public C

我已经按照文档()中给出的配置了JSR-303自定义验证器,并在类路径上配置了LocalValidatoryFactoryBean和Hibernate验证器。然而,我的验证器只是拒绝启动。我在这里建立了一个非常简单的测试项目(),还有一个失败的单元测试。如果您决定看一看,只需克隆它并运行
gradlew clean test
从根目录。 我使用的是SpringFramework4.0.2.RELEASE和HibernateValidator5.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> {
依赖项:

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

为了使spring-to-validation能够在blend参数前面插入一个
@Valid
注释

您的方法可能不起作用,因为JSR303不支持参数约束

约束注释可以针对以下任意图元类型:

受约束属性的字段

约束吸气剂法

受约束bean的类型

构成其他约束的约束的注释类型

  • 除了LocalValidationFactoryBean之外,还需要配置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;
      }
    }
    

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

    @Valid
    用于递归验证bean,我不确定它是否对字符串类型有效;它可能期望类的成员有自己的验证约束。那不是我的问题。请看我上面的答案。另外,BV 1.1支持参数约束
    @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 {