I'm trying to use a cross parameter constraint validator targeted on method parameters. The problem is the validation is not triggered for the method parameters instead it is triggered for the method return value.
I'm using Spring's LocalValidatorFactoryBean.
The JSR-303 provider is hibernate-validator 4.2.0.Final.
Spring version is 3.2.0.

Spring configuration excerpt :

<!-- JSR 303 validation -->
<bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean" />
<bean class="org.springframework.validation.beanvalidation.MethodValidationPostProcessor"> 
        <property name="validator" ref="validator"/>
    <bean>

Custom Constraint Validator:

@SupportedValidationTarget( ValidationTarget.PARAMETERS )
public class InstanceValidator implements
    ConstraintValidator<InstanceCheck, Object[]> {

  @Override
  public void initialize(InstanceCheck constraintAnnotation) {}

  @Override
  public boolean isValid(Object[] value, ConstraintValidatorContext context) {
  ...
  }
}

Annotation:

@Target( { METHOD, ANNOTATION_TYPE, CONSTRUCTOR } )
@Retention(RUNTIME)
@Constraint(validatedBy = InstanceValidator.class)
@Documented
public @interface InstanceCheck {
   String message() default "{constraint.instance.not.allowed}";
   public abstract Class<?>[] groups() default {};
   public abstract Class<? extends Payload>[] payload() default {};
}

SomeService:

 @Validated
 public interface SomeService {
    ...
    @InstanceCheck
    public String addContent(String content) throws SomeException;
    ...
 }

SomeServiceImpl :

 @Service
 public class SomeServiceImpl implements SomeService {
  ...
    public String addContent(String content) throws SomeException {
     // do something
    }
  ...
 }

: UPDATE :

I have tried adding the "validationAppliesTo" method for the annotation type (see below)

  @Target( { METHOD, ANNOTATION_TYPE, CONSTRUCTOR } )
  @Retention(RUNTIME)
  @Constraint(validatedBy = InstanceValidator.class)
  @Documented
  public @interface InstanceCheck {
   String message() default "{constraint.instance.not.allowed}";
   public abstract Class<?>[] groups() default {};
   public abstract Class<? extends Payload>[] payload() default {};
   ConstraintTarget validationAppliesTo() default ConstraintTarget.PARAMETERS;
}

, and now I get the following error: "Parameters starting with 'valid' are not allowed in a constraint."

Thanks in advance for any type of advice.

有帮助吗?

解决方案

Cross-parameter constraints are only supported in Hibernate Validator 5.x (Bean Validation 1.1). Hibernate Validator 4.2 doesn't know how to deal with such constraints.

其他提示

This is coding issue or temporary solution in Hibernate Validator.

Remove any field or method starting with 'valid' in custom Annotation.

In your example rename method -

ConstraintTarget validationAppliesTo() default ConstraintTarget.PARAMETERS;

to

ConstraintTarget xxxxxationAppliesTo() default ConstraintTarget.PARAMETERS;

Issue code ConstraintHelper-

    private void assertNoParameterStartsWithValid(Class<? extends Annotation> annotationType) {
    final Method[] methods = run( GetDeclaredMethods.action( annotationType ) );
    for ( Method m : methods ) {
        if ( m.getName().startsWith( "valid" ) && !m.getName().equals( VALIDATION_APPLIES_TO ) ) {
            throw log.getConstraintParametersCannotStartWithValidException();
        }
    }
}
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top