How to customize request validation in Spring boot using Java Bean Validation
By: Rodolfo Rojas Segura
Tags: Programming, Spring Boot, Java, Bean Validation

Prerequisites

Hibernate Validator is an official Java Bean Validation implementation and will give us the ability to integrate and extends the Validation functionality.

<dependency>

<groupId>org.hibernate</groupId>

<artifactId>hibernate-validator</artifactId>

<version>6.1.6.Final</version>

</dependency>

Expression Language is required in order to use the interpolation in the validation messages

<dependency>

<groupId>javax.el</groupId>

<artifactId>el-api</artifactId>

<version>2.2</version>

</dependency>

Spring Web

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-web</artifactId>

</dependency>

Creating Custom Constrains

Java bean validation and some implementors come with a list of built-in constraints that you can take leverage to validate a bean at any application layer, however, there are cases where those constraints don’t fill our validation needs. The Bean Validation specification gives us the ability to create custom constraints that meets our requirements.

Let’s create a custom Constratin annotation that prevents the use of certain first names

The validator uses for this constraint, will perform the actual validation and do some additional work on the generation of the message if needed.

2. This is a required field, used to constraint grouping. This is not needed for this tutorial.

3. This is a required field, used to create the Payload and set the severity level for the constraint, this is not used by this validator.

Validator

The validator should extend from ConstraintValidator. Initializes the validator with any required data set in the Constraint annotation. this method is guaranteed to be called before any method in the Validator class. The method performs the actual validation, for sake of simplicity the isValid performs a simple validation checking the value of the field is not contained in the not notAllowValues attribute.

NOTE: Spring scans for all the classes that extend from ConstraintValidator, and load them in the context as validators, also given this we can inject and access other beans as we normally access in other beans.

Using the New Constraint

Here we’re using the custom constraint NotContains to prevent the use of some firstName and LastName values. We can also notice that the mixing of custom and built-in constraints is possible.

we’re also using the message attribute to specify the response message when the attribute is invalid, the message is interpolate using EL (Expression Language) to make reference to some dynamic attributes values such as notAlloweValues in the case of the NotContains constraint.

Validating Request

In order to validate the request body, we just need to tell Spring to do that annotating the request body argument with @Valid . Spring takes leverage of the Java Bean validation through the usage of Hibernate Validator Implementation.

Customizing Invalid Request Response

Spring throws a MethodArgumentNotValidException when an argument is not valid. To customize the endpoint response, we’re going to take leverage of the Spring exception handling capability.

@ExceptionHandler Instructs Spring which exception type should handle. We’re extracting all the invalid field errors, they contain the validation metadata for each validation that failed for a specific bean attribute. Creating a map that will be returned as a JSON format containing the endpoint path and an array with the field errors.

DEMO!

Let’s send and invalid request value and will see how our application will respond with a nice and easy to understand error response.