In this tutorial, we will learn how to validate Spring boot REST API requests using Hibernate validator.
In Java, the Java Bean Validation framework has become the de-facto standard for handling validations in Java projects.
JSR 380 is a specification of the Java API for bean validation and this ensures that the properties of a bean meet specific criteria, using annotations such as @NotNull, @Min, and @Max.
Hibernate Validator is the reference implementation of the validation API.
Important Java bean validations
- @NotNull validates that the annotated property value is not null.
- @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.
- @Min validates that the annotated property has a value not smaller than the value attribute.
- @Max validates that the annotated property has a value no larger than the value attribute.
- @Email validates that the annotated property is a valid email address.
- @NotEmpty validates that the property is not null or empty; can be applied to String, Collection, Map, or Array values.
- @NotBlank can be applied only to text values and validates that the property is not null or whitespace.
Check out the complete list here at https://www.sourcecodeexamples.net/2021/03/java-bean-validation-annotation-list.html
Validation in Spring Boot
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>
Validation in Spring Boot REST API Example
1. Create Spring boot application in STS
2. Maven Dependencies
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <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>com.h2database</groupId> <artifactId>h2</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency>
3. Create User Class
package net.javaguides.springboot.model; import jakarta.persistence.*; @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.
4. Configure Database
5. Create UserRepository
package net.javaguides.springboot.repository; import org.springframework.data.jpa.repository.JpaRepository; import net.javaguides.springboot.model.User; public interface UserRepository extends JpaRepository<User, Long>{ }
6. Create UserService Class
package net.javaguides.springboot.service; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import net.javaguides.springboot.model.User; import net.javaguides.springboot.repository.UserRepository; @Service public class UserService { @Autowired private UserRepository userRepository; public User createUser(User user) { return userRepository.save(user); } }
7. Create 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); } }
8. Create ValidationHandler
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); } }
9. Run Spring Boot App
package net.javaguides.springboot; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class SpringbootValidationApplication { public static void main(String[] args) { SpringApplication.run(SpringbootValidationApplication.class, args); } }
10. Testing using Postman Client
In this tutorial, we learned how to validate Spring boot REST API requests using Hibernate validator.
The source code of this tutorial available on my GitHub repository at https://github.com/RameshMF/springboot-validation
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>
Comments
Post a Comment
Leave Comment