0
0
SpringbootDebug / FixBeginner · 4 min read

How to Handle Validation Exception in Spring Boot Correctly

In Spring Boot, handle validation exceptions by using @Valid on request objects and catching MethodArgumentNotValidException with an @ExceptionHandler method in a @ControllerAdvice class. This lets you return clear, custom error messages when validation fails.
🔍

Why This Happens

Validation exceptions occur when input data does not meet the rules defined by annotations like @NotNull or @Size. If you don't handle these exceptions, Spring Boot returns a default error response that may not be user-friendly.

java
import jakarta.validation.constraints.NotBlank;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class UserController {

    @PostMapping("/users")
    public String createUser(@RequestBody User user) {
        return "User created";
    }
}

class User {
    @NotBlank(message = "Name is mandatory")
    private String name;

    // getters and setters
}
Output
HTTP 400 Bad Request with default error body, no clear validation message
🔧

The Fix

Add @Valid to the controller method parameter to trigger validation. Then create a @ControllerAdvice class with an @ExceptionHandler method to catch MethodArgumentNotValidException and return a custom error response.

java
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotBlank;
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.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

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

@RestController
public class UserController {

    @PostMapping("/users")
    public String createUser(@Valid @RequestBody User user) {
        return "User created";
    }
}

class User {
    @NotBlank(message = "Name is mandatory")
    private String name;

    // getters and setters
}

@ControllerAdvice
class ValidationExceptionHandler {

    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ResponseEntity<Map<String, String>> handleValidationExceptions(MethodArgumentNotValidException ex) {
        Map<String, String> errors = new HashMap<>();
        ex.getBindingResult().getAllErrors().forEach(error -> {
            String fieldName = ((FieldError) error).getField();
            String errorMessage = error.getDefaultMessage();
            errors.put(fieldName, errorMessage);
        });
        return new ResponseEntity<>(errors, HttpStatus.BAD_REQUEST);
    }
}
Output
HTTP 400 Bad Request with JSON body {"name":"Name is mandatory"} when name is blank
🛡️

Prevention

Always use @Valid on input parameters that require validation. Centralize exception handling with @ControllerAdvice to keep controllers clean. Use meaningful validation messages and test validation rules early to avoid runtime errors.

⚠️

Related Errors

Other common validation-related errors include:

  • ConstraintViolationException: Happens with validation on method parameters outside controllers.
  • BindException: Occurs when binding form data fails.
  • HttpMessageNotReadableException: Happens if JSON is malformed.

Handle these similarly with @ExceptionHandler methods in @ControllerAdvice.

Key Takeaways

Use @Valid on controller method parameters to trigger validation.
Handle MethodArgumentNotValidException in a @ControllerAdvice class for custom error responses.
Provide clear validation messages with annotations like @NotBlank(message = "...").
Centralize exception handling to keep controllers simple and maintainable.
Test validation rules early to catch input errors before runtime.