Spring Boot validation using Hibernate validator





Hey guys in this post, we will discuss adding validation to the spring boot application using Hibernate validator.

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

Output: http://localhost:8080/employees
Screenshot-2021-03-20-at-2-00-49-PM



Bushan Sirgur

Hey guys, I am Bushan Sirgur from Banglore, India. Currently, I am working as an Associate project in an IT company.

Leave a Reply