Introduction
In this example we will see an example on how to validate form in web application using Spring Boot framework. We will use Thymeleaf as a template for UI (user interface) or front-end. We will perform almost all kinds of validations available through Hibernate validator framework.
This example just validates the input values and once validated successfully it just sends a success response to the end user or client. It does not perform any business on the server side.
We will build our application both on gradle and maven build tools.
Prerequisites
Spring Boot 2.2.2, Gradle 5.6, Maven 3.6.1, Eclipse 4.12, Java at least 8
Create Project
You can create either gradle based or maven based project in Eclipse. The name of the project is spring-boot-web-app-form-validation.
If you are creating gradle based project then you can use below build.gradle script:
buildscript {
ext {
springBootVersion = '2.2.2.RELEASE'
}
repositories {
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
}
}
plugins {
id 'java-library'
id 'org.springframework.boot' version '2.2.2.RELEASE'
}
sourceCompatibility = 12
targetCompatibility = 12
repositories {
mavenCentral()
}
dependencies {
implementation("org.springframework.boot:spring-boot-starter-web:${springBootVersion}")
implementation("org.springframework.boot:spring-boot-starter-thymeleaf:${springBootVersion}")
implementation('org.hibernate:hibernate-validator:6.1.0.Final')
implementation('org.apache.tomcat.embed:tomcat-embed-el:9.0.30')
}
If you are creating maven based project then you can use below pom.xml file:
<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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.roytuts</groupId>
<artifactId>spring-boot-web-app-form-validation</artifactId>
<version>0.0.1-SNAPSHOT</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.2.RELEASE</version>
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>6.1.0.Final</version>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-el</artifactId>
<version>9.0.30</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>at least 8</source>
<target>at least 8</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
Hibernate Validator Annotations
@Digits(integer=, fraction=): annotated value is a number having up to integer digits and fractional digits upto fraction.
@Email: specified character sequence is a valid email address.
@Max(value=): annotated value is less than or equal to the specified maximum.
@Min(value=): annotated value is higher than or equal to the specified minimum
@NotBlank: annotated character sequence is not null and the trimmed length is greater than 0.
@NotEmpty: annotated element is not null nor empty.
@Null: annotated value is null
@NotNull: annotated value is not null
@Pattern(regex=, flags=): annotated string matches the regular expression regex considering the given flag match
@Size(min=, max=): annotated element’s size is between min and max (inclusive)
@Negative: element is strictly negative. Zero values are considered invalid.
@NegativeOrZero: element is negative or zero.
@Future: annotated date is in the future.
@FutureOrPresent: annotated date is in the present or in the future.
@PastOrPresent: annotated date is in the past or in the present.
VO or DTO Class
This is the Java class that will bind the input fields in a form on UI or front-end. We will apply different types of validations using hibernate validator framework.
package spring.boot.web.app.form.validation.dto;
import java.time.LocalDate;
import javax.validation.constraints.Digits;
import javax.validation.constraints.Email;
import javax.validation.constraints.Future;
import javax.validation.constraints.FutureOrPresent;
import javax.validation.constraints.Min;
import javax.validation.constraints.Negative;
import javax.validation.constraints.NegativeOrZero;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.PastOrPresent;
import javax.validation.constraints.Pattern;
import javax.validation.constraints.Size;
import org.springframework.format.annotation.DateTimeFormat;
public class User {
@Min(1)
private int id;
@Min(1)
@Digits(integer = 2, fraction = 2)
private double height;
@NotEmpty
@Size(min = 3, max = 45)
private String name;
@Email
@NotBlank
@Size(max = 150)
private String email;
@NotNull
private String msg;
@Pattern(regexp = "[a-zA-Z]")
private String regex;
@FutureOrPresent
@DateTimeFormat(pattern = "yyyy-MM-dd")
private LocalDate localDate;
@PastOrPresent
@DateTimeFormat(pattern = "yyyy-MM-dd")
private LocalDate pastDate;
@Future
@DateTimeFormat(pattern = "yyyy-MM-dd")
private LocalDate futureDate;
@Negative
private int negative;
@NegativeOrZero
private int negativeOrZero;
// getters and setters
}
Web Controller
The Spring controller that handles request and response for the clients or end users.
We have http GET method to show the form to the clients.
We have http POST method for submitting the form values to the server and any validation failure will show next to the input field.
On success we return the success message as a response body.
package spring.boot.web.app.form.validation.controller;
import javax.validation.Valid;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import spring.boot.web.app.form.validation.dto.User;
@Controller
public class WebAppController {
@GetMapping("/")
public String showPage(User user) {
return "form";
}
@PostMapping("/")
public String validateUser(@Valid User user, BindingResult bindingResult) {
if (bindingResult.hasErrors()) {
return "form";
}
return "redirect:/success";
}
@ResponseBody
@GetMapping("/success")
public String success() {
return "Your form was successfully validated!";
}
}
UI – View File
Look at the below form how we bind the fields to the Java class attributes. We also show errors next to the input fields on validation failures.
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Spring Boot Web App Form Validation</title>
<style type="text/css">
#form {
width: 500px;
padding: 20px;
margin: 50px auto;
background: #fff;
-webkit-border-radius: 2px;
-moz-border-radius: 2px;
border: 1px solid #000;
}
</style>
</head>
<body>
<div id="form">
<h2>Validate Form</h2>
<form name='formValidation' th:action="@{/}" th:object="${user}"
method='POST'>
<table>
<tr>
<td>Id</td>
<td><input type='text' th:field="*{id}"></td>
<td th:if="${#fields.hasErrors('id')}" th:errors="*{id}">Id
Error</td>
</tr>
<tr>
<td>Height</td>
<td><input type='text' th:field="*{height}"></td>
<td th:if="${#fields.hasErrors('height')}" th:errors="*{height}">Height
Error</td>
</tr>
<tr>
<td>Name</td>
<td><input type='text' th:field="*{name}" /></td>
<td th:if="${#fields.hasErrors('name')}" th:errors="*{name}">Name
Error</td>
</tr>
<tr>
<td>Email</td>
<td><input type='text' th:field="*{email}" /></td>
<td th:if="${#fields.hasErrors('email')}" th:errors="*{email}">Email
Error</td>
</tr>
<tr>
<td>Message</td>
<td><input type='text' th:field="*{msg}" /></td>
<td th:if="${#fields.hasErrors('msg')}" th:errors="*{msg}">Message
Error</td>
</tr>
<tr>
<td>Regular Expression</td>
<td><input type='text' th:field="*{regex}" /></td>
<td th:if="${#fields.hasErrors('regex')}" th:errors="*{regex}">Regex
Error</td>
</tr>
<tr>
<td>Future or Present Date</td>
<td><input type='date' th:field="*{localDate}" /></td>
<td th:if="${#fields.hasErrors('localDate')}"
th:errors="*{localDate}">Future or Present Date Error</td>
</tr>
<tr>
<td>Past or Present Date</td>
<td><input type='date' th:field="*{pastDate}" /></td>
<td th:if="${#fields.hasErrors('pastDate')}"
th:errors="*{pastDate}">Past or Present Date Error</td>
</tr>
<tr>
<td>Future Date</td>
<td><input type='date' th:field="*{futureDate}" /></td>
<td th:if="${#fields.hasErrors('futureDate')}"
th:errors="*{futureDate}">Future Date Error</td>
</tr>
<tr>
<td>Negative</td>
<td><input type='text' th:field="*{negative}" /></td>
<td th:if="${#fields.hasErrors('negative')}"
th:errors="*{negative}">Negative Error</td>
</tr>
<tr>
<td>Negative or Zero</td>
<td><input type='text' th:field="*{negativeOrZero}" /></td>
<td th:if="${#fields.hasErrors('negativeOrZero')}"
th:errors="*{negativeOrZero}">Negative or Zero Error</td>
</tr>
<tr>
<td colspan='11'><input name="submit" type="submit"
value="Submit" /></td>
</tr>
</table>
</form>
</div>
</body>
</html>
Main Class
In spring boot applications a class with main method and @SpringBootApplication
annotation are enough to deploy the application into embedded tomcat server.
package spring.boot.web.app.form.validation;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication(scanBasePackages = "spring.boot.web.app.form.validation")
public class SpringBootWebAppFormValidationApp {
public static void main(String[] args) {
SpringApplication.run(SpringBootWebAppFormValidationApp.class, args);
}
}
Testing the Application
Now executing the above main class will deploy the application into tomcat server and you can hit the URL http://local host:8080/ in the browser. The following page appears:

If there is no validation failure then submitting the form will give you the following success message:

Source Code
Thanks for reading.