Form validation with Springboot validators
Spring mvc validators are used to validate the form data. It ensures that correct data is sent and in proper format.
Create a ‘spring starter project’ in STS. Project structure should look like below
pom.xml
<?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>3.3.2</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>form-validation-app</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>form-validation-app</name>
<description>Demo project for Spring Boot</description>
<url/>
<licenses>
<license/>
</licenses>
<developers>
<developer/>
</developers>
<scm>
<connection/>
<developerConnection/>
<tag/>
<url/>
</scm>
<properties>
<java.version>11</java.version>
</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.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
application.properties
spring.application.name=form-validation-app
# Thymeleaf configuration
spring.thymeleaf.prefix=classpath:/templates/
spring.thymeleaf.suffix=.html
spring.thymeleaf.cache=false
# Server configuration (optional)
server.port=8080
# Logging configuration (optional)
logging.level.org.springframework=INFO
logging.level.com.example=DEBUG
User.java
package com.sks.model;
import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.Size;
public class User {
@NotEmpty(message = "Name cannot be null")
@Size(min = 4, max = 50, message = "Name should be between 4 and 50 characters")
private String name;
@NotEmpty(message = "Email is required")
@Email(message = "Email should be valid")
private String email;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
UserValidator.java
package com.sks.validator;
import org.springframework.stereotype.Component;
import org.springframework.validation.Errors;
import org.springframework.validation.ValidationUtils;
import org.springframework.validation.Validator;
import com.sks.model.User;
@Component
public class UserValidator implements Validator {
@Override
public boolean supports(Class<?> clazz) {
return User.class.equals(clazz);
}
@Override
public void validate(Object target, Errors errors) {
User user = (User) target;
ValidationUtils.rejectIfEmptyOrWhitespace(errors, "name", "NotEmpty.user.name");
if (user.getName().length() < 4 || user.getName().length() > 50) {
errors.rejectValue("name", "Size.user.name");
}
ValidationUtils.rejectIfEmptyOrWhitespace(errors, "email", "NotEmpty.user.email");
if (!user.getEmail().contains("@")) {
errors.rejectValue("email", "Email.user.email");
}
}
}
UserController.java
package com.sks.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import com.sks.model.User;
import com.sks.validator.UserValidator;
@Controller
public class UserController {
@Autowired
private UserValidator userValidator;
@GetMapping("/register")
public String displayForm(Model model) {
model.addAttribute("user", new User());
return "register";
}
@PostMapping("/register")
public String submitForm(@ModelAttribute("user") User user, BindingResult bindingResult) {
userValidator.validate(user, bindingResult);
if (bindingResult.hasErrors()) {
return "register";
}
return "success";
}
}
messages.properties file. Create a file under src/main/resources folder with name messages.properties
NotEmpty.user.name=Name cannot be null
Size.user.name=Name should be between 4 and 50 characters
NotEmpty.user.email=Email is required
Email.user.email=Email should be valid
Create html files under the templates folder under src/main/resources package
register.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Register</title>
</head>
<body>
<h3>Welcome to Registration form</h3>
<form th:action="@{/register}" th:object="${user}" method="post">
<div>
<label>Name:</label>
<input type="text" th:field="*{name}"/>
<div th:if="${#fields.hasErrors('name')}" th:errors="*{name}">Name Error</div>
</div><br>
<div>
<label>Email:</label>
<input type="text" th:field="*{email}"/>
<div th:if="${#fields.hasErrors('email')}" th:errors="*{email}">Email Error</div>
</div>
<br>
<div>
<button type="submit">Register</button>
</div>
</form>
</body>
</html>
success.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Success</title>
</head>
<body>
<h1>Registration Successful!</h1>
</body>
</html>
Run the application the test the below url
When click on Register without any values for name and email, error will be displayed