How to Validate Request Parameters in Spring Boot
How to Validate Request Body in Spring Boot
How to Validate Request Headers in Spring Boot
How to Validate Spring Boot Bean Programmatically or Manually
How to Customize Default Error Message in Spring Boot Validation
How to Customize Default Error Message using @ControllerAdvice in Spring Boot Validation
In the spring boot, the @valid annotation is used to validate the spring boot bean. When the validation fails, the default error message will be returned to the client. The default error message is a generic error message that does not make sense in certain api calls. The message must be tailored for a particular api request.
In another situation, the validation error is not an error. The error is required to be ignored and continue as normal. For example, the id value is mandatory in the database update, whereas the id value is not available in the database insert. The same bean object is used in both cases. In this case, if you validate in the rest controller class, you have to create two beans.
In this post, we’ll see how to customize the default error message for an api call. Customization is done using the rest controller method. Here, we’ll see how to ignore a @valid error message, how to convert a default @valid error message to a custom error message, how to convert a default @valid error message to a response message.
Pom.xml file and dependency
The pom.xml file contains all the configurations of the dependency. This dependency includes all the jar files required for validation.
The “spring-boot-starter-validation” dependency will include all the jars needed for the validation of the request body. The web application needs the dependence of “spring-boot-starter-browser.” This will allow the tomcat server and start as a web application. The default “spring-boot-starter-test” test dependency will be applied to pom.xml for the unit testing.
pom.xml
<?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.2.5.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<groupId>com.yawintutor</groupId>
<artifactId>Spring-Application</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>SpringBootValidation</name>
<description>Spring Boot Project</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-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 Bean class to validate
The spring boot bean class is required to store the value obtained from the client or browser in json format. A spring boot bean class contains private variables and getter and setter method. The bean class has annotation for validating the data. In this example the annotation @Min is used to validate a student age.
Student.java
package com.yawintutor;
import javax.validation.constraints.Min;
public class Student {
@Min(5)
private int age;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
How to Ignore the Default Error Message in @Valid validation
In the Student Class, the minimum age is 5. The @Min annotation is used to validate the minimum check. If this validation has to be ignored, you may need to duplicate the bean class without this annotation. Instead, the code below will help to ignore the specific controller method.
TestController.java
package com.yawintutor;
import javax.validation.Valid;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.Errors;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class TestController {
@PostMapping("/student/")
ResponseEntity<String> student(@Valid @RequestBody Student student, Errors errors) {
if (errors.hasErrors()) {
System.out.println("Errors count : " + errors.getErrorCount());
for (ObjectError objectError : errors.getAllErrors()) {
System.out.println("errors : " + objectError.getDefaultMessage());
}
if(errors.hasFieldErrors("age")) {
; // Ignore the min validation in age field.
} else {
return ResponseEntity.badRequest().body(errors.getAllErrors().toString());
}
}
return ResponseEntity.ok("Your age is " + student.getAge());
}
}
curl -X POST \
http://localhost:8080/student/ \
-H 'Cache-Control: no-cache' \
-H 'Content-Type: application/json' \
-H 'Postman-Token: a3a5d66e-2b98-4b7d-8400-9be137b01504' \
-d '{"age":"3"}'
Output
Your age is 3
How to Customize the Default Error Message in @Valid validation
The default error message in the @Min annotation is tailored to the age of the student class. The custom error message is shown as below
TestController.java
package com.yawintutor;
import javax.validation.ConstraintViolationException;
import javax.validation.Valid;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.Errors;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class TestController {
@PostMapping("/student/")
ResponseEntity<String> student(@Valid @RequestBody Student student, Errors errors) {
if (errors.hasErrors()) {
System.out.println("Errors count : " + errors.getErrorCount());
for (ObjectError objectError : errors.getAllErrors()) {
System.out.println("errors : " + objectError.getDefaultMessage());
}
if(errors.hasFieldErrors("age")) {
throw new ConstraintViolationException("Your age is " + student.getAge()+" which is less than 5",null);
} else {
return ResponseEntity.badRequest().body(errors.getAllErrors().toString());
}
}
return ResponseEntity.ok("Your age is " + student.getAge());
}
}
Curl command
curl -X POST \
http://localhost:8080/student/ \
-H 'Cache-Control: no-cache' \
-H 'Content-Type: application/json' \
-H 'Postman-Token: a3a5d66e-2b98-4b7d-8400-9be137b01504' \
-d '{"age":"3"}'
Output
{
"timestamp": "2020-03-29T07:55:26.370+0000",
"status": 500,
"error": "Internal Server Error",
"message": "Your age is 3 which is less than 5",
"path": "/student/"
}
How to Convert Default Error Message to Response Message in @Valid validation
The code below shows how to convert a default error message to a response message in @valid validation. The error message is converted to a valid client response message.
TestController.java
package com.yawintutor;
import javax.validation.ConstraintViolationException;
import javax.validation.Valid;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.Errors;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class TestController {
@PostMapping("/student/")
ResponseEntity<String> student(@Valid @RequestBody Student student, Errors errors) {
if (errors.hasErrors()) {
System.out.println("Errors count : " + errors.getErrorCount());
for (ObjectError objectError : errors.getAllErrors()) {
System.out.println("errors : " + objectError.getDefaultMessage());
}
if(errors.hasFieldErrors("age")) {
return ResponseEntity.ok("Your age is " + student.getAge()+" which is less than 5");
} else {
return ResponseEntity.badRequest().body(errors.getAllErrors().toString());
}
}
return ResponseEntity.ok("Your age is " + student.getAge());
}
}
Curl command
curl -X POST \
http://localhost:8080/student/ \
-H 'Cache-Control: no-cache' \
-H 'Content-Type: application/json' \
-H 'Postman-Token: a3a5d66e-2b98-4b7d-8400-9be137b01504' \
-d '{"age":"3"}'
Output
Your age is 3 which is less than 5