Encodera

Thanks for reading!

Donate to the site — we work hard for you.

Contents

Validating form data

Validation keeps wrong data from being saved: an empty title, a text that is too long, a date in the wrong format. In Vaadin you can write rules in two places: as annotations on the entity — then they work both in the form and when saving to the database — or right in the form with withValidator, if a rule concerns only that screen.

The dependency

Validation annotations are the Jakarta Validation standard, implemented by Hibernate Validator. Add to pom.xml:

<!-- pom.xml -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-validation</artifactId>
</dependency>

Rules on the entity

// src/main/java/com/example/blog/Post.java (fields with rules)
@NotBlank
@Size(max = 120)
private String title;
 
@NotBlank
private String author;
 
@Size(max = 2000)
private String content;
 
@NotNull
private LocalDate publishedOn;

The imports come from the jakarta.validation.constraints package: NotBlank, NotNull, Size. The rest of the class stays the same.

AnnotationRule
@NotNullA value is set
@NotBlankThe string is not empty and not just spaces
@Size(min, max)Length of a string or size of a list
@Min, @MaxNumber limits
@EmailLooks like an email address
@Past, @FutureA date in the past or the future

BeanValidationBinder

BeanValidationBinder is a Binder that reads the annotations itself. In the form from the previous lesson, replace the binding:

// src/main/java/com/example/blog/views/PostFormView.java (fragment)
private final BeanValidationBinder<Post> binder = new BeanValidationBinder<>(Post.class);
 
public PostFormView(PostService service) {
    binder.bindInstanceFields(this);
    // the rest as before
}

The import is com.vaadin.flow.data.binder.BeanValidationBinder. The forField(...) lines for the fields are no longer needed. Binder adds the required marker by itself only to fields with @NotNull, @NotEmpty or @Size(min = 1); for @NotBlank call title.setRequiredIndicatorVisible(true) after binding. Click "Save" on an empty form — Hibernate Validator messages in the browser's language appear under the title and author, such as "must not be blank".

A custom rule in the form

If a rule is needed only on this screen, add it with withValidator before bindInstanceFields:

// src/main/java/com/example/blog/views/PostFormView.java (part of the constructor)
binder.forField(title)
        .withValidator(value -> !value.toLowerCase().contains("todo"), "Remove TODO from the title")
        .bind("title");
binder.bindInstanceFields(this);

Type the title "TODO write intro" and click "Save" — "Remove TODO from the title" appears under the field. bindInstanceFields skips fields already bound by hand, and the annotations on title are still checked.

Your own error text

You can set the message right in the annotation:

// src/main/java/com/example/blog/Post.java (fragment)
@NotBlank(message = "Enter a title")
@Size(max = 120, message = "At most 120 characters")
private String title;

When validation runs

MomentWhat happens
The user leaves a fieldThe field is checked and highlighted
writeBeanIfValidAll fields are checked; on error the object does not change
binder.validate()A manual check that returns the list of errors

The server validates the data in any case: a forged request from the browser cannot bypass the rules.

Common mistake

BeanValidationBinder is used, but the spring-boot-starter-validation dependency is missing. The view fails with the message:

BeanValidationBinder cannot be used because a JSR-303 Bean Validation implementation not found on the classpath or could not be initialized.

Add the dependency from the beginning of the lesson and restart the application.

Thanks for reading!

Donate to the site — we work hard for you.