On this page
task_alt
04 Validation
Validation
Validation is the process of checking if the data is valid before saving it to the database (or similar). The object used to store the data is annotated with validation annotations.
Model
In the example below, the title field must be between 2 and 30 characters long and the description field must be between 10 and 50 characters long.
| Annotation | Description | Example |
|---|---|---|
@Digits | Element must be a number from the accepted range. | @Digits(integer = 2, fraction = 0) |
@Email | String has to be a well-formatted email address. | @Email |
@Max / @Min | The number must be (lower or equal)/(higher or equal) to the specified value. | @Max(value = 42) |
@Negative / @NegativeOrZero | Number must be negative (or zero). | @Negative |
@Positive / @PositiveOrZero | Number must be positive (or zero). | @Positive |
@NotBlank | Element must not be null and contain at least one non-whitespace character. | @NotBlank |
@NotEmpty | Element must not be null nor empty | @NotEmpty |
@NotNull / @Null | Element must (not) be null. | @NotNull |
@Size | The elements size must be between defined boundaries (inclusive) | @Size(min = 5, max = 10) |
A list of all validation attributes can be found in the documentation.
@Document(collection = "questionnaires")
public class Questionnaire {
@Id
private String id;
@Size(min = 2, max = 30)
private String title;
@Size(min = 10, max = 50)
private String description;
public Questionnaire() {}
public Questionnaire(String title, String description) {
this.title = title;
this.description = description;
}
}
Controller
The validation can then be executed using the @Valid annotation in the controller method.
The result of the validation is stored in the BindingResult object.
@PostMapping
public String create(@Valid Questionnaire questionnaire, BindingResult result) {
if (result.hasErrors()) {
return "questionnaires/create";
}
questionnaireRepository.save(questionnaire);
return "redirect:/questionnaires";
}
@PutMapping(value = "/{id}")
public String put(@PathVariable String id, @Valid Questionnaire questionnaire, BindingResult result) {
if (result.hasErrors()) {
return "questionnaires/update";
}
if (!questionnaireRepository.existsById(id)) {
return "404";
}
questionnaireRepository.save(questionnaire);
return "redirect:/questionnaires";
}
View
Error messages can be displayed using the th:errors attribute.
The th:if="${#fields.hasErrors('...')}" is required so that the error message is only displayed if there are errors.
<!DOCTYPE html>
<html th:replace="~{layout :: maincontent(~{::section})}">
<head>
<title>flashcard</title>
</head>
<body>
<section style="width: 60%; margin-left: 10em">
<form th:action="@{/questionnaires}" th:object="${questionnaire}" method="post">
<fieldset>
<div class="mb-3 row">
<label class="col-md-2" th:for="title">Title:</label>
<div class="col-md-10">
<input class="form-control" type="text" th:field="*{title}" autofocus="autofocus"/>
<span th:if="${#fields.hasErrors('title')}" th:errors="*{title}" class="text-danger"/>
</div>
</div>
<div class="mb-3 row">
<label class="col-md-2" th:for="description">Description:</label>
<div class="col-md-10">
<input class="form-control" type="text" th:field="*{description}"/>
<span th:if="${#fields.hasErrors('description')}" th:errors="*{description}" class="text-danger"/>
</div>
</div>
</fieldset>
<div class="mb-3 row row-cols-auto">
<a class="btn btn-light" th:href="@{/questionnaires}">
<i class="bi bi-x-circle-fill"></i> Cancel
</a>
<button type="submit" class="btn btn-primary">
<i class="bi bi-floppy-fill"></i> Save
</button>
</div>
</form>
</section>
</body>
</html>