Java Platform, Enterprise Edition (Java EE) 8 The Java EE Tutorial

## Using Bean Validation Constraints

The Bean Validation model is supported by constraints in the form of annotations placed on a field, method, or class of a JavaBeans component, such as a managed bean.

Constraints can be built in or user defined. User-defined constraints are called custom constraints. Several built-in constraints are available in the `javax.validation.constraints` package. Table 23-1 lists all the built-in constraints. See Creating Custom Constraints for information on creating custom constraints.

Table 23-1 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 `integer` element 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;
`@Email` | The value of the field or property must be a valid email address. |
    @Email
    String emailaddress;
`@Future` | The value of the field or property must be a date in the future. |
    @Future
    Date eventDate;
`@FutureOrPresent` | TThe value of the field or property must be a date or time in present or future. |
    @FutureOrPresent
    Time travelTime;
`@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;
`@Negative` | The value of the field or property must be a negative number. |
    @Negative
    int basementFloor;
`@NegativeOrZero` | The value of the field or property must be negative or zero. |
    @NegativeOrZero
    int debtValue;
`@NotBlank` | The value of the field or property must contain atleast one non-white space character. |
    @NotBlank
    String message;
`@NotEmpty` | The value of the field or property must not be empty. The length of the characters or array, and the size of a collection or map are evaluated. |
    @NotEmpty
    String message;;
`@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;
`@PastOrPresent` | The value of the field or property must be a date or time in the past or present. |
    @PastOrPresent
    Date travelDate;
`@Pattern` | The value of the field or property must match the regular expression defined in the `regexp` element. |
    @Pattern(regexp="\\(\\d{3}\\)\\d{3}-\\d{4}")
    String phoneNumber;
`@Positive` | The value of the field or property must be a positive number. |
    @Positive
    BigDecimal area;
`@PositiveOrZero` | The value of the field or property must be a positive number or zero. . |
    @PositiveOrZero
    int totalGoals;
`@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 a `Collection`, 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;

In the following example, a constraint is placed on a field using the built-in `@NotNull` constraint:

    public class Name {
        @NotNull
        private String firstname;

        @NotNull
        private String lastname;
        ...
    }

You can also place more than one constraint on a single JavaBeans component object. For example, you can place an additional constraint for size of field on the `firstname` and the `lastname` fields:

    public class Name {
        @NotNull
        @Size(min=1, max=16)
        private String firstname;

        @NotNull
        @Size(min=1, max=16)
        private String lastname;
        ...
    }

The following example shows a method with a user-defined constraint that checks user-defined constraint that checks for a predefined phone number pattern, such as a country specific phone number:

    @USPhoneNumber
    public String getPhone() {
        return phone;
    }

For a built-in constraint, a default implementation is available. A user-defined or custom constraint needs a validation implementation. In the preceding example, the `@USPhoneNumber` custom constraint needs an implementation class.

## Repeating Annotations

In Bean Validation 2.0, you can specify the same constraint several times on a validation target using repeating annotation:

    public class Account {

        @Max (value = 2000, groups = Default.class, message = "max.value")
        @Max (value = 5000, groups = GoldCustomer.class, message = "max.value")
        private long withdrawalAmount;
    }

All in-built constraints from `javax .validation.constraints` package support repeatable annotations. Similarly, custom constraints can use `@Repeatable` annotation. In the following sample, depending on whether the group is `PeakHour` or `NonPeakHour`, the car instance is validated as either two passengers or three passengers based car, and then listed as eligible in the car pool lane:

    /**
     * Validate whether a car is eligible for car pool lane
     */
    @Documented
    @Constraint(validatedBy = CarPoolValidator.class)
    @Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE })
    @Retention(RUNTIME)
    @Repeatable(List.class)
    public @interface CarPool {

        String message() default "{CarPool.message}";

        Class<?>[] groups() default {};

        int value();

        Class<? extends Payload>[] payload() default {};

        /**
         * Defines several @CarPool annotations on the same element
         * @see (@link CarPool}
         */
        @Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE })
        @Retention(RUNTIME)
        @Documented
        @interface List {
            CarPool[] value();
        }
    }
    public class Car{

      private String registrationNumber;

      @CarPool(value = 2, group = NonPeakHour.class)
      @CarPool(value = 3, group = {Default.class, PeakHour.class})
      private int totalPassengers;
    }

Any validation failures are gracefully handled and can be displayed by the `h:messages` tag.

Any managed bean that contains Bean Validation annotations automatically gets validation constraints placed on the fields on a JavaServer Faces application’s web pages.

For more information on using validation constraints, see the following:

- Chapter 24, "Bean Validation: Advanced Topics"

- Validating Resource Data with Bean Validation

- Validating Persistent Fields and Properties

Copyright © 2017, Oracle and/or its affiliates. All rights reserved.