Spring MVC Custom Validation is used to enforce user-defined rules on form inputs when built-in validation annotations are not sufficient. It allows developers to create custom constraints and validation logic for specific business requirements. This ensures that only valid and meaningful data is processed in the application.
- Used when application requires business-specific validation rules not covered by standard annotations.
- Helps in validating complex input conditions like format, patterns, or domain-specific rules.
- Ensures data accuracy and consistency before processing or storing in database.
Steps to Create Custom Annotation (Spring MVC)
Follow these steps to create a custom validator to validate the address of a student in a student portal.
Step 1: Create Maven Web Project
- Open Eclipse IDE.
- Click File -> New -> Maven Project.
- Select Create a simple project and select archetype.
- Click Next.

Provide all the metadata:

A maven web project would be created with a pom.xml configuration file. The project structure would look something like this:

Step 2: Configure the pom.xml File
The pom.xml file is used to manage all project dependencies. In this step, we add Spring MVC, Servlet API, JSP (JSTL), and Hibernate Validator dependencies. These libraries are essential for building a web application and enabling validation features in Spring MVC.
pom.xml:
<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.gfg</groupId>
<artifactId>SpringMvcStudentValidation</artifactId>
<version>1.0</version>
<packaging>war</packaging>
<dependencies>
<!-- Spring MVC -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.29</version>
</dependency>
<!-- Servlet API -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>
<!-- JSP + JSTL -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<!-- Validation API -->
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>2.0.1.Final</version>
</dependency>
<!-- Hibernate Validator -->
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
<version>6.2.0.Final</version>
</dependency>
</dependencies>
</project>
Step 3: Configure the web.xml File
The web.xml file is the deployment descriptor of the application. It defines and registers the DispatcherServlet, which acts as the front controller in Spring MVC. All incoming requests are routed through this servlet to the appropriate controller.
<web-app xmlns="http://www.oracle.com/webfolder/technetwork/jsc/xml/ns/javaee/index.html"
xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.oracle.com/webfolder/technetwork/jsc/xml/ns/javaee/index.html
http://www.oracle.com/webfolder/technetwork/jsc/xml/ns/javaee/web-app_3_0.xsd"
version="3.0">
<display-name>To do List</display-name>
<welcome-file-list>
<welcome-file>login.do</welcome-file>
</welcome-file-list>
<servlet>
<servlet-name>gfg</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/gfg-servlet.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>gfg</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
Step 4: Create Spring MVC configuration file
This XML file contains Spring MVC configuration such as component scanning, view resolver, and annotation support. It helps Spring detect controller classes automatically and resolves JSP pages from a specific folder location. It acts as the core configuration file for the MVC layer.
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc">
<context:component-scan base-package="com.gfg"/>
<mvc:annotation-driven/>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/"/>
<property name="suffix" value=".jsp"/>
</bean>
</beans>
Step 5: Create the Student Model Class
The Student class represents the data structure of the form. It contains fields like first name, last name, roll number, and address. Validation annotations such as @NotNull, @Size, and custom @Address are applied to ensure that user input follows defined business rules before processing.
package com.gfg.model;
import javax.validation.constraints.Min;
import javax.validation.constraints.Size;
import com.gfg.validationconfig.Address;
public class Student {
@NotNull(message = "Student first name can't be empty")
@Size(min = 1, message = "Student first name can't be empty")
private String firstName;
@NotNull(message = "Student last name can't be empty")
@Size(min = 1, message = "Student last name can't be empty")
private String lastName;
@Min(value = 1000, message = "Roll number must be a four-digit number")
private int rollNo;
@NotNull(message = "Address cannot be null")
@Address(message = "Address must contain 'India'")
private String address;
// Default constructor
public Student() {}
// Getters and Setters
public String getFirstName() { return firstName; }
public void setFirstName(String firstName) { this.firstName = firstName; }
public String getLastName() { return lastName; }
public void setLastName(String lastName) { this.lastName = lastName; }
public int getRollNo() { return rollNo; }
public void setRollNo(int rollNo) { this.rollNo = rollNo; }
public String getAddress() { return address; }
public void setAddress(String address) { this.address = address; }
}
Step 6: Create the Student Controller
The controller is responsible for handling HTTP requests and managing the application flow. It receives user input from the form, performs validation using @Valid, and checks errors using BindingResult. If validation fails, the same form is returned; otherwise, the user is redirected to the success page.
package com.gfg.controller;
import javax.validation.Valid;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import com.gfg.model.Student;
@Controller
public class StudentController {
@RequestMapping("/login")
public String showForm(Model theModel) {
theModel.addAttribute("student", new Student());
return "portal";
}
@RequestMapping("/welcome")
public String processForm(@Valid @ModelAttribute("student") Student student, BindingResult result) {
if (result.hasErrors()) {
return "portal";
}
else {
return "welcome";
}
}
}
Step 7: Define the Address Annotation
A custom annotation is created to define user-specific validation rules that are not available by default in Spring. This annotation is linked with a validator class using @Constraint. It allows developers to define reusable validation logic for specific business requirements.
package com.gfg.validationconfig;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import javax.validation.Constraint;
import javax.validation.Payload;
@Constraint(validatedBy = AddressValidator.class)
@Target({ ElementType.METHOD, ElementType.FIELD })
@Retention(RetentionPolicy.RUNTIME)
public @interface Address
{
public String
message() default "You address must contains india";
public Class<?>[] groups() default {};
public Class<? extends Payload>[] payload() default {};
}
Step 8: Create the custom Address Validator
The validator class contains the actual logic for custom validation. It implements ConstraintValidator interface and overrides the isValid method. In this example, it checks whether the address contains the word “India”, ensuring business-specific validation rules are applied.
package com.gfg.validationconfig;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
public class AddressValidator implements ConstraintValidator<Address, String> {
@Override
public boolean isValid(String address, ConstraintValidatorContext context) {
if (address == null) {
return false;
}
return address.toLowerCase().contains("india");
}
}
Step 9: Create the portal.jsp Form
This JSP page is used to display the user input form. Spring form tags are used to bind form fields directly with the model object. It also displays validation error messages dynamically next to each field if the input is invalid.
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<html>
<head>
<style>
.error {color:red}
</style>
</head>
<body>
<h1>Student Portal</h1>
<form:form action="welcome" modelAttribute="student">
<label>First name:</label>
<form:input path="firstName" />
<form:errors path="firstName" cssClass="error" /><br><br>
<label>Last name:</label>
<form:input path="lastName" />
<form:errors path="lastName" cssClass="error" /><br><br>
<label>Roll No:</label>
<form:input path="rollNo" />
<form:errors path="rollNo" cssClass="error" /><br><br>
<label>Address:</label>
<form:textarea path="address" />
<form:errors path="address" cssClass="error" /><br><br>
<input type="submit" value="Submit" />
</form:form>
</body>
</html>
Step 10: Create the welcome.jsp View
This page is displayed after successful validation of user input. It shows the submitted student details and confirms that all validation rules have been passed. It acts as the final confirmation page of the application flow.
<%-- <%@ taglib prefix="c" uri="http://www.oracle.com/technetwork/java/index.html" %>
--%>
<!DOCTYPE html>
<html>
<body>
<div>
<h2>Welcome ${student.firstName} ${student.lastName} to Student portal<br><br>
Your Roll Number is ${student.rollNo} and you live in India.</h2>
</div>
</body>
</html>
Now, that our Spring MVC project has been completed with all the configuration files and classes. The Structure of your project should look like this:

Step 11: Run Your Application
- Right-click project.
- Select Run As -> Run on Server.
- Choose Apache Tomcat Server.
- Click Finish.
Open the browser and access:
http://localhost:8080/SpringMvcStudentValidation/welcome
Output:
The image below shows the Student Portal form with fields for entering the first name, last name, roll number, and address

The below image demonstrates the validation errors as per the custom validation.

The below image demonstrates that the form has been filled correctly.

After successful form submission and validation, the Welcome page is displayed with a confirmation message, showing the student’s first name, last name, roll number, and address containing “India”.

Explanation: This example shows how Spring MVC processes a student form using built-in and custom validation. The user enters data in the Student Portal form, which is bound to the model object. On submission, Spring validates the input and displays errors if any validation fails. If all data is valid, the controller redirects to the Welcome page showing the submitted details.