public class Person {
@NotNull
@Size(min=1, max=40)
private String firstName;
@Pattern(regexp=".+@.+\\.[a-z]+")
private String email;
...
}
...
@PostMapping("/")
public String update(@Valid Person person, BindingResult bindingResult) {
if (bindingResult.hasErrors()) {
return "profile";
}
return "redirect:/profile-updated";
}
Errors can be displayed in the returned HTML page using Thymeleaf, for example:
...
<form action="#" th:action="@{/}" th:object="${person}" method="post">
<table>
<tr>
<td>Name:</td>
<td><input type="text" th:field="*{firstName}" /></td>
<td th:if="${#fields.hasErrors('firstName')}" th:errors="*{firstName}">Name Error</td>
</tr>
<tr>
<td>Name:</td>
<td><input type="text" th:field="*{email}" /></td>
<td th:if="${#fields.hasErrors('email')}" th:errors="*{email}">Email Error</td>
</tr>
...
</table>
</form>
...
public class Person {
private String firstName;
private String email;
private String password;
...
}
@Documented
@Constraint(validatedBy = PasswordValidator.class)
@Target( { ElementType.METHOD, ElementType.FIELD })
@Retention(RetentionPolicy.RUNTIME)
public @interface Password {
String message() default "Password does match the password policy";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
validatedBy
attribute in the @Constraint
annotation above.public class PasswordValidator implements ConstraintValidator<Password, String> {
@Override
public void initialize(Password paramA) {
}
public boolean isValid(String password, ConstraintValidatorContext ctx) {
if (password == null || password.length() < 9) {
return false;
}
return true;
}
}
password
field in the Person class as an annotation e.g....
@Password
private String password;
...
...
@PostMapping("/")
public String update(@Valid Person person, BindingResult bindingResult) {
if (bindingResult.hasErrors()) {
return "profile";
}
return "redirect:/profile-updated";
}