Enterprise Java Development@TOPIC@

Chapter 52. Core Validation API

52.1. Validation Goals
52.2. Constraints
52.2.1. Annotating Class
52.2.2. Validating Instances
52.3. Constraint Groups
52.3.1. Uses
52.3.2. Defining Groups
52.3.3. Groups Applied to Classes
52.3.4. Validating with Groups
52.4. Custom Validators
52.4.1. Annotation
52.4.2. Validator
52.4.3. Annotating Class
52.4.4. Example Usage
52.5. Composite Constraints
52.5.1. Multiple Constraints
52.5.2. Replace With Composite
52.5.3. Composite Annotation
52.5.4. Composed Validations Individually Reported
52.5.5. @ReportAsSingleViolation
52.6. Group Sequences
52.6.1. Validation Groups and Sequence
52.6.2. Assign Constraints from Sequence
52.6.3. Sample Execution
52.6.4. Optionally Assign Sequence to be Default for Class
52.7. Validating Types
52.7.1. Annotation
52.7.2. Validator
52.7.3. Validator
52.8. Cascade Validation
52.8.1. Trigger Validation Cascade with @Valid
52.8.2. Validation
52.9. XML Descriptor
52.9.1. POJO Bean Class
52.9.2. META-INF/validation.xml
52.9.3. Constraint Mapping
52.10. Summary

Applied to FIELDs, METHODs, TYPEs, etc.

package ejava.jpa.example.validation;


import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.*;
import javax.validation.Constraint;
import javax.validation.Payload;
/**
 * Defines a constraint annotation for expressing a minimum age.
 */
@Documented
@Constraint(validatedBy={MinAgeValidator.class})
@Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER})
@Retention(RUNTIME)
public @interface MinAge {
    String message() default "too young";
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default{};
    int age() default 0;
}
package ejava.jpa.example.validation;

...
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
public class MinAgeValidator implements ConstraintValidator<MinAge, Date>{
    int minAge;
    @Override
    public void initialize(MinAge constraint) {
        this.minAge = constraint.age();
    }
    @Override
    public boolean isValid(Date date, ConstraintValidatorContext ctx) {
        if (date==null) { return true; }
        //get today's date
        Calendar latestBirthDate = new GregorianCalendar();
        latestBirthDate.add(Calendar.YEAR, -1*minAge);
        
        //get calendate date of object
        Calendar birthDate = new GregorianCalendar();
        birthDate.setTime(date);
        if (birthDate.after(latestBirthDate)) {
            String errorMsg = String.format("%d is younger than minimum %d", 
                    getAge(birthDate), 
                    minAge);
            ctx.buildConstraintViolationWithTemplate(errorMsg)
                .addConstraintViolation();
            return false;
        } else {
            return true;
        }
    }
    
    private int getAge(Calendar birth) {
    ...
...
}

Define a sequence of validation groups to be tested in order and short-circuit upon failure

Look across properties of type

Traverse validation across relationships

Define Constraints external to Bean Class