Domanda

i have a little problem with implementing properly my own validation annotation.

Here is sample code:

@Pattern(regexp="[0-9]*")
@Size(min=3, max=10)
@Constraint(validatedBy = SampleValidator.class)
@Documented
@Target({ANNOTATION_TYPE, METHOD, FIELD, CONSTRUCTOR, PARAMETER})
@Retention(RUNTIME)
public @interface MyAnnotation {

    String message() default "Wrong!";
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};

    @Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER })
    @Retention(RUNTIME)
    @Documented
    @interface List {
        MyAnnotation[] value();
    }

}

My problem is, I want my annotation to work in the way, that @Size and @Pattern annotation run first and if they're valid then (and only then) run validator provided by @Constraint annotation (SampleValidator.class).

Put it simple:

  • I want to run SampleValidator only if @Pattern and @Size are valid

(I implementes SampleValidator just as additional validator that should be called only in some specific circumstances)

How can I obtain such behaviour? Thanks in advance!

Obviously, I can't do anything like that:

@GroupSequence({ Step1.class, Step2.class })
@Constraint(validatedBy = SampleValidator.class, groups = Step1.class) // no 'groups' attribute
@Size(min=3, max=10, groups = Step2.class)
@Pattern(regexp="[0-9]*", groups = Step2.class)
@Documented
@Target({ANNOTATION_TYPE, METHOD, FIELD, CONSTRUCTOR, PARAMETER})
@Retention(RUNTIME)
public @interface MyAnnotation {
    ...
}
È stato utile?

Soluzione 2

The answer is only partly correct. Yes @ReportAsSingleViolation that only one single violations will be generated and validation will stop after first failure in this case. However, the specification gives no guarantee in which order constraints are evaluated. It could be the composing constraints first or the validator specified via @Constraint. If anything you would rely on some implementation detail which could change any time. Also there is no order defined in which @Size and @Pattern are evaluated. Bottom line, you cannot achieve your wanted behaviour with constraint composition.

If you want to guarantee a sequenced execution you need to look at the GroupSequence feature.

Altri suggerimenti

Try adding the @ReportAsSingleViolation annotation. According to the specification:

"More specifically, if a composed constraint is marked as @ReportAsSingleViolation, the evaluation of the composing constraints stops at the first failing constraint and the error report corresponding to the composed constraint is generated and returned."

http://beanvalidation.org/1.1/spec/#constraintsdefinitionimplementation-constraintcomposition

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top