When to Use @Validated vs @Valid in Spring Boot: A Complete Guide

This article explains the key differences between Spring's @Validated and @Valid annotations, covering their origins, support for group validation, nested property handling, usage in Spring MVC, practical code examples, custom annotations, and the underlying validation mechanism.

Spring Full-Stack Practical Cases
Spring Full-Stack Practical Cases
Spring Full-Stack Practical Cases
When to Use @Validated vs @Valid in Spring Boot: A Complete Guide

1. Introduction

In the Spring framework, @Validated and @Valid are both used for data validation, but they have important differences.

Source

@Valid

is part of the JSR‑303 Bean Validation specification (Jakarta EE) and is defined in the validation‑api package.

Group Validation

@Valid

does not support group validation, whereas @Validated does via its groups attribute.

Nested Property Validation

For nested properties, @Valid and @Validated are interchangeable, but group validation on nested properties requires @Validated.

Usage in Spring MVC

Both annotations can be placed on method parameters to trigger validation. To apply validation at the controller‑class level, @Validated must be used.

2. Practical Cases

2.1 Group Validation

When different business scenarios need different validation rules, use @Validated with groups:

@NotEmpty(message = "姓名不能为空", groups = G1.class)
private String name;

Define a group interface or class (e.g., G1) and apply it in the controller:

public Object save(@Validated({G1.class}) @RequestBody User user,
                  BindingResult errors) {
    // ...
}

The value attribute can contain multiple groups. @Valid cannot perform group validation.

2.2 Class‑Level Parameter Validation

To validate method parameters, place @Validated on the controller class:

@RestController
@RequestMapping("/validators")
@Validated
public class ValidatorController {
    @GetMapping("get")
    public Object get(@NotEmpty(message = "参数name不能为空") String name) {
        return name;
    }
}

Directly annotating parameters works only when the class is annotated with @Validated; @Valid on the class has no effect.

Why @Validated Is Required

Spring Boot registers a MethodValidationPostProcessor that creates proxies only for beans annotated with @Validated. To make @Valid effective, you can customize this post‑processor:

@Bean
MethodValidationPostProcessor methodValidationPostProcessor() {
    MethodValidationPostProcessor processor = new MethodValidationPostProcessor();
    processor.setValidatedAnnotationType(Valid.class);
    return processor;
}

3. Lesser‑Known Secrets

3.1 Custom Annotation

Define a custom annotation and meta‑annotate it with @Validated to enable validation:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.PARAMETER)
@Validated
public @interface PackValid {}

@PostMapping("")
public Object save(@PackValid @RequestBody User user, BindingResult errors) {
    // ...
}

Replacing @Validated with @Valid on the custom annotation will not work.

3.2 Special‑Named Annotations

Annotations whose simple name starts with Valid are also recognized by Spring’s validation logic:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.PARAMETER)
public @interface ValidPack {}

@PostMapping("")
public Object save(@ValidPack @RequestBody User user, BindingResult errors) {
    // ...
}

3.3 Underlying Principle

The utility class determines validation hints as follows:

public abstract class ValidationAnnotationUtils {
    public static Object[] determineValidationHints(Annotation ann) {
        if (ann instanceof Validated) {
            return ((Validated) ann).value();
        }
        Class<? extends Annotation> annotationType = ann.annotationType();
        if ("javax.validation.Valid".equals(annotationType.getName())) {
            return EMPTY_OBJECT_ARRAY;
        }
        Validated validatedAnn = AnnotationUtils.getAnnotation(ann, Validated.class);
        if (validatedAnn != null) {
            return validatedAnn.value();
        }
        if (annotationType.getSimpleName().startsWith("Valid")) {
            return convertValidationHints(AnnotationUtils.getValue(ann));
        }
        return null;
    }
}

These are the core differences and connections between @Validated and @Valid. In newer Spring versions (e.g., 6.1) you can also control the specific exception type thrown.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

Backendvalidationspring-boot
Spring Full-Stack Practical Cases
Written by

Spring Full-Stack Practical Cases

Full-stack Java development with Vue 2/3 front-end suite; hands-on examples and source code analysis for Spring, Spring Boot 2/3, and Spring Cloud.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.