Jakarta Validation API defines a metadata model and API for JavaBean and method validation
—
Comprehensive set of pre-defined constraint annotations for common validation scenarios including null checks, size validation, numeric ranges, date/time validation, and format validation.
Constraints for validating null and non-null values.
/**
* The annotated element must not be null
* Accepts any type
*/
@Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE})
@Retention(RUNTIME)
@Constraint(validatedBy = {})
@interface NotNull {
String message() default "{jakarta.validation.constraints.NotNull.message}";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
@Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE})
@Retention(RUNTIME)
@interface List {
NotNull[] value();
}
}
/**
* The annotated element must be null
* Accepts any type
*/
@Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE})
@Retention(RUNTIME)
@Constraint(validatedBy = {})
@interface Null {
String message() default "{jakarta.validation.constraints.Null.message}";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
@Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE})
@Retention(RUNTIME)
@interface List {
Null[] value();
}
}Usage Examples:
class User {
@NotNull
private String username; // Cannot be null
@Null
private String reserved; // Must be null
}Constraints for validating strings, collections, arrays, and maps.
/**
* The annotated element must not be null and must contain at least one non-whitespace character
* Supported types: CharSequence
*/
@Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE})
@Retention(RUNTIME)
@Constraint(validatedBy = {})
@interface NotBlank {
String message() default "{jakarta.validation.constraints.NotBlank.message}";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
@Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE})
@Retention(RUNTIME)
@interface List {
NotBlank[] value();
}
}
/**
* The annotated element must not be null and not empty
* Supported types: CharSequence, Collection, Map, Array
*/
@Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE})
@Retention(RUNTIME)
@Constraint(validatedBy = {})
@interface NotEmpty {
String message() default "{jakarta.validation.constraints.NotEmpty.message}";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
@Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE})
@Retention(RUNTIME)
@interface List {
NotEmpty[] value();
}
}
/**
* The annotated element size must be between the specified boundaries (inclusive)
* Supported types: CharSequence, Collection, Map, Array
*/
@Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE})
@Retention(RUNTIME)
@Constraint(validatedBy = {})
@interface Size {
String message() default "{jakarta.validation.constraints.Size.message}";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
/**
* Size must be higher or equal to
* @return minimum size (inclusive)
*/
int min() default 0;
/**
* Size must be lower or equal to
* @return maximum size (inclusive)
*/
int max() default Integer.MAX_VALUE;
@Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE})
@Retention(RUNTIME)
@interface List {
Size[] value();
}
}Usage Examples:
class ValidationExamples {
@NotBlank
private String username; // Not null, not empty, not just whitespace
@NotEmpty
private List<String> items; // Not null and not empty
@Size(min = 2, max = 50)
private String name; // Length between 2 and 50 characters
@Size(max = 10)
private List<Item> itemList; // At most 10 items
}Constraints for validating numeric values and ranges.
/**
* The annotated element must be greater than or equal to the specified minimum
* Supported types: BigDecimal, BigInteger, CharSequence, byte, short, int, long and their wrappers
*/
@Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE})
@Retention(RUNTIME)
@Constraint(validatedBy = {})
@interface Min {
String message() default "{jakarta.validation.constraints.Min.message}";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
/**
* The minimum value (inclusive)
* @return minimum value
*/
long value();
@Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE})
@Retention(RUNTIME)
@interface List {
Min[] value();
}
}
/**
* The annotated element must be less than or equal to the specified maximum
* Supported types: BigDecimal, BigInteger, CharSequence, byte, short, int, long and their wrappers
*/
@Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE})
@Retention(RUNTIME)
@Constraint(validatedBy = {})
@interface Max {
String message() default "{jakarta.validation.constraints.Max.message}";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
/**
* The maximum value (inclusive)
* @return maximum value
*/
long value();
@Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE})
@Retention(RUNTIME)
@interface List {
Max[] value();
}
}
/**
* The annotated element must be greater than or equal to the specified minimum (supports decimal precision)
* Supported types: BigDecimal, BigInteger, CharSequence, byte, short, int, long and their wrappers
*/
@Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE})
@Retention(RUNTIME)
@Constraint(validatedBy = {})
@interface DecimalMin {
String message() default "{jakarta.validation.constraints.DecimalMin.message}";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
/**
* The string representation of the minimum value
* @return minimum value as string
*/
String value();
/**
* Whether the specified minimum is inclusive or exclusive
* @return true for inclusive, false for exclusive
*/
boolean inclusive() default true;
@Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE})
@Retention(RUNTIME)
@interface List {
DecimalMin[] value();
}
}
/**
* The annotated element must be less than or equal to the specified maximum (supports decimal precision)
* Supported types: BigDecimal, BigInteger, CharSequence, byte, short, int, long and their wrappers
*/
@Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE})
@Retention(RUNTIME)
@Constraint(validatedBy = {})
@interface DecimalMax {
String message() default "{jakarta.validation.constraints.DecimalMax.message}";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
/**
* The string representation of the maximum value
* @return maximum value as string
*/
String value();
/**
* Whether the specified maximum is inclusive or exclusive
* @return true for inclusive, false for exclusive
*/
boolean inclusive() default true;
@Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE})
@Retention(RUNTIME)
@interface List {
DecimalMax[] value();
}
}
/**
* The annotated element must be a strictly positive number (greater than 0)
* Supported types: BigDecimal, BigInteger, CharSequence, byte, short, int, long, float, double and their wrappers
*/
@Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE})
@Retention(RUNTIME)
@Constraint(validatedBy = {})
@interface Positive {
String message() default "{jakarta.validation.constraints.Positive.message}";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
@Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE})
@Retention(RUNTIME)
@interface List {
Positive[] value();
}
}
/**
* The annotated element must be a positive number or zero
* Supported types: BigDecimal, BigInteger, CharSequence, byte, short, int, long, float, double and their wrappers
*/
@Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE})
@Retention(RUNTIME)
@Constraint(validatedBy = {})
@interface PositiveOrZero {
String message() default "{jakarta.validation.constraints.PositiveOrZero.message}";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
@Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE})
@Retention(RUNTIME)
@interface List {
PositiveOrZero[] value();
}
}
/**
* The annotated element must be a strictly negative number (less than 0)
* Supported types: BigDecimal, BigInteger, CharSequence, byte, short, int, long, float, double and their wrappers
*/
@Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE})
@Retention(RUNTIME)
@Constraint(validatedBy = {})
@interface Negative {
String message() default "{jakarta.validation.constraints.Negative.message}";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
@Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE})
@Retention(RUNTIME)
@interface List {
Negative[] value();
}
}
/**
* The annotated element must be a negative number or zero
* Supported types: BigDecimal, BigInteger, CharSequence, byte, short, int, long, float, double and their wrappers
*/
@Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE})
@Retention(RUNTIME)
@Constraint(validatedBy = {})
@interface NegativeOrZero {
String message() default "{jakarta.validation.constraints.NegativeOrZero.message}";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
@Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE})
@Retention(RUNTIME)
@interface List {
NegativeOrZero[] value();
}
}
/**
* The annotated element must be a number within accepted range
* Supported types: BigDecimal, BigInteger, CharSequence, byte, short, int, long and their wrappers
*/
@Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE})
@Retention(RUNTIME)
@Constraint(validatedBy = {})
@interface Digits {
String message() default "{jakarta.validation.constraints.Digits.message}";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
/**
* Maximum number of integral digits accepted for this number
* @return maximum integral digits
*/
int integer();
/**
* Maximum number of fractional digits accepted for this number
* @return maximum fractional digits
*/
int fraction();
@Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE})
@Retention(RUNTIME)
@interface List {
Digits[] value();
}
}Usage Examples:
class Product {
@Min(1)
private int quantity; // At least 1
@Max(100)
private int maxUsers; // At most 100
@DecimalMin("0.01")
@DecimalMax("999999.99")
private BigDecimal price; // Between 0.01 and 999999.99
@Positive
private Double rating; // Must be > 0
@PositiveOrZero
private int score; // Must be >= 0
@Digits(integer = 6, fraction = 2)
private BigDecimal amount; // Max 6 digits before decimal, 2 after
}Constraints for validating boolean values.
/**
* The annotated element must be true
* Supported types: boolean, Boolean
*/
@Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE})
@Retention(RUNTIME)
@Constraint(validatedBy = {})
@interface AssertTrue {
String message() default "{jakarta.validation.constraints.AssertTrue.message}";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
@Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE})
@Retention(RUNTIME)
@interface List {
AssertTrue[] value();
}
}
/**
* The annotated element must be false
* Supported types: boolean, Boolean
*/
@Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE})
@Retention(RUNTIME)
@Constraint(validatedBy = {})
@interface AssertFalse {
String message() default "{jakarta.validation.constraints.AssertFalse.message}";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
@Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE})
@Retention(RUNTIME)
@interface List {
AssertFalse[] value();
}
}Constraints for validating temporal values.
/**
* The annotated element must be a date in the past
* Supported types: Date, Calendar, Instant, LocalDate, LocalDateTime, LocalTime, MonthDay, OffsetDateTime, OffsetTime, Year, YearMonth, ZonedDateTime, HijrahDate, JapaneseDate, MinguoDate, ThaiBuddhistDate
*/
@Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE})
@Retention(RUNTIME)
@Constraint(validatedBy = {})
@interface Past {
String message() default "{jakarta.validation.constraints.Past.message}";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
@Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE})
@Retention(RUNTIME)
@interface List {
Past[] value();
}
}
/**
* The annotated element must be a date in the past or in the present
* Supported types: Date, Calendar, Instant, LocalDate, LocalDateTime, LocalTime, MonthDay, OffsetDateTime, OffsetTime, Year, YearMonth, ZonedDateTime, HijrahDate, JapaneseDate, MinguoDate, ThaiBuddhistDate
*/
@Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE})
@Retention(RUNTIME)
@Constraint(validatedBy = {})
@interface PastOrPresent {
String message() default "{jakarta.validation.constraints.PastOrPresent.message}";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
@Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE})
@Retention(RUNTIME)
@interface List {
PastOrPresent[] value();
}
}
/**
* The annotated element must be a date in the future
* Supported types: Date, Calendar, Instant, LocalDate, LocalDateTime, LocalTime, MonthDay, OffsetDateTime, OffsetTime, Year, YearMonth, ZonedDateTime, HijrahDate, JapaneseDate, MinguoDate, ThaiBuddhistDate
*/
@Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE})
@Retention(RUNTIME)
@Constraint(validatedBy = {})
@interface Future {
String message() default "{jakarta.validation.constraints.Future.message}";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
@Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE})
@Retention(RUNTIME)
@interface List {
Future[] value();
}
}
/**
* The annotated element must be a date in the future or in the present
* Supported types: Date, Calendar, Instant, LocalDate, LocalDateTime, LocalTime, MonthDay, OffsetDateTime, OffsetTime, Year, YearMonth, ZonedDateTime, HijrahDate, JapaneseDate, MinguoDate, ThaiBuddhistDate
*/
@Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE})
@Retention(RUNTIME)
@Constraint(validatedBy = {})
@interface FutureOrPresent {
String message() default "{jakarta.validation.constraints.FutureOrPresent.message}";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
@Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE})
@Retention(RUNTIME)
@interface List {
FutureOrPresent[] value();
}
}Usage Examples:
import java.time.LocalDate;
import java.time.LocalDateTime;
class Event {
@AssertTrue
private boolean isActive; // Must be true
@AssertFalse
private boolean isDeleted; // Must be false
@Past
private LocalDate createdDate; // Must be in the past
@Future
private LocalDateTime eventDate; // Must be in the future
@PastOrPresent
private LocalDate lastModified; // Past or present
}Constraints for validating string formats and patterns.
/**
* The annotated CharSequence must match the specified regular expression
* Supported types: CharSequence
*/
@Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE})
@Retention(RUNTIME)
@Constraint(validatedBy = {})
@interface Pattern {
String message() default "{jakarta.validation.constraints.Pattern.message}";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
/**
* The regular expression to match
* @return regular expression
*/
String regexp();
/**
* Array of Flag enums defining regex behavior
* @return regex flags
*/
Flag[] flags() default {};
/**
* Possible flags for Pattern constraint
*/
enum Flag {
UNIX_LINES(Pattern.UNIX_LINES),
CASE_INSENSITIVE(Pattern.CASE_INSENSITIVE),
COMMENTS(Pattern.COMMENTS),
MULTILINE(Pattern.MULTILINE),
DOTALL(Pattern.DOTALL),
UNICODE_CASE(Pattern.UNICODE_CASE),
CANON_EQ(Pattern.CANON_EQ);
private final int value;
Flag(int value) {
this.value = value;
}
public int getValue() {
return value;
}
}
@Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE})
@Retention(RUNTIME)
@interface List {
Pattern[] value();
}
}
/**
* The annotated element must be a well-formed email address
* Supported types: CharSequence
*/
@Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE})
@Retention(RUNTIME)
@Constraint(validatedBy = {})
@interface Email {
String message() default "{jakarta.validation.constraints.Email.message}";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
/**
* Regular expression to match email format (optional override)
* @return email regex pattern
*/
String regexp() default ".*";
/**
* Array of Flag enums for regex behavior (optional)
* @return regex flags
*/
Pattern.Flag[] flags() default {};
@Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE})
@Retention(RUNTIME)
@interface List {
Email[] value();
}
}Usage Examples:
class UserData {
@Email
private String email; // Valid email format
@Pattern(regexp = "^[A-Za-z0-9]+$")
private String username; // Alphanumeric only
@Pattern(regexp = "\\d{3}-\\d{3}-\\d{4}")
private String phoneNumber; // Format: 123-456-7890
@Pattern(regexp = "^(?=.*[A-Z])(?=.*[a-z])(?=.*\\d).{8,}$",
flags = {Pattern.Flag.MULTILINE})
private String password; // Strong password pattern
}Install with Tessl CLI
npx tessl i tessl/maven-jakarta-validation--jakarta-validation-api