Enterprise Java Development@TOPIC@

Chapter 1. Core Validation API

1.1. Validation Goals
1.2. Constraints
1.2.1. Annotating Class
1.2.2. Validating Instances
1.3. Constraint Groups
1.3.1. Uses
1.3.2. Defining Groups
1.3.3. Groups Applied to Classes
1.3.4. Validating with Groups
1.4. Custom Validators
1.4.1. Annotation
1.4.2. Validator
1.4.3. Annotating Class
1.4.4. Example Usage
1.5. Composite Constraints
1.5.1. Multiple Constraints
1.5.2. Replace With Composite
1.5.3. Composite Annotation
1.5.4. Composed Validations Individually Reported
1.5.5. @ReportAsSingleViolation
1.6. Group Sequences
1.6.1. Validation Groups and Sequence
1.6.2. Assign Constraints from Sequence
1.6.3. Sample Execution
1.6.4. Optionally Assign Sequence to be Default for Class
1.7. Validating Types
1.7.1. Annotation
1.7.2. Validator
1.7.3. Validator
1.8. Cascade Validation
1.8.1. Trigger Validation Cascade with @Valid
1.8.2. Validation
1.9. XML Descriptor
1.9.1. POJO Bean Class
1.9.2. META-INF/validation.xml
1.9.3. Constraint Mapping
1.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