Validating the user inputs is one of the common tasks that the developer should implement during web application development. Validation may include checking the correct mobile number format, the minimum size of an input, etc.

In this post, we will learn how to validate the form data using spring boot thymeleaf and Bean validation API.

The following are the version details used in this example.

  • Spring Boot version : 2.2.6.RELEASE
  • Java version 1.8

Create Spring Boot application with required dependencies

Create a spring boot application with the required dependencies. Add spring-boot-starter-web, spring-boot-starter-thymeleaf, and lombok maven dependencies. We will use the Thymeleaf template engine in this example.

The spring-boot-starter-web dependency is bundled with spring-boot-starter-validation starter dependency. This dependency contains the Bean validation API, that is used for form validation in our example.

Below is the complete pom.xml file with the required dependencies.

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.2.6.RELEASE</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
	<groupId>com.asbnotebook</groupId>
	<artifactId>spring-boot-form-validation-thymeleaf</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>spring-boot-form-validation-thymeleaf</name>
	<description>Demo project for Spring Boot</description>

	<properties>
		<java.version>1.8</java.version>
		<maven-jar-plugin.version>3.1.1</maven-jar-plugin.version>
	</properties>

	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-thymeleaf</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>

		<dependency>
			<groupId>org.projectlombok</groupId>
			<artifactId>lombok</artifactId>
			<optional>true</optional>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
			<exclusions>
				<exclusion>
					<groupId>org.junit.vintage</groupId>
					<artifactId>junit-vintage-engine</artifactId>
				</exclusion>
			</exclusions>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>
</project>

Add the Bean validation

Create a DTO class called Student.java. This class will hold the data entered on the thymeleaf form.

package com.asbnotebook.dto;

import java.time.LocalDate;

import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Past;
import javax.validation.constraints.Pattern;
import javax.validation.constraints.Size;

import org.springframework.format.annotation.DateTimeFormat;

import lombok.Data;

@Data
public class Student {

	@NotNull(message = "LastName can not be null!!")
	@NotEmpty(message = "LastName can not be empty!!")
	private String name;

	@NotNull(message = "Choose the subject count you are going to study!")
	@Min(value = 4, message = "Student should enroll to minimum 4 subjects!!")
	@Max(value = 8, message = "Student can enroll to maximum 8 subjects!!")
	private int subjectCount;

	@NotNull
	@Min(1)
	@Max(12)
	private int grade;

	@NotNull
	@Size(max = 10, min = 10, message = "Mobile number should be of 10 digits")
	@Pattern(regexp = "[7-9][0-9]{9}", message = "Mobile number is invalid!!")
	private String mobileNo;

	@NotNull(message = "Please enter birth date")
	@Past(message = "Birth date should be less than current date!!")
	@DateTimeFormat(iso = DateTimeFormat.ISO.DATE)
	private LocalDate birthDate;
}

We have used the javax.validation library to validate the fields. Few of the validation annotations used here are:

  • @NotNull: Ensures that the input field is not null.
  • @NotEmpty: Ensures that the field is not empty. It can be applied to fields of type String, collections, etc.
  • @Min: The entered number should be equal to or greater than the defined minimum value.
  • @Max: The entered number should be equal to or less than the defined maximum value.
  • @Pattern: This validation annotation can be used to match the input with the specified regex expression. We have used the phone number field to match the specified regex expression in our example.
  • @Size: To validate the size of the input character sequence, map, list, etc.
  • @Past: Makes sure that the input date/time is of the past.

Create a StudentController.java class. Add the following code to the created file.

package com.asbnotebook.controller;

import javax.validation.Valid;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.Errors;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;

import com.asbnotebook.dto.Student;

@Controller
public class StudentController {

	@GetMapping("/")
	public String getForm(Student student) {
		return "index";
	}

	@PostMapping("/save-student")
	public String submitStudentDetails(@Valid Student student, Errors errors, Model model) {
		if (null != errors && errors.getErrorCount() > 0) {
			return "index";
		} else {
			model.addAttribute("successMsg", "Details saved successfully!!");
			return "success";
		}
	}
}

Here, we have set index.html as the default landing page. As the thymeleaf starter dependency is available on the classpath, we need to make sure that all the template files are available under src/main/resources/templates directory.

The thymeleaf form will submit to the URL path /save-student. The user form data is submitted to this HTTP Post URL path.

The @Valid annotation denotes that the parameter should be validated.

We also have the Errors object that holds the validation error details. If the error count is zero, we are redirecting the page to success.html and display the success message.

Create the Thymeleaf template pages

Create the index.html page under the directory /src/main/resources/templates/ of the project. We have used the bootstrap library to give a little nice look and feel for the page. 🙂

<!DOCTYPE html SYSTEM "http://www.thymeleaf.org/dtd/xhtml1-strict-thymeleaf-4.dtd">
<html xmlns:th="http://www.thymeleaf.org" >
<head>
	<meta charset="utf-8">
	<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
	<title>Registration page</title>
	<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css">
</head>
	<body>
		<div align="center" class="col-md-12">
			<h2>Welcome to Student registration page</h2>
			<div class="col-md-6">
				<form action="#" th:action="@{/save-student}" th:object="${student}" method="post">
					<div class="form-group">
						<label for="name">Name:</label> 
						<input type="text" class="form-control" id="name" th:field="*{name}">
						<p class="alert alert-danger" th:if="${#fields.hasErrors('name')}" th:errors="*{name}">
					</div>
					<div class="form-group">
						<label for="subjectCount">Subjects Count:</label> 
						<input type="number" class="form-control" id="subjectCount" th:field="*{subjectCount}">
						<p class="alert alert-danger" th:if="${#fields.hasErrors('subjectCount')}" th:errors="*{subjectCount}" />
					</div>
					<div class="form-group">
						<label for="grade">Grade:</label> 
						<input type="number" class="form-control" id="grade" th:field="*{grade}" />
						<p class="alert alert-danger" th:if="${#fields.hasErrors('grade')}" th:errors="*{grade}" />
					</div>
					<div class="form-group">
						<label for="mobile">Mobile Number:</label> 
						<input type="number" class="form-control" id="mobile" th:field="*{mobileNo}" />
						<p class="alert alert-danger" th:if="${#fields.hasErrors('mobileNo')}" th:errors="*{mobileNo}" />
					</div>
					<div class="form-group">
						<label for="bd">Birth Date:</label> 
						<input type="date" class="form-control" id="bd" th:field="*{birthDate}" />
						<p class="alert alert-danger" th:if="${#fields.hasErrors('birthDate')}" th:errors="*{birthDate}" />
					</div>
					<div class="form-group">
						<button type="submit" class="btn btn-primary">Submit</button>
					</div>
				</form>
			</div>
		</div>
	</body>
</html>

Create another success.html template page to display the success message.

<!DOCTYPE html SYSTEM "http://www.thymeleaf.org/dtd/xhtml1-strict-thymeleaf-4.dtd">
<html xmlns:th="http://www.thymeleaf.org" >
<head>
	<meta charset="utf-8">
	<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
	<title>Registration page</title>
	<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css">
</head>
<body>
	<div class="col-md-12" align="center">
		<br />
		<div class="alert alert-success col-md-8" role="alert">
			<p th:text="${successMsg}" />
		</div>
	</div>
</body>
</html>

Run the application

Start the spring boot application. We should be able to get the student registration form page at http://localhost:8080.

Click on the Submit button. We should be able to get the validation error messages, as shown below.

Spring boot thymeleaf validation example

Few more validation error for invalid data is shown below.

Spring boot thymeleaf validation example

Enter the valid data for all the fields. Now we can submit the form successfully. 🙂

validation example spring boot thymeleaf

Conclusion

In this post, we learned basic thymeleaf template form validation example with spring boot. I hope you have enjoyed the post.

The example code is available on Github.

Subscribe to my mailing list to get the latest posts directly into your mailbox. 🙂

Processing…
Success! You’re on the list.

You may also interested in