## Spring Boot Thymeleaf Form Data Validation with Bean Validator

### Introduction

Form Data Validation is a very common, and rudimentary step in building any web application with user input. We want to make sure that certain ranges are respected, and that certain formats are followed. For example, we'll want to make sure that the user isn't -345 years old, or that their email address is valid.

There are many ways to validate form data - and the method you use depends on your application. In general, you'll want to perform client-side validation, as well as server-side validation. Client-side validation makes sure that unfiltered data doesn't even reach the back-end, while server-side validation makes sure that the wrong data isn't processed further.

In this article, we'll cover how to perform form data validation in Spring Boot with Thymeleaf, as the template engine.

We'll leverage Spring Boot's built-in Bean Validation API, which makes this process simple and straightforward.

### Spring Boot Validation Maven Dependency

Spring Boot allows us to define validation criteria using annotations. In your Domain Model, you can simply annotate fields with the constraints, and it'll enforce them.

For the validation annotations to work we need to add the following dependency:

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


### Domain Model

Let's define a simple POJO, with a few fields that we want to validate:

@Entity
public class Person {

@Id
@GeneratedValue(strategy= GenerationType.AUTO)
private Long id;

@NotEmpty
@Size(min = 5)
private String fullName;

@NotEmpty
@Email
private String email;

@NotNull
@Min(value = 18)
private Integer age;

// Getters and Setters

}


Now, let's break the annotations we used:

• @NotEmpty - is used to constrain a field of type String, Collection, Map, or Array to not be null or empty.
• @Size([min = x, max = y]) - is used to define the rules for the size of a String, Collection, Map, or Array.
• @Email - helps us to validate the string against a regex which defines the structure of a valid email.
• @NotNull - tells Spring the field should not be null, but it can be empty.
• @Min and @Max are used to specify the limits of a variable. For example, the @Min age could be set to, say, 18.

### Persistence Layer - Repository

To create a simple CRUD repository, all we have to do is extend the JpaRepository and supply our domain model and the ID's data type:

@Repository
public interface PersonRepository extends JpaRepository<Person, Long> {
}


### Creating a Form with Thymeleaf

Now, let's make a simple form using HTML and Bootstrap to collect information:

<form th:action="@{/add}" th:object="${person}" method="post" class="form"> <div class="form-group"> <label for="fullName">Name</label> <input class="form-control" type="text" th:field="*{fullName}" id="fullName" placeholder="Full Name"> <div class="alert alert-warning" th:if="${#fields.hasErrors('fullName')}" th:errors="*{fullName}"></div>
</div>
<div class="form-group">
<label for="email">Email</label>
<input class="form-control" type="text" th:field="*{email}" id="email" placeholder="Email">
<div class="alert alert-warning" th:if="${#fields.hasErrors('email')}" th:errors="*{email}"></div> </div> <div class="form-group"> <label for="age">Age</label> <input class="form-control" type="text" th:field="*{age}" id="age" placeholder="Age"> <div class="alert alert-warning" th:if="${#fields.hasErrors('age')}" th:errors="*{age}"></div>
</div>
<input type="submit"  class="btn btn-success" value="Add User">
</form>


### Customizing Error Messages

To set a custom message for any validation constraint, you can use the message option:

@NotEmpty(message = "Field can't be empty!)
private String field;


You can simply write these messages out in your model, like this. Though, it's considered good practice to put the validation messages in a properties file, that you can reference. This is done since you can bundle all validation messages together, and can update them if the models get changed at a later date.

Let's make our ValidationMessages.properties under src/main/resources:

Size.Person.FullName=The Full Name should have at least 5 characters


We will then modify the Person model, and supply this property as the message of the @Size annotation:

@NotEmpty(message = "The Full Name can't be null")
@Size(min = 5, message = "{Size.Person.FullName}")
private String fullName;


Let's go back to our form and see how it looks now:

### Conclusion

In this article, we've gone over how to use the Bean Validator API that Spring Boot uses to effortlessly perform form data validation with Thymeleaf.

We've created a domain model, annotated our fields with Bean Validator constraints. Then, we've made a repository and controller to display the form and process it, as well as save the relevant information into a Person object, making sure that the fields are validated with the @Valid annotation.

You can find the source code on GitHub.