Проверка данных в форме
Проверка (валидация) не даёт сохранить неверные данные: пустой заголовок, слишком длинный текст, дату в неправильном формате. В Vaadin правила можно писать в двух местах: аннотациями на сущности — тогда они работают и в форме, и при сохранении в базу, — или прямо в форме через withValidator, если правило касается только этого экрана.
Зависимость
Аннотации проверки — стандарт Jakarta Validation, его реализует Hibernate Validator. Добавьте в pom.xml:
<!-- pom.xml -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>Правила на сущности
// src/main/java/com/example/blog/Post.java (поля с правилами)
@NotBlank
@Size(max = 120)
private String title;
@NotBlank
private String author;
@Size(max = 2000)
private String content;
@NotNull
private LocalDate publishedOn;Импорты — из пакета jakarta.validation.constraints: NotBlank, NotNull, Size. Остальное в классе не меняется.
| Аннотация | Правило |
|---|---|
@NotNull | Значение задано |
@NotBlank | Строка не пустая и не из одних пробелов |
@Size(min, max) | Длина строки или размер списка |
@Min, @Max | Границы числа |
@Email | Похоже на адрес почты |
@Past, @Future | Дата в прошлом или будущем |
BeanValidationBinder
BeanValidationBinder — это Binder, который читает аннотации сам. В форме из прошлого урока замените привязку:
// src/main/java/com/example/blog/views/PostFormView.java (фрагмент)
private final BeanValidationBinder<Post> binder = new BeanValidationBinder<>(Post.class);
public PostFormView(PostService service) {
binder.bindInstanceFields(this);
// дальше как раньше
}Импорт — com.vaadin.flow.data.binder.BeanValidationBinder. Строки forField(...) для полей больше не нужны. Звёздочку обязательности Binder ставит сам только полям с @NotNull, @NotEmpty или @Size(min = 1); для @NotBlank вызовите после привязки title.setRequiredIndicatorVisible(true). Нажмите «Сохранить» с пустой формой — под заголовком и автором появятся сообщения Hibernate Validator на языке браузера, например «не должно быть пустым».
Своё правило в форме
Если правило нужно только этому экрану, добавьте его через withValidator до bindInstanceFields:
// src/main/java/com/example/blog/views/PostFormView.java (фрагмент конструктора)
binder.forField(title)
.withValidator(value -> !value.toLowerCase().contains("todo"), "Уберите TODO из заголовка")
.bind("title");
binder.bindInstanceFields(this);Введите заголовок «TODO написать введение» и нажмите «Сохранить» — под полем появится «Уберите TODO из заголовка». bindInstanceFields пропускает поля, уже связанные вручную, а аннотации с title всё равно проверяются.
Свой текст ошибки
Сообщение можно задать прямо в аннотации:
// src/main/java/com/example/blog/Post.java (фрагмент)
@NotBlank(message = "Введите заголовок")
@Size(max = 120, message = "Не длиннее 120 символов")
private String title;Когда проверка срабатывает
| Момент | Что происходит |
|---|---|
| Пользователь ушёл из поля | Поле проверяется и подсвечивается |
writeBeanIfValid | Проверяются все поля; при ошибке объект не меняется |
binder.validate() | Ручная проверка, возвращает список ошибок |
Сервер проверяет данные в любом случае: подделать запрос из браузера и обойти правила нельзя.
Частая ошибка
BeanValidationBinder есть, а зависимости spring-boot-starter-validation нет. Экран падает с сообщением:
BeanValidationBinder cannot be used because a JSR-303 Bean Validation implementation not found on the classpath or could not be initialized.Добавьте зависимость из начала урока и перезапустите приложение.