Validating data
A client may send an empty title or a thousand-page text. Checking every field with if is tedious. The Jakarta Validation standard lets you describe the rules as annotations right on the DTO fields, and Spring checks them before calling the controller method. An invalid request gets a 400 response, and the method never even starts.
Setup
Validation is a separate module. Add the starter to pom.xml (on start.spring.io it is called Validation):
<!-- pom.xml -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>The starter brings in Hibernate Validator — the most widely used implementation of the standard.
Rules on fields
// src/main/java/com/example/blog/NewPostRequest.java
package com.example.blog;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Size;
public record NewPostRequest(
@NotBlank @Size(max = 120) String title,
@NotBlank String body,
@NotBlank String author) {
}@NotBlank rejects null, an empty string and a string of spaces only. @Size(max = 120) limits the title length.
Switching the check on
// src/main/java/com/example/blog/PostController.java
@PostMapping
public ResponseEntity<Post> create(@Valid @RequestBody NewPostRequest request) {
Post post = postService.create(request);
return ResponseEntity.created(URI.create("/api/posts/" + post.id())).body(post);
}The @Valid annotation (from the jakarta.validation package) triggers the check. Add it to the update method too.
What the client gets
curl -i -X POST http://localhost:8080/api/posts \
-H "Content-Type: application/json" \
-d '{"title":"","body":"x"}'HTTP/1.1 400
{"timestamp":"2026-10-04T08:50:07.790Z","status":400,"error":"Bad Request","path":"/api/posts"}The post was not created. Spring writes the details only to the log (line shortened):
WARN ... Resolved [org.springframework.web.bind.MethodArgumentNotValidException: Validation failed for argument [0] ... with 2 errors: [Field error in object 'newPostRequest' on field 'author' ...The client, though, needs to know which fields are wrong. In the next lesson we will return a list of errors per field.
Common annotations
| Annotation | Checks |
|---|---|
@NotNull | The value is not null |
@NotBlank | A string is not empty and not just spaces |
@Size(min, max) | String length or list size |
@Min, @Max | Number bounds |
@Email | Looks like an email address |
@Pattern(regexp) | The string matches a regular expression |
@Past, @Future | A date in the past or future |
Your own message
Every annotation has a message parameter:
@NotBlank(message = "Title is required") String titleWithout it Hibernate Validator uses a standard text in the language from the request's Accept-Language header, or the system language when there is no header: must not be blank for English, не должно быть пустым for Russian.
Common mistake
If you forget @Valid before @RequestBody, the field annotations do nothing. There is no error — a post with an empty title is quietly saved. After adding rules, always test them with an invalid request and make sure a 400 comes back.