How to Use BindingResult in Spring Boot for Form Validation
In Spring Boot,
BindingResult is used alongside a validated model object in a controller method to capture validation errors. It must immediately follow the model attribute parameter and allows you to check for errors and handle them before processing the form data.Syntax
Use BindingResult as a parameter right after the model object annotated with @Valid in your controller method. This lets Spring store validation errors for that object.
@Valid: triggers validation on the model object.BindingResult: holds validation errors if any.- Order matters:
BindingResultmust come immediately after the validated object.
java
public String submitForm(@Valid @ModelAttribute("user") User user, BindingResult bindingResult) { if (bindingResult.hasErrors()) { return "formPage"; // show form again with errors } // process valid user return "successPage"; }
Example
This example shows a Spring Boot controller handling a user registration form. The User object is validated, and BindingResult checks for errors. If errors exist, the form page is returned with error messages; otherwise, it proceeds to success.
java
import jakarta.validation.Valid; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.validation.BindingResult; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.PostMapping; import jakarta.validation.constraints.Email; import jakarta.validation.constraints.NotBlank; @Controller public class UserController { public static class User { @NotBlank(message = "Name is required") private String name; @Email(message = "Enter a valid email") @NotBlank(message = "Email is required") private String email; // getters and setters public String getName() { return name; } public void setName(String name) { this.name = name; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } } @GetMapping("/register") public String showForm(Model model) { model.addAttribute("user", new User()); return "registerForm"; } @PostMapping("/register") public String submitForm(@Valid @ModelAttribute("user") User user, BindingResult bindingResult) { if (bindingResult.hasErrors()) { return "registerForm"; // show form with errors } // process user data here return "registerSuccess"; } }
Output
If form input is invalid, the user sees the form again with error messages; if valid, the success page is shown.
Common Pitfalls
- Wrong parameter order: Placing
BindingResultbefore the validated object causes Spring to ignore validation errors. - Missing
@Validannotation: Without@Valid, validation won't run andBindingResultwill be empty. - Not checking
bindingResult.hasErrors(): Skipping this check can cause processing invalid data.
java
/* Wrong order example - will NOT work properly */ public String submitForm(BindingResult bindingResult, @Valid @ModelAttribute("user") User user) { // bindingResult will not contain errors return "somePage"; } /* Correct order example */ public String submitForm(@Valid @ModelAttribute("user") User user, BindingResult bindingResult) { if (bindingResult.hasErrors()) { return "formPage"; } return "successPage"; }
Quick Reference
Remember these key points when using BindingResult in Spring Boot:
| Tip | Description |
|---|---|
Place BindingResult immediately after the validated object | Ensures Spring captures validation errors correctly. |
Annotate the model object with @Valid | Triggers validation before binding results. |
Check bindingResult.hasErrors() before processing | Prevents handling invalid data. |
| Return the form view if errors exist | Allows users to correct input with error messages. |
| Use validation annotations on model fields | Defines rules for user input validation. |
Key Takeaways
Always put BindingResult right after the @Valid annotated model object in the controller method.
Use bindingResult.hasErrors() to check for validation errors before processing data.
Annotate your model fields with validation annotations like @NotBlank and @Email for automatic checks.
Return the form view with errors if validation fails to let users fix their input.
Missing @Valid or wrong parameter order causes BindingResult to not capture errors.