Spring Boot Validate JSON Request Body

In this tutorial, we will learn how to validate the Spring boot REST API JSON request body using Hibernate validator.

1. Add Validation Dependency to your Spring Boot Project

Spring boot provides good integration support with Hibernate validator.

We will use Hibernate Validator, which is one of the reference implementations of the bean validation API.

Starting with Boot 2.3, we need to explicitly add the spring-boot-starter-validation dependency:

<dependency> 
    <groupId>org.springframework.boot</groupId> 
    <artifactId>spring-boot-starter-validation</artifactId> 
</dependency>

2. Add Java Bean Validation Annotations to your Model or Domain Class

For example, consider we have  User class:
package net.javaguides.springboot.model;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.validation.constraints.Email;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.Size;

@Table(name = "users")
@Entity
public class User {
	
	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	private long id;
	
	@Column(name = "name", nullable = false)
	
	// user name should not be null or empty
	// user name should have at least 2 characters
	@NotEmpty
	@Size(min = 2, message = "user name should have at least 2 characters")
	private String name;
	
	// email should be a valid email format
	// email should not be null or empty
	@NotEmpty
	@Email
	private String email;
	
	// password should not be null or empty
	// password should have at least 8 characters
	@NotEmpty
	@Size(min = 8, message = "password should have at least 8 characters")
	private String password;
	
	public User() {
		
	}
	
	public User(String name, String email, String password) {
		super();
		this.name = name;
		this.email = email;
		this.password = password;
	}
	public long getId() {
		return id;
	}
	public void setId(long id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getEmail() {
		return email;
	}
	public void setEmail(String email) {
		this.email = email;
	}
	public String getPassword() {
		return password;
	}
	public void setPassword(String password) {
		this.password = password;
	}
}

 Note that we have added Java bean annotations to the User domain entity:

  • @NotEmpty validates that the property is not null or empty; can be applied to String, Collection, Map, or Array values.
  • @Size validates that the annotated property value has a size between the attributes min and max; can be applied to String, Collection, Map, and array properties.
  • @Email validates that the annotated property is a valid email address.

3. Add @Valid Annotation in Addition to @RequestBody Annotation

For example, consider we have  UserController class:
package net.javaguides.springboot.controller;

import javax.validation.Valid;

import org.springframework.beans.factory.annotation.Autowired;
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.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import net.javaguides.springboot.model.User;
import net.javaguides.springboot.service.UserService;

@RestController
@RequestMapping("/api/")
public class UserController {
	
	@Autowired
	private UserService userService;
	
	@PostMapping("users")
	public ResponseEntity<User> createUser(@Valid @RequestBody User user){
		User savedUser = userService.createUser(user);
		return new ResponseEntity<User>(savedUser, HttpStatus.CREATED);
	}

}
Note that we enable validation on Spring Rest Controller by adding @Valid annotation in addition to @RequestBody.

4. Customize the Validation Error Response

To customize response validation, we need to extend ResponseEntityExceptionHandler class and override handleMethodArgumentNotValid(MethodArgumentNotValidException ex, HttpHeaders headers, HttpStatus status, WebRequest request) method.

Let's create ValidationHandler class and add the following content to it:

package net.javaguides.springboot.controller;

import java.util.HashMap;
import java.util.Map;

import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.FieldError;
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 ValidationHandler extends ResponseEntityExceptionHandler{
	
	@Override
	protected ResponseEntity<Object> handleMethodArgumentNotValid(MethodArgumentNotValidException ex,
			HttpHeaders headers, HttpStatus status, WebRequest request) {
		
		Map<String, String> errors = new HashMap<>();
		ex.getBindingResult().getAllErrors().forEach((error) ->{
			
			String fieldName = ((FieldError) error).getField();
			String message = error.getDefaultMessage();
			errors.put(fieldName, message);
		});
		return new ResponseEntity<Object>(errors, HttpStatus.BAD_REQUEST);
	}
}

5. Run Spring Boot App and Test REST API using Postman Client

The below screenshot shows the validation of Spring boot REST API using Hibernate validator:

6. Source Code on GitHub

The source code of this tutorial is available on our GitHub repository at https://github.com/sourcecodeexamples/springboot-validation

Comments