Search code examples
javavalidationbean-validationvalidationrules

How to java bean validate range only if not null or zero


I would like to use Java Bean Validation to validate an Integer. It is a validation of multiple validations.

I'm currently using Spring Boot and validation, and system is using a @RestController where I'm receiving the post-call.

public Person addPerson(@RequestBody @Validated Person Person) {/*the code*/}

I would like the age to be validated, where these values are valid:

age == null or age == 0 or (age >= 15 and age <= 80)


public class Person {
    private Integer age;
}

I would like to be able to use the current validation constraints of java. Do I need to implement my own constraint annotation ?

This would be nice, but this does not work:

public class Person {
    @Null
    @Range(min=0, max=0)
    @Range(min=15, max = 80)
    private Integer age;
}

Solution

  • You can group build in constraints using ConstraintCoposition:

    public class Test {
    
        private static ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
    
        @ConstraintComposition(CompositionType.AND)
        @Min(value = 0)
        @Max(value = 0)
        @Target( { ElementType.ANNOTATION_TYPE } )
        @Retention( RetentionPolicy.RUNTIME )
        @Constraint(validatedBy = { })
        public @interface ZeroComposite {
            String message() default "Not valid";
            Class<?>[] groups() default { };
            Class< ? extends Payload>[] payload() default { };
        }
    
        @ConstraintComposition(CompositionType.OR)
        @Null
        @ZeroComposite
        @Range(min=15, max = 80)
        @Target( { ElementType.METHOD, ElementType.FIELD } )
        @Retention( RetentionPolicy.RUNTIME )
        @Constraint(validatedBy = { })
        public @interface Composite {
            String message() default "Not valid";
            Class<?>[] groups() default { };
            Class< ? extends Payload>[] payload() default { };
        }
    
        @Composite
        private Integer age;
    
    
        public Test(Integer age) {
            this.age = age;
        }
    
        public static void main(String args[]) {
            validate(new Test(-1));
            validate(new Test(null));
            validate(new Test(0));
            validate(new Test(5));
            validate(new Test(15));
            validate(new Test(80));
            validate(new Test(81));
        }
    
        private static void validate(Test t) {
            Set<ConstraintViolation<Test>> violations = 
                factory.getValidator().validate(t);
    
            for (ConstraintViolation<Test> cv : violations) {
                System.out.println(cv.toString());
            }
        }
    }