Spring Boot 4 Complete Guide · Lekcja

Ograniczenia walidacji Bean Validation i grupy ograniczeń

Stosuj adnotacje Jakarta Bean Validation z grupowaniem, aby wymuszać reguły zależne od kontekstu.

Lekcja 1 z 413 kroki

Ograniczenia walidacji Bean Validation i grupy ograniczeń to bezpłatna lekcja Spring Boot 4 Complete Guide na CoddyKit. To lekcja 1 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej Spring Boot 4 Complete Guide, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Spring Boot 4 Complete Guide zawiera 4 lekcji w sumie.

Części tej lekcji nie zostały jeszcze przetłumaczone i są wyświetlane po angielsku.

Why Bean Validation?

In a Spring Boot 4 application you constantly receive untrusted data: request bodies, query params, form submissions. Jakarta Bean Validation (the jakarta.validation API) lets you declare rules as annotations directly on your model fields instead of writing manual if checks everywhere.

  • Declarative — the rule lives next to the field it protects.
  • Centralized — Spring triggers validation automatically at the controller boundary.
  • Consistent — the same annotated class can be validated in the web layer, service layer, or persistence layer.

The reference implementation behind the API is Hibernate Validator, pulled in by the spring-boot-starter-validation dependency.

Adding the Starter

Validation is not bundled with the web starter anymore, so you must add it explicitly. Once present, Hibernate Validator is auto-configured and Spring wires a Validator bean for you.

Add the dependency to your pom.xml:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-validation</artifactId>
</dependency>

Annotating a DTO

You attach constraints to the fields of a Data Transfer Object. Each annotation carries an optional message and validation parameters.

  • @NotBlank — the string must contain at least one non-whitespace character.
  • @Email — must look like a valid email address.
  • @Size(min, max) — length must fall within range.
  • @Min / @Max — numeric bounds.
public class UserRegistrationRequest {

    @NotBlank(message = "Username is required")
    @Size(min = 3, max = 20)
    private String username;

    @NotBlank
    @Email(message = "Provide a valid email")
    private String email;

    @Min(value = 18, message = "Must be at least 18")
    private int age;

    // getters and setters
}

Triggering Validation with @Valid

Annotating the DTO alone does nothing. You must tell Spring to validate the argument by placing @Valid on the controller method parameter. If validation fails, Spring throws a MethodArgumentNotValidException before your method body ever runs, and returns a 400 Bad Request.

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

    @PostMapping
    public ResponseEntity<String> register(
            @Valid @RequestBody UserRegistrationRequest request) {
        // reaches here only if all constraints pass
        return ResponseEntity.ok("Registered " + request.getUsername());
    }
}

The Problem: One DTO, Many Contexts

Imagine the same UserRegistrationRequest is reused for two operations:

  • Create — the client must NOT send an id (the server generates it).
  • Update — the client MUST send an existing id to know what to modify.

A field that should be @Null on create but @NotNull on update cannot be expressed with plain annotations, because they always fire. This is exactly the problem constraint groups solve.

Defining Constraint Groups

A constraint group is just a marker interface — an empty interface used purely as a tag. You create one per validation context.

Every constraint annotation accepts a groups attribute. When you assign a constraint to a group, that constraint only runs when validation is requested for that group.

public interface OnCreate {}

public interface OnUpdate {}

Assigning Constraints to Groups

Now tag each constraint with the group(s) it belongs to. A constraint with no groups attribute implicitly belongs to the built-in Default group and runs unless you switch groups.

Here the id field obeys opposite rules depending on context:

public class ProductRequest {

    @Null(groups = OnCreate.class,
          message = "id must be empty when creating")
    @NotNull(groups = OnUpdate.class,
             message = "id is required when updating")
    private Long id;

    @NotBlank(groups = {OnCreate.class, OnUpdate.class})
    private String name;

    @Positive(groups = {OnCreate.class, OnUpdate.class})
    private BigDecimal price;

    // getters and setters
}

Selecting a Group with @Validated

Here is the crucial distinction: @Valid always validates the Default group only and cannot select a group. To activate a specific group you must use Spring's @Validated annotation, which accepts the target group class.

Each endpoint picks the group that matches its operation:

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

    @PostMapping
    public ResponseEntity<Void> create(
            @Validated(OnCreate.class) @RequestBody ProductRequest req) {
        // @Null id, @NotBlank name, @Positive price enforced
        return ResponseEntity.status(HttpStatus.CREATED).build();
    }

    @PutMapping
    public ResponseEntity<Void> update(
            @Validated(OnUpdate.class) @RequestBody ProductRequest req) {
        // @NotNull id enforced instead
        return ResponseEntity.ok().build();
    }
}

@Valid vs @Validated

This pair trips up many developers, so commit it to memory:

  • @Valid — comes from jakarta.validation. Works on fields for nested/cascading validation, but cannot specify a group (uses Default).
  • @Validated — comes from org.springframework.validation.annotation. Accepts group classes, and also enables method-level validation on Spring beans. Cannot be placed on a field for cascading.

Rule of thumb: use @Validated(Group.class) at the controller parameter to pick a group; use @Valid on inner object fields to cascade into them.

Cascading and Group Sequences

Two advanced needs come up often:

  • Cascading — to validate a nested object, mark its field with @Valid. Without it, the nested object's constraints are skipped.
  • Ordering — a @GroupSequence runs groups in order and stops at the first group that fails, so you can enforce cheap checks before expensive ones.
@GroupSequence({First.class, Second.class})
public interface OrderedChecks {}

public class OrderRequest {

    @NotEmpty(groups = First.class)
    private List<@Valid LineItem> items; // @Valid cascades into each item

    @AssertTrue(groups = Second.class,
                message = "Total must match line items")
    public boolean isTotalConsistent() {
        return /* expensive cross-field check */ true;
    }
}

Reading the Errors

When a grouped validation fails, the resulting MethodArgumentNotValidException still carries the standard BindingResult. You can translate it into a clean JSON response with a @RestControllerAdvice handler, mapping each field to its message.

@RestControllerAdvice
public class ValidationExceptionHandler {

    @ExceptionHandler(MethodArgumentNotValidException.class)
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public Map<String, String> handle(MethodArgumentNotValidException ex) {
        Map<String, String> errors = new HashMap<>();
        ex.getBindingResult().getFieldErrors().forEach(err ->
                errors.put(err.getField(), err.getDefaultMessage()));
        return errors;
    }
}

Quick Check

Test your understanding of how Spring selects a constraint group.

Recap

You learned how to enforce context-specific validation rules with Jakarta Bean Validation in Spring Boot 4:

  • Add spring-boot-starter-validation, then annotate DTO fields with constraints like @NotBlank, @Email, @Size, @Min.
  • Trigger validation at the controller boundary; a failure yields a 400 via MethodArgumentNotValidException.
  • Constraint groups are marker interfaces assigned via each annotation's groups attribute, letting one DTO carry different rules per operation (e.g. @Null on create vs @NotNull on update).
  • Use @Validated(Group.class) to select a group — @Valid only runs the Default group and is for cascading into nested objects.
  • @GroupSequence orders groups and short-circuits on the first failure; @Valid on a collection cascades into each element.
Bezpłatny start

Ucz się Java dzięki korepetycjom AI — za darmo

Pisz i uruchamiaj kod w przeglądarce, otrzymuj natychmiastową pomoc od korepetytora AI dostępnego 24/7 i kontynuuj naukę w sieci lub w aplikacji.

Kursy
21
Lekcje
84

Często zadawane pytania

Czy lekcja „Ograniczenia walidacji Bean Validation i grupy ograniczeń” jest bezpłatna?

Tak — pełny tekst „Ograniczenia walidacji Bean Validation i grupy ograniczeń” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu Spring Boot 4 Complete Guide, przejdź na CoddyKit PRO. Kurs Spring Boot 4 Complete Guide zawiera 4 lekcji w sumie.

Co nauczysz się w „Ograniczenia walidacji Bean Validation i grupy ograniczeń”?

Stosuj adnotacje Jakarta Bean Validation z grupowaniem, aby wymuszać reguły zależne od kontekstu. Ćwiczysz Spring Boot 4 Complete Guide z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.

Czy potrzebuję doświadczenia, aby zacząć Spring Boot 4 Complete Guide?

Nie wymagamy żadnego doświadczenia. Spring Boot 4 Complete Guide w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 1 z 4.

Ile czasu zajmuje lekcja „Ograniczenia walidacji Bean Validation i grupy ograniczeń”?

Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.

Czy mogę pisać i uruchamiać kod w tej lekcji Spring Boot 4 Complete Guide?

Tak. Każda lekcja Spring Boot 4 Complete Guide zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.

Wszystkie lekcje w tym kursie

  1. Ograniczenia walidacji Bean Validation i grupy ograniczeń
  2. Tworzenie niestandardowych adnotacji ograniczeń
  3. Globalna obsługa wyjątków za pomocą @ControllerAdvice
  4. Odpowiedzi ze szczegółami problemu RFC 7807
← Powrót do Spring Boot 4 Complete Guide