Skip to main content

Understanding @Validated in Spring Boot: A Complete Guide

In real-world applications, we often deal with user input—whether it’s coming from APIs, forms, or service calls. Validating this input is critical to ensure our application behaves correctly and securely.

Spring Boot makes this easier with annotations like @Valid and @Validated.

In this blog, we’ll dive deep into what @Validated is, how it works, and when to use it—with examples you can apply directly to your projects.


📌 What is @Validated?

@Validated is a Spring Framework annotation (org.springframework.validation.annotation.Validated) that enables bean validation (JSR-303/JSR-380, powered by Hibernate Validator by default).

It tells Spring to:

  • Validate incoming request data (DTOs).

  • Validate method arguments in services.

  • Enforce constraints like @NotNull, @Email, @Size, etc.


📝 Example 1: Using @Validated in a REST Controller

Suppose you have a REST endpoint to create a user:

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

    @PostMapping
    public ResponseEntity<String> createUser(@Validated @RequestBody UserDTO user) {
        return ResponseEntity.ok("User created: " + user.getName());
    }
}

Your UserDTO might look like this:

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

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

    // getters & setters
}

👉 If the request body fails validation (e.g., empty name or invalid email), Spring will automatically throw a MethodArgumentNotValidException and return a 400 Bad Request with error details.


📝 Example 2: Method-Level Validation in Services

Validation is not limited to controllers—you can apply it at the service layer too.

@Service
@Validated
public class UserService {

    public void registerUser(@NotBlank String name, @Email String email) {
        // Validation happens before entering this method
        System.out.println("User registered: " + name + ", " + email);
    }
}

Here, Spring validates method parameters automatically when the service method is called.


⚖️ Difference Between @Valid and @Validated

  • @Valid → Standard JSR-303 annotation (from jakarta.validation.Valid).

  • @Validated → Spring’s extension of @Valid, with support for validation groups.

So when should you use which?

  • Use @Valid when you don’t need groups—simple bean validation is enough.

  • Use @Validated when you want advanced validation scenarios with groups.


🔄 Example 3: Validation Groups with @Validated

Sometimes validation rules differ depending on the operation (e.g., creating vs updating a user). That’s where groups shine.

public class UserDTO {

    @NotNull(groups = Update.class)
    private Long id;

    @NotBlank(groups = {Create.class, Update.class})
    private String name;

    @Email(groups = Create.class)
    private String email;

    // groups interfaces
    public interface Create {}
    public interface Update {}
}

Controller methods:

@PostMapping("/create")
public ResponseEntity<String> create(@Validated(UserDTO.Create.class) @RequestBody UserDTO user) {
    return ResponseEntity.ok("User created");
}

@PutMapping("/update")
public ResponseEntity<String> update(@Validated(UserDTO.Update.class) @RequestBody UserDTO user) {
    return ResponseEntity.ok("User updated");
}

👉 Here:

  • When creating, id is not required but email must be valid.

  • When updating, id must be present but email isn’t validated.


✅ Why Use @Validated?

  • Ensures data integrity by validating user input.

  • Reduces boilerplate—no need to write manual validation logic.

  • Provides clear error responses when data is invalid.

  • Supports validation groups, making it more powerful than @Valid.


🚀 Key Takeaways

  • @Validated is Spring’s way of applying JSR-303 bean validation.

  • It works at controller level (for request DTOs) and service level (for method arguments).

  • Unlike @Valid, it supports validation groups—useful for different validation rules in different contexts.

  • Always combine it with constraints like @NotNull, @NotBlank, @Email, etc.


🔔 If you’re building Spring Boot APIs, use @Validated wisely—it’s a small annotation that prevents big problems down the road.


Would you like me to also include a sample @ControllerAdvice class that catches validation errors and returns a clean JSON error response? That would make the blog more practical.

Comments

Popular posts from this blog

📘 Understanding MDC and NDC in Logging

When debugging production issues, logs are your best friends. But in multi-threaded applications or systems handling multiple requests, logs can quickly become messy and hard to trace. This is where MDC (Mapped Diagnostic Context) and NDC (Nested Diagnostic Context) come in. 🔹 What is MDC? MDC (Mapped Diagnostic Context) allows you to store key-value pairs that are automatically added to your log entries. 👉 Example use case: Storing userId , transactionId , or requestId in MDC so every log line contains this contextual information. This makes tracing requests across distributed services much easier. Code Example (SLF4J with Logback): import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.slf4j.MDC; public class MDCExample { private static final Logger log = LoggerFactory.getLogger(MDCExample.class); public static void main(String[] args) { MDC.put("userId", "12345"); MDC.put("transactionId", "...