Open In App

Spring MVC – Handling Form Validation with Spring Validator

Last Updated : 16 Sep, 2024
Comments
Improve
Suggest changes
Like Article
Like
Report

Form validation is crucial in web applications to ensure that user input is both accurate and appropriate before processing or storing it. In Spring MVC, form validation can be efficiently managed using the Spring Validator interface and annotations. This allows for flexible and robust validation mechanisms that are easy to implement and maintain in a Spring Boot application.

Spring Validator

The Validator interface in Spring provides a mechanism for validating user input in web applications. It ensures that data submitted by users conforms to certain rules or constraints before it is processed or stored.

1. The Validator Interface

In a Spring application, validation can typically be performed using the Validator interface, which includes two main methods:

  • supports(Class<?> clazz): Checks whether the Validator can validate instances of the provided class. It returns true if the validator can validate the given class; otherwise, it returns false.
  • validate(Object target, Errors errors): Performs the actual validation. It takes two parameters:
    • target: The object to be validated.
    • errors: The error object that contains information about validation errors.

2. BindingResult

BindingResult holds the result of the binding and validation. It is used to check for errors in the submitted form data and allows you to handle these errors appropriately.

Key methods of BindingResult:

  • hasErrors(): Returns true if there are any errors in the binding result.
  • hasFieldErrors(): Returns true if there are any field-specific errors.
  • getFieldErrors(): Returns a list of FieldError objects that represent errors on specific fields.
  • rejectValue(String field, String errorCode, Object[] errorArgs, String defaultMessage): Adds an error for a specific field.

3. Using Annotations for Validation

Spring supports validation using annotations from the Bean Validation API (JSR-380), such as @NotBlank, @Size, and @Min. These annotations are placed on the fields of Java Beans to specify validation constraints.

Annotations:

  • @NotBlank: Ensures that the field is not empty and not null.
  • @Size: Validates the size of the field.
  • @Min: Validates that the numeric field is greater than or equal to the specified value.

Implementation of Handling Form Validation with Spring Validator

We will create a simple Spring MVC project to demonstrate form validation with Spring Validator. This includes both annotation-based and custom validation in a Spring Boot project.

Step 1: Create the New Spring Boot Project

Create a new Spring Boot project using IntelliJ IDEA. Choose the following options:

  • Name: spring-mvc-validation-example
  • Language: Java
  • Type: Maven
  • Packaging: Jar
  • Click on the Next button.

Click on the Next button.

Project Metadata

Step 2: Add Dependencies

Add the following dependencies into the Spring Boot project.

  • Spring Web
  • Thymeleaf
  • Spring Boot DevTools
  • Validation Lombok

Click on the Create button.

Add Dependencies

Project Structure

After creating the project, the folder structure will look like the below image:

Project Folder Structure

Step 3: Create the User Class

Create a User class to represent the form data with validation annotations.

User.java:

Java
package com.gfg.springmvcvalidationexample;

import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Size;

/**
 * Represents a user with validation constraints.
 */
public class User {

    @NotBlank(message = "Name is required")
    @Size(min = 2, max = 30, message = "Name must be between 2 and 30 characters")
    private String name;

    @Min(value = 18, message = "Age should be at least 18")
    private int age;

    // Getters and setters

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

Explanation:

  • @NotBlank ensures the name field is not null or empty.
  • @Size restricts the length of the name between the 2 and 30 characters.
  • @Min ensures the age is at the least 18.

Step 4: Create the UserValidator Class

Create a custom validator for additional validation logic.

UserValidator.java:

Java
package com.gfg.springmvcvalidationexample;

import org.springframework.stereotype.Component;
import org.springframework.validation.Errors;
import org.springframework.validation.Validator;

/**
 * Custom validator for the User class.
 */
@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;

        // Custom validation for age
        if (user.getAge() < 18) {
            errors.rejectValue("age", "age.min", "Age must be at least 18");
        }
    }
}

Explanation:

  • The supports() method returns true, if the class is User.
  • The validate() method adds the custom error, if the age is less than 18.

Step 5: Create the UserController Class

Create a controller to handle form submissions and validation.

UserController.java:

Java
package com.gfg.springmvcvalidationexample;

import jakarta.validation.Valid;
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.PostMapping;
import org.springframework.web.bind.annotation.ModelAttribute;

/**
 * Controller for handling user form submissions.
 */
@Controller
public class UserController {

    @Autowired
    private UserValidator userValidator;

    @GetMapping("/user")
    public String showForm(Model model) {
        model.addAttribute("user", new User());
        return "userForm"; // View name for the form
    }

    @PostMapping("/user")
    public String submitForm(@Valid @ModelAttribute("user") User user, BindingResult result, Model model) {
        // Custom validation
        userValidator.validate(user, result);

        if (result.hasErrors()) {
            return "userForm"; // Return to form view if there are errors
        }

        // Process user data here

        return "userSuccess"; // View name for successful submission
    }
}

Explanation:

  • @Valid triggers the validation on the user model attribute.
  • BindingResult checks for the errors after validation.
  • The custom UserValidator can be used to perform additional checks.

Step 6: Main Class

This is the entry point of the Spring Boot application.

SpringMvcValidationExampleApplication.java:

Java
package com.gfg.springmvcvalidationexample;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/**
 * Main application class for Spring Boot.
 */
@SpringBootApplication
public class SpringMvcValidationExampleApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringMvcValidationExampleApplication.class, args);
    }
}

Step 7: Create the userForm.html Page

Create the HTML form for user input.

src/main/resources/templates/userForm.html

HTML
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <title>User Form</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            background-color: #f0f8f0; /* Light green background */
            color: #333;
            margin: 0;
            padding: 0;
        }
        .container {
            width: 60%;
            margin: 0 auto;
            padding: 20px;
            background-color: #fff;
            border-radius: 8px;
            box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
            margin-top: 50px;
        }
        h1 {
            color: #4caf50; /* Primary green color */
            text-align: center;
        }
        label {
            display: block;
            margin: 10px 0 5px;
            font-weight: bold;
        }
        input[type="text"], input[type="number"] {
            width: calc(100% - 22px);
            padding: 10px;
            border: 1px solid #ccc;
            border-radius: 4px;
            margin-bottom: 20px;
        }
        button {
            background-color: #4caf50; /* Primary green color */
            color: #fff;
            border: none;
            padding: 10px 20px;
            text-align: center;
            text-decoration: none;
            display: inline-block;
            font-size: 16px;
            margin: 4px 2px;
            cursor: pointer;
            border-radius: 4px;
        }
        .error {
            color: red;
            margin-bottom: 10px;
        }
    </style>
</head>
<body>
    <div class="container">
        <h1>User Form</h1>
        <form th:action="@{/user}" th:object="${user}" method="post">
            <div th:if="${#fields.hasErrors('name')}" class="error">
                <p th:errors="*{name}">Name Error</p>
            </div>
            <label for="name">Name:</label>
            <input type="text" id="name" th:field="*{name}" />

            <div th:if="${#fields.hasErrors('age')}" class="error">
                <p th:errors="*{age}">Age Error</p>
            </div>
            <label for="age">Age:</label>
            <input type="number" id="age" th:field="*{age}" />

            <button type="submit">Submit</button>
        </form>
    </div>
</body>
</html>

Step 8: Create the userSuccess.html Page

Create the HTML page to display a success message after form submission.

src/main/resources/templates/userSuccess.html

HTML
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <title>Success</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            background-color: #e0ffe0; /* Light green background */
            color: #333;
            margin: 0;
            padding: 0;
        }
        .container {
            width: 60%;
            margin: 0 auto;
            padding: 20px;
            background-color: #fff;
            border-radius: 8px;
            box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
            margin-top: 50px;
            text-align: center;
        }
        h1 {
            color: #4caf50; /* Primary green color */
        }
    </style>
</head>
<body>
    <div class="container">
        <h1>Form Submission Successful!</h1>
        <p>Your form has been submitted successfully.</p>
    </div>
</body>
</html>

pom.xml File:

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.3</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.gfg</groupId>
    <artifactId>spring-mvc-validation-example</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>spring-mvc-validation-example</name>
    <description>spring-mvc-validation-example</description>
    <url/>
    <licenses>
        <license/>
    </licenses>
    <developers>
        <developer/>
    </developers>
    <scm>
        <connection/>
        <developerConnection/>
        <tag/>
        <url/>
    </scm>
    <properties>
        <java.version>17</java.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-validation</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </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>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

Step 9: Run the Application

Run the Spring Boot application by executing the main class. The application will start on port 8080 by default.

Application Starts

Step 10: Test the Application

  • Open your browser and navigate to http://localhost:8080/user.
  • Fill out the form with valid and invalid data to test validation.
  • Submit the form and observe the validation messages and success page.

Output Video:

By following these steps, we will able to implement and test the form validation in the Spring MVC application. This ensures that the user input is validated correctly before any further processing of the Spring application.


Next Article
Article Tags :

Similar Reads