Validating Input
Never trust incoming data — add validation rules so bad requests are rejected automatically before they cause trouble.
What you will learn
- Add validation rules to a model
- Trigger validation with @Valid
- Understand why validation matters
Why validate?
Anyone can send data to your API — including empty names, negative prices, or junk. Validation checks the data against rules and rejects bad requests automatically, so your code only ever handles clean data.
The validation flow, start to finish
Adding validation is three small steps, then Spring does the checking on every request. Here is the whole flow in order before we do each step:
- Add the validation starter to
pom.xmlso the rule annotations exist (Step 1 below). - Put rules on the model fields, e.g.
@NotBlankon a name (Step 2 below). - Add
@Validbefore the@RequestBodyparameter so Spring runs the rules (Step 3 below). - A request arrives — Spring checks the data against the rules before your method runs.
- If the data is good, your method runs as normal. If it is bad, Spring stops it and sends back a
400 Bad Requestwith your messages.
Step 1: add the starter
Validation lives in a small starter. Add it to pom.xml (or pick it on Initializr):
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>Note: Output: (No output — this adds the validation library so the rule annotations below work.)
Step 2: put rules on the model
Annotate the fields with rules. They read almost like English:
public class Product {
@NotBlank(message = "Name is required")
private String name;
@Min(value = 0, message = "Price cannot be negative")
private double price;
// getters and setters ...
}Note: Output:
(No output yet — these rules only run when a request is checked, which we set up next.)
@NotBlank means the name must not be empty; @Min(0) means the price must be zero or more.
Step 3: trigger it with @Valid
Add @Valid before the @RequestBody and Spring checks the rules on every request:
@PostMapping("/products")
public String create(@Valid @RequestBody Product product) {
return "Created: " + product.getName();
}Note: Output: Good request {"name":"Mouse","price":499.0} -> Created: Mouse Bad request {"name":"","price":-5} -> 400 Bad Request, with messages: "Name is required", "Price cannot be negative" Spring rejected the bad request before your method ran, and sent back the helpful messages you wrote.
| Rule | Checks that… |
|---|---|
@NotBlank | A String is not empty or just spaces |
@NotNull | A value is present |
@Min / @Max | A number is within a range |
@Email | A String looks like an email |
@Size | Length is within limits |
Tip: A 400 Bad Request status means “your request was invalid”. Validation produces it for you, with the exact messages you wrote — so the client knows precisely what to fix.
Watch out: Validation rules do nothing without @Valid on the method parameter. The annotations on the model are just labels until @Valid tells Spring to enforce them.
Q. What makes Spring actually run the validation rules on a request body?
✍️ Practice
- Add
@NotBlankto a Book’s title and author, then send an empty title and see the 400 error. - Add
@Emailto a user’s email field and test a bad email.
🏠 Homework
- Add validation to a Student model (name required, age between 16 and 99) and confirm bad input is rejected with your messages.