From the course: Java EE: Bean Validation

Built-in constraints introduction

From the course: Java EE: Bean Validation

Start my 1-month free trial

Built-in constraints introduction

- [Instructor] The Bean Validation API comes equipped with a range of very useful constraints that we can use to ensure the integrity of our data as it moves through the application. Validation constraints are defined as annotations and mark classes, fields, methods, parameters, constructors, and return values. Validation triggers automatically when used in combination with other Java EE technology such as JSF backing beans, EJBs, JAX-RS REST endpoints, and JPA. When used in Java SE or in parts of Java EE that do not benefit from Bean Validation integration, then validation can be provoked manually. This is done by either injecting an instance of the Validator class from the javax.validation package if you are developing in a CDI-enabled environment or by constructing the Bootstrap validation code yourself. You will learn both manual and automatic validation during this course. All the built-in Bean Validation constraints are defined in the javax.validation.constraints package. They total 22 and fall into three rather broad categories. Those that check for existence or none existence, those that constrain on numerical values, and miscellaneous groups that include pattern matching, dates, and Boolean. The constraints that check for existence or none existence of values or null values are @NotNull, @Null, @NotEmpty, and @NotBlank. Those that constrain on numerical values or are numerical in nature are @DecimalMax and @DecimalMin, @Digits, @Max and @Min, @Negative, @NegativeOrZero, @Positive, and @PositiveOrZero, and @Size. And in the miscellaneous group is @AssertFalse and @AssertTrue, @Future, @FutureOrPresent, @Past, @PastOrPresent, @Pattern, and @Email. I will be talking about what each of these constraints do later on in the course, however, as you can see, the developers of the API have given them quite logical names, so you ought to be able to make a reasonable guess about the function of each one. Many of these constraint annotations can be specially configured for the specific use case you are constraining. This is done by passing metadata to the annotation. So, an example of this would be the @Min constraint annotation. This constraint ensures that any numerical field it marks has a value of at least the value passed to the @Min annotation. As you can see, in this case, the value of the age field must be 18 or greater. Constraints can be used together to build more complex constraint logic. For example, it is quite common to combine @NotNull with other constraints because not all constraints check for null values. Consider this example. The null value of the dob field will not cause a constraint violation exception even though it is obvious to us that the data's not valid. To solve this, add the @NotNull annotation to the dob field to ensure that the data is checked for being not null. Now the field value will be protected from nulls and dates in the past. Constraints can also accept optional parameters that further refine their behavior. For example, the @DecimalMin constraint has two parameters that affect its behavior, the compulsory value parameter which sets the minimum value that a decimal value can be and the optional inclusive flag that takes a Boolean value that, when set to true, means that the field's value can include the minimum value set. You might be wondering what happens if a validation constraint detects that a violation has occurred. Well, as you might expect, it throws an exception. It throws a ConstraintViolationException containing a message about the constraint violation and configured with the details of what caused the violation failure. The details of how to handle validation failures, setting messages and representing them to the end user is dealt with in a later chapter, however, for now, just know that once a validation exception is thrown, validation continues until all the constraints have been executed and all validation exceptions are returned. Bean Validation annotations can be used to ensure data integrity throughout the bean and not just on fields. They can mark constraints, methods, and method parameters. When they are placed on a method, they validate the return value. Commonly they are used on fields, but when used on methods and method parameters, they help you adopt a programming to contract style. You have already learned that validation is automatically triggered when used with APIs that integrate Bean Validation, but what if you use it where this feature is not available, such as in the Java SE application or in a unit test? You have to provoke the Bean Validation manually by creating an instance of the Validator from the ValidatorFactory. Then the instance of the POJO you want to validate is passed to the validate method. Validation occurs and any constraint validations are expressed as validation exceptions in the return set of constraints. The code you see here is an example of how this might look. Once this code is executed, you would then test the size of the set, and if the size is zero, no validation exceptions had occurred. I will be using this code many times to write unit tests to quickly test the code before deploying it to the server.

Contents