Hey guys in this post, we will discuss adding validation to the spring boot application using Hibernate validator.
Table of Contents
Overview
Hibernate Validator is the reference implementation of Bean validation API. With Bean Validation, a single javax.validation.Validator
instance typically validates all model objects that declare validation constraints. To configure such a JSR-303 backed Validator with Spring MVC, simply add a Bean Validation provider, such as Hibernate Validator, to your classpath
Hibernate validator provides the following annotations to validate the fields
Example on Spring Boot Validation
Let’s create a step-by-step spring boot project and add the validations to it.
Create spring boot project
There are many different ways to create a spring boot application, you can follow the below articles to create one –
>> Create spring boot application using Spring initializer
>> Create spring boot application in Spring tool suite [STS]
>> Create spring boot application in IntelliJ IDEA
Add maven dependencies
Open pom.xml
and add the following dependencies –
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.4</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>in.bushansirgur</groupId>
<artifactId>hibernatevalidator</artifactId>
<version>v1</version>
<name>hibernatevalidator</name>
<description>Spring boot hibernate validator</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
spring-boot-starter-web
dependency for building web applications using Spring MVC. It uses the tomcat as the default embedded container. spring-boot-devtools
dependency for automatic reloads or live reload of applications. spring-boot-starter-validation
dependency for the hibernate validator.
If you are using Spring boot less than 2.3v then you don’t need to add this dependency as spring-boot-starter-web
has the contains hibernate validator.
Create an entity class
Create Employee.java
inside the in.bushansirgur.springboot.entity
package and add the following content
package in.bushansirgur.springboot.entity;
import javax.validation.constraints.Email;
import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
public class Employee {
@NotBlank(message = "Please enter name")
@Size(min=4, message = "Name should be atleast 4 characters")
@Size(max=10, message = "Name should not be greater than 10 characters")
private String name;
@NotNull(message = "Please enter salary")
@Min(value=1000, message = "Salary must be atleast 1000.00")
@Max(value=10000, message = "Salary should not be greater than 10000.00")
private Double salary;
@Email(message = "Please enter valid email", regexp="^[a-zA-Z0-9._-]+@[a-zA-Z0-9-]+\\.[a-zA-Z.]{2,5}")
@NotNull(message = "Please enter email")
private String email;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Double getSalary() {
return salary;
}
public void setSalary(Double salary) {
this.salary = salary;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
We have added @NotBlank
annotation to the name field, which validates that the value of the field should not be null, should not be blank and length should be greater than 0. @Size
annotation validates that the minimum characters should be 4 and the maximum should be 10. Also, we have added the custom validation message using the message
option.
We have added @NotNull
annotation to the salary field, which validates that the field should be not null. @Min
and @Max
annotation validate that the value should be ranged between the specified min and max values.
We have added @Email
annotation to the email field, which validates that the email should be valid and it should match the regex pattern which we specified with the regexp
option.
Create global exception handler class
Create GlobalExceptionHandler.java
inside the in.bushansirgur.springboot.exception
package and add the following content
package in.bushansirgur.springboot.exception;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;
@ControllerAdvice
public class GlobalExceptionHandler extends ResponseEntityExceptionHandler{
@Override
protected ResponseEntity<Object> handleMethodArgumentNotValid(MethodArgumentNotValidException ex,
HttpHeaders headers, HttpStatus status, WebRequest request) {
Map<String, Object> body = new LinkedHashMap<>();
body.put("timestamp", new Date());
body.put("status", status.value());
//Get all errors
List<String> errors = ex.getBindingResult()
.getFieldErrors()
.stream()
.map(x -> x.getDefaultMessage())
.collect(Collectors.toList());
body.put("errors", errors);
return new ResponseEntity<>(body, status);
}
}
We extended this class with ResponseEntityExceptionHandler
, and override the method handleMethodArgumentNotValid()
which will trigger if the bean validation fails.
Inside the method, we will add the default messages to LinkedHashMap
that are failed by the validation.
Create a Rest controller
Create EmployeeController.java
inside the in.bushansirgur.springboot.controller
package and add the following content
package in.bushansirgur.springboot.controller;
import javax.validation.Valid;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import in.bushansirgur.springboot.entity.Employee;
@RestController
public class EmplooyeeController {
@PostMapping("/employees")
public ResponseEntity<Employee> save (@Valid @RequestBody Employee e) {
return new ResponseEntity<Employee>(e, HttpStatus.CREATED);
}
}
Before we bind the request body to the entity class, spring will validate the bean with @Valid
annotation. If validation fails, then it throws an exception MethodArgumentNotValidException
.
Run the app
Run the application using the below maven command –
mvn spring-boot:run