Search code examples
javaannotationsbean-validation

Spring annotation method purpose


I write simple validation annotation for spring project. Problem is that I don't understand some method purpose. Here is my annotation:

@Constraint(validatedBy = PostCodeValidator.class)
@Target({ElementType.METHOD, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface PostCode {
    public String value() default "LUV";
    public String message() default "must start with LUV";
    public Class<?>[] groups() default {};
    public Class<? extends Payload>[] payload() default {};

}

Could anyone explain me groups() & payload() method purpose? I'll be very grateful if explanation will be as simple as it possible. Thanks.


Solution

  • 1) In Bean Validation Api, groups are used for selecting which fields of bean will be validated. Example : a User with Address property.

    public class User {
        @NotNull(groups = GroupUser.class)
        String firstname;
        @NotNull(groups = GroupAddress.class)
        String street;
        @NotNull(groups = GroupAddress.class)
        String city;
    }
    

    To validate the whole user you can do :

    Set<ConstraintViolation<User>> constraintViolations = validator.validate(user, GroupUser.class, GroupAddress.class);
    

    To validate only the user information without address part you can use :

    Set<ConstraintViolation<User>> constraintViolations = validator.validate(user, GroupUserName.class);
    

    2) Payload is used to manage the severity level of error. You can implement Payload interface :

    public class Severity {
        public static class Info implements Payload {}
        public static class Error implements Payload {}
    }
    

    If you annotate the firstname field with :

    @NotNull(payload = {Severity.Error.class})
    

    Then after validation you can add some logic by severity :

    for (ConstraintViolation<TestBean> violation : constraintViolations) {
        Set<Class<? extends Payload>> payloads = violation.getConstraintDescriptor().getPayload();
        for (Class<? extends Payload> payload : payloads) {
            if (payload == Severity.Error.class) {
                // logic here   
            }
        }
    }