Ce contenu n'est pas disponible dans la langue sélectionnée.
Chapter 14. Bean Validation
14.1. About Bean Validation Copier lienLien copié sur presse-papiers!
Bean Validation, or JavaBeans Validation, is a model for validating data in Java objects. The model uses built-in and custom annotation constraints to ensure the integrity of application data. The specification is documented here: JSR 349: Bean Validation 1.1.
Hibernate Validator is the JBoss EAP implementation of Bean Validation. It is also the reference implementation of the JSR.
JBoss EAP is 100% compliant with JSR 349 Bean Validation 1.1 specification. Hibernate Validator also provides additional features to the specification.
To get started with Bean Validation, see the bean-validation quickstart that ships with JBoss EAP. For information about how to download and run the quickstarts, see Using the Quickstart Examples.
14.2. Validation Constraints Copier lienLien copié sur presse-papiers!
14.2.1. About Validation Constraints Copier lienLien copié sur presse-papiers!
Validation constraints are rules applied to a Java element, such as a field, property or bean. A constraint will usually have a set of attributes used to set its limits. There are predefined constraints, and custom ones can be created. Each constraint is expressed in the form of an annotation.
The built-in validation constraints for Hibernate Validator are listed here: Hibernate Validator Constraints.
14.2.2. Hibernate Validator Constraints Copier lienLien copié sur presse-papiers!
When applicable, the application-level constraints lead to creation of database-level constraints that are described in the Hibernate Metadata Impact column in the table below.
Java-specific Validation Constraints
The following table includes validation constraints defined in the Java specifications, which are included in the javax.validation.constraints package.
| Annotation | Property type | Runtime checking | Hibernate Metadata impact |
|---|---|---|---|
|
| Boolean | Check that the method evaluates to false. Useful for constraints expressed in code rather than annotations. | None. |
|
| Boolean | Check that the method evaluates to true. Useful for constraints expressed in code rather than annotations. | None. |
|
| Numeric or string representation of a numeric |
Check whether the property is a number having up to | Define column precision and scale. |
|
| Date or calendar | Check if the date is in the future. | None. |
|
| Numeric or string representation of a numeric | Check if the value is less than or equal to max. | Add a check constraint on the column. |
|
| Numeric or string representation of a numeric | Check if the value is more than or equal to Min. | Add a check constraint on the column. |
|
| Check if the value is not null. | Column(s) are not null. | |
|
| Date or calendar | Check if the date is in the past. | Add a check constraint on the column. |
|
| String |
Check if the property matches the regular expression given a match flag. See | None. |
|
| Array, collection, map | Check if the element size is between min and max, both values included. | None. |
|
| Object | Perform 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. |
The parameter @Valid is a part of the Bean Validation specification, even though it is located in the javax.validation.constraints package.
Hibernate Validator-specific Validation Constraints
The following table includes vendor-specific validation constraints, which are a part of the org.hibernate.validator.constraints package.
| Annotation | Property type | Runtime checking | Hibernate Metadata impact |
|---|---|---|---|
|
| String | Check if the string length matches the range. | Column length will be set to max. |
|
| String | Check whether the string is a well formatted credit card number, derivative of the Luhn algorithm. | None. |
|
| String | Check whether the string is a properly formatted EAN or UPC-A code. | None. |
|
| String | Check whether the string is conform to the e-mail address specification. | None. |
|
| Check if the string is not null nor empty. Check if the connection is not null nor empty. | Columns are not null for String. | |
|
| Numeric or string representation of a numeric | Check if the value is between min and max, both values included. | Add a check constraint on the column. |
14.2.3. Bean Validation Using Custom Constraints Copier lienLien copié sur presse-papiers!
Bean Validation API defines a set of standard constraint annotations, such as @NotNull, @Size, and so on. However, in cases where these predefined constraints are not sufficient, you can easily create custom constraints tailored to your specific validation requirements.
Creating a Bean Validation custom constraint requires that you create a constraint annotation and implement a constraint validator. The following abbreviated code examples are taken from the bean-validation-custom-constraint quickstart that ships with JBoss EAP. See that quickstart for a complete working example.
14.2.3.1. Creating A Constraint Annotation Copier lienLien copié sur presse-papiers!
The following example shows the personAddress field of entity Person is validated using a set of custom constraints defined in the class AddressValidator.
Create the entity
PersonExample:
PersonClasspackage org.jboss.as.quickstarts.bean_validation_custom_constraint; @Entity @Table(name = "person") public class Person implements Serializable { private static final long serialVersionUID = 1L; @Id @GeneratedValue @Column(name = "person_id") private Long personId; @NotNull @Size(min = 4) private String firstName; @NotNull @Size(min = 4) private String lastName; // Custom Constraint @Address for bean validation @NotNull @Address @OneToOne(mappedBy = "person", cascade = CascadeType.ALL) private PersonAddress personAddress; public Person() { } public Person(String firstName, String lastName, PersonAddress address) { this.firstName = firstName; this.lastName = lastName; this.personAddress = address; } /* getters and setters omitted for brevity*/ }Create the constraint validator files:
Example:
AddressInterfacepackage org.jboss.as.quickstarts.bean_validation_custom_constraint; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import javax.validation.Constraint; import javax.validation.Payload; // Linking the AddressValidator class with @Address annotation. @Constraint(validatedBy = { AddressValidator.class }) // This constraint annotation can be used only on fields and method parameters. @Target({ ElementType.FIELD, ElementType.PARAMETER }) @Retention(value = RetentionPolicy.RUNTIME) @Documented public @interface Address { // The message to return when the instance of MyAddress fails the validation. String message() default "Address Fields must not be null/empty and obey character limit constraints"; Class<?>[] groups() default {}; Class<? extends Payload>[] payload() default {}; }Example:
PersonAddressClasspackage org.jboss.as.quickstarts.bean_validation_custom_constraint; import java.io.Serializable; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.OneToOne; import javax.persistence.PrimaryKeyJoinColumn; import javax.persistence.Table; @Entity @Table(name = "person_address") public class PersonAddress implements Serializable { private static final long serialVersionUID = 1L; @Id @Column(name = "person_id", unique = true, nullable = false) @GeneratedValue(strategy = GenerationType.SEQUENCE) private Long personId; private String streetAddress; private String locality; private String city; private String state; private String country; private String pinCode; @OneToOne @PrimaryKeyJoinColumn private Person person; public PersonAddress() { } public PersonAddress(String streetAddress, String locality, String city, String state, String country, String pinCode) { this.streetAddress = streetAddress; this.locality = locality; this.city = city; this.state = state; this.country = country; this.pinCode = pinCode; } /* getters and setters omitted for brevity*/ }
14.2.3.2. Implementing A Constraint Validator Copier lienLien copié sur presse-papiers!
Having defined the annotation, you need to create a constraint validator that is able to validate elements with an @Address annotation. To do so, implement the interface ConstraintValidator as shown below:
Example: AddressValidator Class
package org.jboss.as.quickstarts.bean_validation_custom_constraint;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import org.jboss.as.quickstarts.bean_validation_custom_constraint.PersonAddress;
public class AddressValidator implements ConstraintValidator<Address, PersonAddress> {
public void initialize(Address constraintAnnotation) {
}
/**
* 1. A null address is handled by the @NotNull constraint on the @Address.
* 2. The address should have all the data values specified.
* 3. Pin code in the address should be of at least 6 characters.
* 4. The country in the address should be of at least 4 characters.
*/
public boolean isValid(PersonAddress value, ConstraintValidatorContext context) {
if (value == null) {
return true;
}
if (value.getCity() == null || value.getCountry() == null || value.getLocality() == null
|| value.getPinCode() == null || value.getState() == null || value.getStreetAddress() == null) {
return false;
}
if (value.getCity().isEmpty()
|| value.getCountry().isEmpty() || value.getLocality().isEmpty()
|| value.getPinCode().isEmpty() || value.getState().isEmpty() || value.getStreetAddress().isEmpty()) {
return false;
}
if (value.getPinCode().length() < 6) {
return false;
}
if (value.getCountry().length() < 4) {
return false;
}
return true;
}
}
14.3. Validation Configuration Copier lienLien copié sur presse-papiers!
You can configure bean validation using XML descriptors in the validation.xml file located in the /META-INF directory. If this file exists in the class path, its configuration is applied when the ValidatorFactory gets created.
Example: Validation Configuration File
The following example shows several configuration options of the validation.xml file. All the settings are optional. These options can also be configured using the javax.validation package.
<validation-config xmlns="http://jboss.org/xml/ns/javax/validation/configuration"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://jboss.org/xml/ns/javax/validation/configuration">
<default-provider>
org.hibernate.validator.HibernateValidator
</default-provider>
<message-interpolator>
org.hibernate.validator.messageinterpolation.ResourceBundleMessageInterpolator
</message-interpolator>
<constraint-validator-factory>
org.hibernate.validator.engine.ConstraintValidatorFactoryImpl
</constraint-validator-factory>
<constraint-mapping>
/constraints-example.xml
</constraint-mapping>
<property name="prop1">value1</property>
<property name="prop2">value2</property>
</validation-config>
The node default-provider allows to choose the bean validation provider. This is useful if there is more than one provider on the classpath. The message-interpolator and constraint-validator-factory properties are used to customize the used implementations for the interfaces MessageInterpolator and ConstraintValidatorFactory, which are defined in the javax.validation package. The constraint-mapping element lists additional XML files containing the actual constraint configuration.