Table 9-2
Built-In Bean Validation Constraints
Constraint
|
Description
|
Example
|
@AssertFalse
|
The value of the field or property must be false.
|
@AssertFalse
boolean isUnsupported;
|
@AssertTrue
|
The value of the field or property must be true.
|
@AssertTrue
boolean isActive;
|
@DecimalMax
|
The value of the field or property must be a decimal value lower
than or equal to the number in the value element.
|
@DecimalMax("30.00")
BigDecimal discount;
|
@DecimalMin
|
The value of the field or property must be a decimal value
greater than or equal to the number in the value element.
|
@DecimalMin("5.00")
BigDecimal discount;
|
@Digits
|
The value of the field or property must be a number within a
specified range. The integerelement specifies the maximum
integral digits for the number, and the fraction element
specifies the maximum fractional digits for the number.
|
@Digits(integer=6, fraction=2)
BigDecimal price;
|
@Future
|
The value of the field or property must be a date in the
future.
|
@Future
Date eventDate;
|
@Max
|
The value of the field or property must be an integer value
lower than or equal to the number in the value element.
|
@Max(10)
int quantity;
|
@Min
|
The value of the field or property must be an integer value
greater than or equal to the number in the value element.
|
@Min(5)
int quantity;
|
@NotNull
|
The value of the field or property must not be null.
|
@NotNull
String username;
|
@Null
|
The value of the field or property must be null.
|
@Null
String unusedString;
|
@Past
|
The value of the field or property must be a date in the
past.
|
@Past
Date birthday;
|
@Pattern
|
The value of the field or property must match the regular
expression defined in the regexpelement.
|
@Pattern(regexp="\\(\\d{3}\\)\\d{3}-\\d{4}")
String phoneNumber;
|
@Size
|
The size of the field or property is evaluated and must match
the specified boundaries. If the field or property is
a String, the size of the string is evaluated. If the field or
property is aCollection, the size of the Collection is
evaluated. If the field or property is a Map, the size of
the Map is evaluated. If the field or property is an
array, the size of the array is evaluated. Use one of the
optional max or min elements to specify the
boundaries.
|
@Size(min=2, max=240)
String briefMessage;
|
@Valid |
yes |
field/property. Any non-primitive types are supported. |
Performs validation recursively on the associated object. If
the object is a collection or an array, the elements are validated
recursively. If the object is a map, the value elements are
validated recursively. |
none |
@CreditCardNumber |
no |
field/property. The supported type is String. |
Check that the annotated string passes the Luhn checksum test.
Note, this validation aims to check for user mistake, not credit
card validity! See also Anatomy of Credit Card Numbers. |
@Email |
no |
field/property. Needs to be a string. |
Check whether the specified string is a valid email
address. |
none
|
@Length(min=, max=) |
no |
field/property. Needs to be a string. |
Validate that the annotated string is between min and maxincluded. |
Column length will be set to max.
|
@NotBlank |
no |
field/property |
Check that the annotated string is not null and the trimmed
length is greater than 0. The difference to @NotEmpty is that this
constraint can only be applied on strings and that trailing
whitespaces are ignored. |
none |
@NotEmpty |
no |
field/property. Supported types are String, Collection, Map and
arrays. |
Check whether the annotated element is not null nor
empty. |
none |
@ScriptAssert(lang=, script=, alias=) |
no |
type |
Checks whether the given script can successfully be evaluated
against the annotated element. In order to use this constraint, an
implementation of the Java Scripting API as defined by JSR 223
("Scripting for the JavaTMPlatform") must part of the
class path. This is automatically the case when running on Java 6.
For older Java versions, the JSR 223 RI can be added manually to
the class path.The expressions to be evaluated can be written in
any scripting or expression language, for which a JSR 223
compatible engine can be found in the class path. |
none |
@URL(protocol=, host=, port=) |
no |
field/property. The supported type is String. |
Check if the annotated string is a valid URL. If any of
parametersprotocol, host or port is specified the URL must match
the specified values in the according part. |
none |
The Bean Validation API does not only allow to
validate single class instances but also complete object graphs. To
do so, just annotate a field or property representing a reference
to another object with@Valid. If the parent object is validated,
all referenced objects annotated with @Valid will be
validated as well (as will be their children etc.)
Constraints groups
On the presentation tier, it may happen that you have to use the
same form bean in two different contexts, such as create and
update. In both contexts you have different constraints. For
example, when creating your profile, the username is mandatory.
When updating, it cannot be changed so there's no need to validate
it.
Groups and Inheritance
A group can extend another group, and since groups are
interfaces a group can extend more than one group. When the
validator evaluates a specific group's constraints it also
evaluates all of its super groups (interfaces) constraints. So
actually a better way to configure the Book bean validation groups
would have been as illustrated bellow:
public interface BookLifeCycle extends Default {}
public interface Draft extends BookLifeCycle{}
public interface Printing extends Draft{}
Validating a Bean based on its Life Cycle Phase
A nice pattern, or structure, is when the bean announces
its own lifecycle phase - for that reason I added the BookLifeCycle
interface, by adding to the bean a reference to its own life cycle
phase we can use it to validate the bean:
GroupSequence
To control the order in which groups are validated the
@GroupSequence annotation can be used.
@GroupSequence({Default.class, Draft.class, Printing.class})
public interface BookOrderedValidation {}
Multiple Instances of the Same Constraints
we would like a string property to either be in pattern A
or B.
@Pattern.List( {@Pattern(regexp="A.*"), @Pattern(regexp="B.*")} )
private String title;
Different Constraint Configurations per Group
Using the inner List annotation one can also apply different
constraint configurations for each validation group.
@Min.List( { @Min(value = 100, groups = Printing.class), @Min(value = 5, groups = Draft.class) })
private int numOfPages;
Custome Bean Validator - Comparing 2 fields on one class
There doesn't seem to be a way to access other values from
an object when validating one of its properties. The solution is to
put the annotation on the class, then the validator will get the
entire object in to validate against, and you can access just the
info you need to perform the validation.
PayLoad
an attribute payload that can be used by clients of
the Bean Validation API to asign custom payload objects to a
constraint. This attribute is not used by the API itself.
public class Severity {
public static class Info extends ConstraintPayload {};
public static class Error extends ConstraintPayload {};
}
public class ContactDetails {
@NotNull(message="Name is mandatory", payload=Severity.Error.class)
private String name;
@NotNull(message="Phone number not specified, but not mandatory", payload=Severity.Info.class)
private String phoneNumber;
// ...
}
Now a client can after the validation of a ContactDetails instance access the severity of a constraint using ConstraintViolation.getConstraintDescriptor().getPayload() and adjust its behaviour depending on the severity.