Validation in Spring Boot

Validation is a crucial part of any application to ensure that the data being processed meets certain criteria. Spring Boot provides comprehensive support for validation through JSR-380 (Bean Validation 2.0) and Hibernate Validator. In this tutorial, we'll explore how to perform validation in a Spring Boot application.


  • JDK 17 or later
  • Maven or Gradle
  • IDE (IntelliJ IDEA, Eclipse, etc.)

Step 1: Set Up a Spring Boot Project

1.1 Create a New Spring Boot Project

Use Spring Initializr to create a new project with the following dependencies:

  • Spring Web
  • Spring Boot Actuator
  • Spring Data JPA
  • H2 Database
  • Validation

1.2 Configure

Set up the application properties for your project.


Step 2: Define the Entity with Validation Annotations

Create an entity class with validation annotations to enforce constraints on the fields.

package com.example.demo;

import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.validation.constraints.DecimalMin;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;

public class Product {

    @NotNull(message = "ID cannot be null")
    private Long id;

    @NotBlank(message = "Name is mandatory")
    @Size(min = 2, max = 100, message = "Name must be between 2 and 100 characters")
    private String name;

    @NotNull(message = "Price cannot be null")
    @DecimalMin(value = "0.0", inclusive = false, message = "Price must be greater than zero")
    private Double price;

    // Constructors
    public Product() {

    public Product(Long id, String name, Double price) { = id; = name;
        this.price = price;

    // Getters and setters
    public Long getId() {
        return id;

    public void setId(Long id) { = id;

    public String getName() {
        return name;

    public void setName(String name) { = name;

    public Double getPrice() {
        return price;

    public void setPrice(Double price) {
        this.price = price;

Step 3: Create a Repository

Create a repository interface to manage Product entities.

package com.example.demo;


public interface ProductRepository extends JpaRepository<Product, Long> {

Step 4: Create a Service

Create a service to handle business logic and validation.

package com.example.demo;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import jakarta.validation.Valid;

import java.util.List;

public class ProductService {

    private ProductRepository productRepository;

    public List<Product> getAllProducts() {
        return productRepository.findAll();

    public Product getProductById(Long id) {
        return productRepository.findById(id).orElse(null);

    public Product addProduct(@Valid Product product) {

Step 5: Create a Controller

Create a REST controller to handle HTTP requests and validate input data.

package com.example.demo;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import jakarta.validation.Valid;
import java.util.List;

public class ProductController {

    private ProductService productService;

    public List<Product> getAllProducts() {
        return productService.getAllProducts();

    public Product getProductById(@PathVariable Long id) {
        return productService.getProductById(id);

    public Product addProduct(@Valid @RequestBody Product product) {
        return productService.addProduct(product);

Step 6: Global Exception Handling

Create a global exception handler to handle validation errors and return meaningful responses.

package com.example.demo;

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.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;

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

public class GlobalExceptionHandler {

    public ResponseEntity<Map<String, String>> handleValidationExceptions(MethodArgumentNotValidException ex) {
        Map<String, String> errors = ex.getBindingResult().getFieldErrors()
                        fieldError -> fieldError.getField(),
                        fieldError -> fieldError.getDefaultMessage()
        return new ResponseEntity<>(errors, HttpStatus.BAD_REQUEST);

    public ResponseEntity<Map<String, String>> handleGlobalExceptions(Exception ex) {
        Map<String, String> error = new HashMap<>();
        error.put("message", ex.getMessage());
        return new ResponseEntity<>(error, HttpStatus.INTERNAL_SERVER_ERROR);

Step 7: Testing the Application

7.1 Create Test Cases

Write test cases to verify the validation logic.

package com.example.demo;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;

import static org.junit.jupiter.api.Assertions.assertEquals;

class ProductControllerTests {

    private RestTemplate restTemplate;

    void testAddProductValidation() {
        Product product = new Product(null, "", -1.0);
        ResponseEntity<String> response = restTemplate.postForEntity("/products", product, String.class);
        assertEquals(HttpStatus.BAD_REQUEST, response.getStatusCode());

7.2 Run the Application

Run the Spring Boot application and navigate to http://localhost:8080/products to test the endpoints and see the validation in action.


In this tutorial, you have learned how to implement validation in a Spring Boot 3.2 application. We covered how to use validation annotations on entity fields, handle validation in services and controllers, and create a global exception handler to manage validation errors. This approach ensures that your application processes only valid data and provides meaningful error messages to clients.