Open In App

Spring – MVC Custom Validation

Last Updated : 10 Mar, 2022
Improve
Improve
Like Article
Like
Save
Share
Report

Prerequisites: Spring MVC, Spring MVC Validation

It is necessary to validate user input in any web application to ensure the processing of valid data. The Spring MVC framework supports the use of validation API. The validation API puts constraints on the user input using annotations and can validate both client-side and server-side. It provides standard predefined validators like @Min, @Max, @Size, @Pattern, and @NotNull. In case we have to process a more specific input spring MVC also provides the concept of user-defined validators with custom validation logic. In this article, we’ll create a custom validator to validate the address of a student in a student portal.

Steps to create a Student form with custom validation

Firstly, we need to create a maven webapp project, in this tutorial we’ll use Eclipse IDE. Now, choose to create maven while creating a new project and add a maven webapp archetype. Enter the group id and the artifact id for your project and click finish.

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

Now, let’s configure the pom.xml configuration file to add dependencies. Maven will get and manage all the dependencies defined in this file. You will need to add all these dependencies to be able to use the methods. The hibernate-validator dependency allows to express and validate application constraints.

XML




<?xml version="1.0" encoding="UTF-8"?>
         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>0.0.1-SNAPSHOT</version>
  <packaging>war</packaging>
 
  <name>SpringMvcStudentValidation Maven Webapp</name>
  <!-- FIXME change it to the project's website -->
  <url>http://www.example.com</url>
 
  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.7</maven.compiler.source>
    <maven.compiler.target>1.7</maven.compiler.target>
  </properties>
 
  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>
 
    <dependency
        <groupId>org.springframework</groupId
        <artifactId>spring-webmvc</artifactId
        <version>5.1.1.RELEASE</version
    </dependency
     
    <dependency
        <groupId>org.apache.tomcat</groupId
        <artifactId>tomcat-jasper</artifactId
        <version>9.0.12</version
    </dependency
     
    <dependency>   
        <groupId>javax.servlet</groupId>   
        <artifactId>servlet-api</artifactId>   
        <version>3.0-alpha-1</version>   
    </dependency
     
    <dependency
        <groupId>javax.servlet</groupId
        <artifactId>jstl</artifactId
        <version>1.2</version
    </dependency
     
    <dependency
        <groupId>org.hibernate.validator</groupId
        <artifactId>hibernate-validator</artifactId
        <version>6.0.13.Final</version
    </dependency
 
  </dependencies>
 
  <build>
    <finalName>SpringMvcStudentValidation</finalName>
    <pluginManagement>
      <plugins>
        <plugin>
          <artifactId>maven-clean-plugin</artifactId>
          <version>3.1.0</version>
        </plugin>
        <plugin>
          <artifactId>maven-resources-plugin</artifactId>
          <version>3.0.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-surefire-plugin</artifactId>
          <version>2.22.1</version>
        </plugin>
        <plugin>
          <artifactId>maven-war-plugin</artifactId>
          <version>3.2.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-install-plugin</artifactId>
          <version>2.5.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-deploy-plugin</artifactId>
          <version>2.8.2</version>
        </plugin>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.2</version>
            <configuration>
                <verbose>true</verbose>
                <source>1.8</source>
                <target>1.8</target>
                <showWarnings>true</showWarnings>
            </configuration>
        </plugin>
        <plugin>
            <groupId>org.apache.tomcat.maven</groupId>
            <artifactId>tomcat7-maven-plugin</artifactId>
            <version>2.2</version>
            <configuration>
                <path>/</path>
                <contextReloadable>true</contextReloadable>
            </configuration>
        </plugin>
      </plugins>
    </pluginManagement>
  </build>
</project>


The web.xml file in the “webapp/WEB-INF/web.xml” defines mapping with different URLs and servlets to handle requests for those URLs. In this, we have defined the servlet XML file to be named as gfg. The URL-pattern is set as “/”, which means any request with “/” will be sent to the dispatcher servlet to be handled.

XML




         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
                             http://java.sun.com/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>


 
 

The gfg-servlet.xml file is located in  “/src/main/webapp/WEB-INF/gfg.servlet.xml”. This file is named after the servlet-name we have mentioned in the web.xml file, it handles all HTTP requests for the web applications. The annotation-driven enable the spring annotation classes. The bean configuration helps in identifying and scanning the jsp located in the views folder. The component scan locates and allocated beans according to the defined annotation. It’s a pretty simple file to handle incoming HTTP calls.

 

XML




    xsi:schemaLocation="http://www.springframework.org/schema/beans
                        http://www.springframework.org/schema/beans/spring-beans.xsd
                        http://www.springframework.org/schema/mvc
                        http://www.springframework.org/schema/mvc/spring-mvc.xsd
                        http://www.springframework.org/schema/context
                        http://www.springframework.org/schema/context/spring-context.xsd">
 
    <context:component-scan base-package="com.gfg" />
     <bean
        class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix">
            <value>/WEB-INF/views/</value>
        </property>
        <property name="suffix">
            <value>.jsp</value>
        </property>
    </bean>
    <mvc:annotation-driven />
     
</beans>


 
 

Now, we’ll create a student class in the com.gfg.model package, for our student portal we’ll show four attributes firstName, lastName, rollNo, and address. The first two fields have @Size validation annotation as a constrain of min size as one, so they can’t be empty. For roll number, we have used @Min which is also a predefined validator. Now, for address, we have used @Address which is a custom validator that we are going to define and configure.

 

Java




package com.gfg.model;
 
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
 
import com.gfg.validationconfig.Address;
 
public class Student {
     
    @Size(min = 1, message = "Student first name can't be empty")
    private String firstName;
     
    @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;
     
     // custom validation
    @Address   
    private String address;
 
 
    public Student(@NotNull String firstName, @NotNull String lastName,
        @Min(value = 1000, message = "Roll number must be a four digit number")
        int rollNo,
        @Size(min = 20, message = "Address must contains atleast 20 letters") @Size(max = 40, message = "Address must contains atleast 20 letters")
        String address) {
        super();
        this.firstName = firstName;
        this.lastName = lastName;
        this.rollNo = rollNo;
        this.address = address;
    }
     
    public Student() {
    }
 
     
    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 this.address;
    }
     
    public void setAddress(String address) {
        this.address = address;
    }
     
}


The Controller class handles the incoming requests by redirecting them to the appropriate view page, any URL must be defined in the controller class in order to send a request. In this project, we have defined a StudentController class in com.gfg.controller package. In this class we have two methods for two request, the first one simply redirects to the login portal and simply add a new student object to match the inputs into the form using the model’s addAttribute. The second method redirects to the welcome page, but before that, it checks for any validation errors using the BindingResult. If there exists an error it redirects to the portal else to the welcome page.

Java




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";
        
    
}


The AddressValidator class in the com.gfg.validationcongfig package defines the constrain for which the object needs to be checked, this class implements the ConstraintValidator which defines the logic to validate a given constrain. We override a method class isValid from the ConstrainValidator interface, where we define our validation logic.

Java




package com.gfg.validationconfig;
 
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
   
public class AddressValidator implements ConstraintValidator<Address, String> {
   
    @Override
    public boolean isValid(String s, ConstraintValidatorContext cvc) { 
        s = s.toLowerCase();
        boolean result = s.contains("india");
        return result; 
    


Now, we create an Address annotation using the @interface, This class must have three overridden in order for the validation logic to work. The first method defines the error message to be shown, the second method represents a group of constraints, the third method represents additional information about the annotation. The @Constraint, @Target, and @Retention annotation define the validation logic, the element to be passed, and additional information.

Java




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 {}; 


The portal.jsp page the “/webapp/WEB-INF/views/portal.jsp” defines the student login portal. We have used the form configuration to format our form. This is a pretty simple form that defines four fields.

HTML




<%@ 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>


The welcome.jsp page in the “/webapp/WEB-INF/views/welcome.jsp” is the view page that is shown after successful login.

HTML




<%-- <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
 --%>
<!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:

Project Structure

Project Structure

Output:

It’s time to run your web application on the tomcat server. I am assuming you know how to run a tomcat server. After successfully running the tomcat server enter http://localhost:8080/SpringMvcStudentValidation/welcome in your favorite browser.

OutputOutputOutputOutput

So, we have created a Spring MVC project with our own validation and used it in a student portal form.



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads