Spring MVC Form Custom Validation

We have discussed earlier the other forms of Validation, such as Regular Expression and Number Validations. Spring Validation also offers a user to perform Custom Validations. It allows us to create our annotation, which will be used to implement the validation rules. For example, a field collegeCode is taken for custom validation and a ConstraintValidator, which is used to validate the collegeCode checks whether it starts with the word “TIPS” or not.

In the example of custom Validation, we are going to use the following annotations:

  • @Constraint The @Constraint annotation is used to mark an annotation as a Bean Validation Constraint. It is available in javax.validation package.
  • @Target – The @Target annotation indicates the text on which the annotation type is applicable. It is available in the java.lang.annotation package.
  • @Retention – The @Retention annotation indicates that how long the annotation is to be retained with the provided annotated type. It is available in java.lang.annotation package.

Let’s understand the concept of custom validation with the help of an example.

Directory Structure of Custom validation

Spring MVC Form Custom Validation

Example of Custom Validation

Here, we are going to create an example of Custom validation.

Following are the steps to create an example of custom validation:

  • Create a request page

In this step, we are going to create a request page index.jsp.

index.jsp

<html>
<body>
<h2> Spring MVC Web application </h2>
<a href = "cust-regis-form"> Customer Registration Form </a>
</body>
</html> 
  • Create the Model class

In this step, we are going to create the Model class Customer.java, which stores the form data.

Customer.java

 import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Pattern;
import javax.validation.constraints.Size;
import com.SpringMVC.CustomValidation.CollegeCode;
public class Customer {
                private String fname;
                @NotNull
                @Size(min = 3, message = " This field is required ")
                private String lname;
                @Min(value = 1, message = "Tickets must be greater than or equal to 1 ")
                @Max(value = 100, message = "Tickets must be smaller than or equal to 100")
                private int tick ;
                @NotNull(message = "is Required")
                @Pattern(regexp = "^[a-zA-Z0-9]{6}", message = "must be of 6 char/digit")
                private String postal_code;
                @CollegeCode
                private String collegeCode;
                public String getCollegeCode() {
                                return collegeCode;
                }
                public void setCollegeCode(String collegeCode) {
                                this.collegeCode = collegeCode;
                }
                public String getpostal_code() {
                                return postal_code;
                }
                public void setpostal_code(String postal_code) {
                                this.postal_code = postal_code;
                }
                public int gettick() {
                                return tick;
                }
                public void settick(int tick) {
                                this.tick = tick;
                }
                public String getFname() {
                                return fname;
                }
                public void setFname(String fname) {
                                this.fname = fname;
                }
                public String getLname() {
                                return lname;
                }
                public void setLname(String lname) {
                                this.lname = lname;
                }
  } 
  • Create the Controller class

In this step, we are going to create a Controller class MainController.java, which returns the JSP view pages.

MainController.java

 import javax.validation.Valid;
import org.springframework.beans.propertyeditors.StringTrimmerEditor;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class MainController {
                @InitBinder
                public void initBinder(WebDataBinder dataBinder) {
                                StringTrimmerEditor stringEditor = new StringTrimmerEditor(true);
                                dataBinder.registerCustomEditor(String.class,stringEditor );
                }
                @RequestMapping("/cust-regis-form")
                public String showCustomerForm(Model m) {
                                m.addAttribute("customer", new Customer()) ;
                                return "customerform" ;
                }
                @RequestMapping("/processForm")
                public String showCustomerData( @Valid @ModelAttribute("customer") Customer custom,
                                                BindingResult thebindingresult) {
                                                                if (thebindingresult.hasErrors()) {
                                                return "customerform" ;
                                }
                                else {
                                                return "customerformdata" ;
                                }
              }
  } 
  • Create the Validator annotation

In this step, we are going to create the validator annotation for the application. Our validator annotation is CollegeCode, which is going to annotate the collegeCode field.

CollegeCode.java

 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 = Clge_CodeConstraintValidator.class)
@Target({ElementType.METHOD, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface CollegeCode {
                // default college code
                public String value() default "TIPS";
                // default error message
                public String message() default "College code must start with 'TIPS'" ;
                public Class<?>[] groups() default {};
                public Class<? extends Payload>[] payload()  default {};
  } 
  • Create the Validator class

In this step, we are going to create a validator class named Clge_CodeConstraintValidator, which contains the validation code.

Clge_CodeConstraintValidator.java

 import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
public class Clge_CodeConstraintValidator implements ConstraintValidator<CollegeCode, String>
{
                private String collegePrefix;
                public void initialize(CollegeCode thecc) {
                                collegePrefix = thecc.value();
                }
                public boolean isValid(String code, ConstraintValidatorContext context) {
                                boolean result;
                                if(code != null) {
                                                result = code.startsWith(collegePrefix);
                                }
                                else
                                {
                                                result = true;
                                }
                                return result ;
                }
 } 
  • Add the entry of Controller in the web.xml

In this step, we are going to add the entry of the Controller in the web.xml.

web.xml

 <?xml version = "1.0" encoding = "UTF-8"?>
<web-app xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
                xmlns = "http://xmlns.jcp.org/xml/ns/javaee"
                xsi:schemaLocation = "http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
                id = "WebApp_ID" version = "3.1">
                <display-name>spring-mvc-demo</display-name>
                <absolute-ordering />
                <!-- Spring MVC Configs -->
                <!-- Step 1: Configure Spring MVC Dispatcher Servlet -->
                <servlet>
                                <servlet-name>dispatcher</servlet-name>
                                <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
                                <init-param>
                                                <param-name>contextConfigLocation</param-name>
                                                <param-value>/WEB-INF/spring-servlet.xml</param-value>
                                </init-param>
                                <load-on-startup>1</load-on-startup>
                </servlet>
                <!-- Step 2: Set up URL mapping for Spring MVC Dispatcher Servlet -->
                <servlet-mapping>
                                <servlet-name>dispatcher</servlet-name>
                                <url-pattern>/</url-pattern>
                </servlet-mapping>
</web-app> 
  • Define the Model into another XML file

In this step, we are going to add the entry of Model class in another XML file (spring-servlet.xml).

spring-servlet.xml

 <?xml version = "1.0" encoding = "UTF-8"?>
<beans xmlns = "http://www.springframework.org/schema/beans"
                xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
                xmlns:context = "http://www.springframework.org/schema/context"
                xmlns:mvc = "http://www.springframework.org/schema/mvc"
                xsi:schemaLocation = " http://www.springframework.org/schema/beans
                http://www.springframework.org/schema/beans/spring-beans.xsd
                http://www.springframework.org/schema/context
                http://www.springframework.org/schema/context/spring-context.xsd
                http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc.xsd">
                <!-- Step 3: Add support for component scanning -->
                <context:component-scan base-package = "com.app.SpringMVCValidation" />
                <!-- Step 4: Add support for conversion, formatting and validation support -->
                <mvc:annotation-driven/>
                <!-- Step 5: Define Spring MVC view resolver -->
                <bean
                                class="org.springframework.web.servlet.view.InternalResourceViewResolver">
                                <property name = "prefix" value = "/WEB-INF/view/" />
                                <property name = "suffix" value = ".jsp" />
                </bean>
</beans> 
  • Create all the view pages

In this step, we are going to create all the view pages (JSP pages) required in the application.

customerform.jsp

 <%@ taglib prefix = "form" uri = "http://www.springframework.org/tags/form" %>
<!DOCTYPE html>
<html>
<head>
<meta charset = "ISO-8859-1">
<title> Customer Form </title>
<style>
     .error {color:blue}
</style>
</head>
<body>
<h3><i>The field with Asterisk(*) mark is required.</i></h3>
<form:form action = "processForm" modelAttribute = "customer" >
FIRST NAME: <form:input path = "fname" />
<br></br>
LAST NAME (*): <form:input path = "lname" />
  <form:errors path = "lname" cssClass = "error" >
  </form:errors>
<br> </br>
TICKETS: <form:input path = "tick" />
     <form:errors path = "tick" cssClass = "error">
    </form:errors>
    <br> </br>
POSTAL CODE (*): <form:input path = "postal_code" />
   <form:errors path = "postal_code" cssClass = "error">
   </form:errors>
<br></br>
COLLEGE CODE: <form:input path = "collegeCode" />
   <form:errors path = "collegeCode" cssClass = "error">
   </form:errors>
 <br> </br> 
<input type = "submit" value = "Submit" />
 </form:form>
</body>
</html> 

customerformdata.jsp

 <%@ taglib prefix = "c"  uri = "http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
<title>Customer data</title>
</head>
<body>
The customer is confirmed: ${customer.fname} ${customer.lname}
<br> </br>
Tickets : ${customer.tick}
<br> </br>
Postal Code: ${customer.postal_code}
<br> </br>
College Code: ${customer.collegeCode}
</body>
</html> 

Output

Spring MVC Form Custom Validation 1
Spring MVC Form Custom Validation 2
Spring MVC Form Custom Validation 3
Spring MVC Form Custom Validation 4
Spring MVC Form Custom Validation 5