DEV Community

realNameHidden
realNameHidden

Posted on

How Do You Handle Validation Errors Globally in Spring Boot?

"Learn how to handle validation errors globally in Spring Boot using @ControllerAdvice and exception handlers. Beginner-friendly guide with Java 21 examples."


Introduction

Imagine filling out an online form to apply for a credit card. You click Submit, and suddenly you see five different error messages scattered across the page—some in red, some as pop-ups, and some not even readable. Frustrating, right?

The same thing happens to API consumers when validation errors are handled inconsistently.

In Spring Boot, validation errors are common—missing fields, invalid formats, or wrong values. If every controller handles these errors differently, your API quickly becomes messy and hard to maintain.

That’s where global validation error handling in Spring Boot comes to the rescue. Think of it like a central customer support desk—instead of every department answering complaints their own way, all issues are handled consistently in one place.

In this blog, you’ll learn how to handle validation errors globally in Spring Boot, using simple explanations, real-world analogies, and Java 21–compatible examples.


Core Concepts

What Is Validation in Spring Boot?

Validation is Spring Boot’s way of checking incoming data before processing it.

Examples:

  • Username cannot be empty
  • Email must be valid
  • Age must be greater than 18

Spring Boot uses Jakarta Bean Validation (jakarta.validation) with annotations like:

  • @NotNull
  • @NotBlank
  • @Email
  • @Size

What Are Validation Errors?

Validation errors occur before your business logic runs. Spring detects them and throws exceptions such as:

  • MethodArgumentNotValidException (for @RequestBody)
  • ConstraintViolationException (for path variables and request params)

Why Handle Validation Errors Globally?

Handling errors globally gives you:

Consistency – Same error format everywhere

Cleaner controllers – No try-catch clutter

Better API experience – Predictable error responses

Easy maintenance – Change logic in one place

👉 In short, global validation error handling in Spring Boot makes your APIs professional and production-ready.

The Key Tool: @ControllerAdvice

Think of @ControllerAdvice as a security guard standing outside all controllers. Whenever an exception occurs, it intercepts it and responds properly.


Code Examples

✅ Example 1: Global Handling of @RequestBody Validation Errors

This is the most common scenario in REST APIs.

Step 1: DTO with Validation Rules

package com.example.demo.dto;

import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Size;

public class UserRequest {

    @NotBlank(message = "Name must not be blank")
    private String name;

    @Email(message = "Email must be valid")
    private String email;

    @Size(min = 8, message = "Password must be at least 8 characters long")
    private String password;

    // Getters and setters
    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;
    }
}
Enter fullscreen mode Exit fullscreen mode

Step 2: REST Controller

package com.example.demo.controller;

import com.example.demo.dto.UserRequest;
import jakarta.validation.Valid;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/users")
public class UserController {

    @PostMapping
    public ResponseEntity<String> createUser(@Valid @RequestBody UserRequest request) {
        return ResponseEntity.ok("User created successfully");
    }
}
Enter fullscreen mode Exit fullscreen mode

Step 3: Global Exception Handler

package com.example.demo.exception;

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 java.util.HashMap;
import java.util.Map;

@ControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ResponseEntity<Map<String, String>> handleValidationErrors(
            MethodArgumentNotValidException ex) {

        Map<String, String> errors = new HashMap<>();

        ex.getBindingResult()
          .getFieldErrors()
          .forEach(error -> errors.put(
                  error.getField(),
                  error.getDefaultMessage()
          ));

        return new ResponseEntity<>(errors, HttpStatus.BAD_REQUEST);
    }
}
Enter fullscreen mode Exit fullscreen mode

📌 Resulting API Response

{
  "email": "Email must be valid",
  "password": "Password must be at least 8 characters long"
}
Enter fullscreen mode Exit fullscreen mode

Clean, readable, and consistent!


✅ Example 2: Handling Validation Errors for Query Parameters & Path Variables

Not all inputs come from request bodies.

Controller Example

package com.example.demo.controller;

import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotBlank;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/products")
public class ProductController {

    @GetMapping("/{id}")
    public String getProduct(
            @PathVariable @Min(value = 1, message = "Product ID must be greater than 0") Long id,
            @RequestParam @NotBlank(message = "Category is required") String category) {

        return "Product fetched successfully";
    }
}
Enter fullscreen mode Exit fullscreen mode

Global Handler for ConstraintViolationException

package com.example.demo.exception;

import jakarta.validation.ConstraintViolationException;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ControllerAdvice;

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

@ControllerAdvice
public class GlobalConstraintExceptionHandler {

    @ExceptionHandler(ConstraintViolationException.class)
    public ResponseEntity<Map<String, String>> handleConstraintViolations(
            ConstraintViolationException ex) {

        Map<String, String> errors = new HashMap<>();

        ex.getConstraintViolations().forEach(violation ->
                errors.put(
                        violation.getPropertyPath().toString(),
                        violation.getMessage()
                )
        );

        return new ResponseEntity<>(errors, HttpStatus.BAD_REQUEST);
    }
}
Enter fullscreen mode Exit fullscreen mode

📌 Why this matters:
This ensures global validation error handling in Spring Boot works for all input types—not just JSON bodies.


Best Practices

  1. Always use @Valid or @Validated
    Forgetting this is the #1 reason validation doesn’t work.

  2. Return structured error responses
    APIs should return JSON objects, not plain text messages.

  3. Centralize error handling
    Avoid handling validation errors inside controllers.

  4. Use meaningful validation messages
    Default messages are often unclear for API consumers.

  5. Don’t expose internal details
    Never leak stack traces or framework internals in responses.


Conclusion

Handling validation errors properly is not optional—it’s a must-have for any professional API.

By using:

  • Bean Validation annotations
  • @ControllerAdvice
  • Centralized exception handlers

you can implement global validation error handling in Spring Boot that is clean, consistent, and easy to maintain.

If you’re serious about Java programming and want to learn Java the right way, mastering this pattern will instantly improve the quality of your Spring Boot applications.


Call to Action

💬 Have questions about validation or exception handling in Spring Boot?
👇 Drop them in the comments below!

If you found this helpful, try implementing it in your next project—and feel free to ask for advanced or real-world scenarios.


🔗 Helpful Resources

Happy coding! 🚀

Enter fullscreen mode Exit fullscreen mode

Top comments (0)