Spring Boot is one of the most popular Java frameworks at present. With convention over configuration, it makes creation of production level ‘Spring applications,’ very fast and easy, therefore a lot of web applications use this technology. This post is about validating client HTTP requests in a Spring Boot application using Hibernate Validator.
Hibernate validator contains many validators that can be used for validating fields. Also, we can create custom validators as required for specific checking of business logic. Let us build a simple Spring Boot application, and integrate the validations step by step.
Here, we will develop a simple Spring Boot application with a user registration facility. New users should be able to send HTTP post requests with their data and register it in the system. Request validation should be done by the server to avoid invalid data.
Using your favourite IDE (IntelliJ IDEA) create a new application with Spring Initialiser.
For registration, users will send a post request. Let's represent it with UserRegistrationRequest.java.
@NotBlank verifies that the trimmed length is greater than zero.
@Length gives a minimum and maximum value for the string.
@Email validates the correct email format.
The message is the output displayed if the validation fails.
In addition, there are lot more validators here.
Controller is the place where the client request hits first in the server. Implement UserController with a register method as below. If any of the validations fail, a MethodArgumentNotValidException will be thrown.
Even though we can do the validation as above, we still don't have a way of returning the proper error response. We need to send the list of error messages and a suitable http error code to the client side. Let us add the following method with @ExceptionHandler annotation into the controller for this purpose.
Here, all the MethodArgumentNotValidException will hit this method. It will return an HTTP 400 response with a list of validation errors.
Most of the time we face situations where complex validations are needed to be done with the DTO fields. For that we need to create custom validators. Let us introduce a new field postal code to the UserRegistrationRequest.
Create a new Java class named PostalCodeValidator implementing ConstraintValidator. Overrides initialise method with an empty body and isValid method with postal code validation logic which does a simple check for a five-digit number as below.
Then apply the new validator in the DTO as we did under step3.
Sometimes we face situations where we have to validate multiple fields. Let's add two hypothetical variables named startDate and endDate in the DTO where endDate should be after startDate and create a new annotation named StartEndDate.
And implement StartEndDateValidator with isValid method.
Put the new annotation in the DTO. As we are validating two fields, we have to add the annotation at the class level.
Now we have created a DTO and included several validators on its fields. Now it is time to run the application and see what happens. Let us simply run the Spring Boot application with the IDE. Then we can send a post request containing a dummy UserRegistrationRequest using postman.
Because the request is valid, we do not get any error messages. Now let us try with an empty name, postal code with 6 digits and a start date which occurs after the end date. Now we get the list of error messages as expected.
In this way we can validate user requests using predefined / custom validators and return meaningful error messages and error codes. We can maintain clean code by minimising code duplications by reusing the validators.
You can find the complete code here.