Thursday 29 November 2018

Spring web mvc: Form validation

Spring supports JSR 380 bean validation specification. In any application, validating data is a common task. Many times, we end up in writing same validation logic at many places (including presentation layer, Business layer, Data Access layer, service layer, persistence layer etc.,). To avoid these kinds of duplications, make the validations robust, JCP (Java Community Process) approves a JSR (Java Specification request) to validate beans.

Below table summarizes the bean validation JSRs approved by JCP. At the time of writing this article, JSR 380 is the latest specification approved by JCP.

JSR
Description
JSR 303
This JSR will define a meta-data model and API for JavaBeanTM validation based on annotations, with overrides and extended meta-data through the use of XML validation descriptors.
JSR 349
It is enhanced version of JSR 303
JSR 380
At the time of writing this article, It is the latest standard on bean validations. It leverages the language features in Java8. If you want to use JSR 380 features in your application, Java8 is the minimum requirement.

How to use JSR-380 bean validation APIS in spring
First of all, you require a JSR-380 specification implementation library. I am going to use hibernate-validator api, it implements JSR-380 specification.

                  <!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-validator -->
                  <dependency>
                           <groupId>org.hibernate</groupId>
                           <artifactId>hibernate-validator</artifactId>
                           <version>6.0.10.Final</version>
                  </dependency>

                  <!-- https://mvnrepository.com/artifact/javax.validation/validation-api -->
                  <dependency>
                           <groupId>javax.validation</groupId>
                           <artifactId>validation-api</artifactId>
                           <version>2.0.1.Final</version>
                  </dependency>

Now, you can use JSR-380 validation annotation on model class.

For example,

public class Student {

         @Size(min = 3, max = 30, message = "User name must be between 3 and 30")
         private String userName;

         @DecimalMax(value="40", message="Age must be less than or equal to 40")
         private int age;
        
}

I set
a.   userName length should be minimum 3 characters and maximum 30 characters.
b.   Student maximum age should be less than or equal to 40.

Now we need to tell the spring that, we want to validate the spring model object using JSR-380 specification. You can specify that by using @Valid annotation.

@RequestMapping("/registerMe")
public ModelAndView getHelloMessage(@Valid @ModelAttribute("studentInfo") Student student, BindingResult bindingResult) {
        
}

As you see above snippet, I added @Valid annotation on student model object.

Final step is you should add below annotation in dispatcher servlet file.
<mvc:annotation-driven />

Find the below working application.

HelloWorldController.java
package com.sample.myApp.controllers;

import javax.validation.Valid;

import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

import com.sample.myApp.model.Student;

@Controller
public class HelloWorldController {

 @RequestMapping("/registration")
 public String getRegistrationpage() {
  return "registration";
 }

 @RequestMapping("/registerMe")
 public ModelAndView getHelloMessage(@Valid @ModelAttribute("studentInfo") Student student,
   BindingResult bindingResult) {
  if (bindingResult.hasErrors()) {
   ModelAndView modelAndView = new ModelAndView("registration");
   return modelAndView;
  }

  ModelAndView modelAndView = new ModelAndView("welcome");

  modelAndView.addObject("message", "Dear User, your details are registered");

  return modelAndView;
 }

}

Student.java
package com.sample.myApp.model;

import java.util.Date;
import java.util.List;

import javax.validation.constraints.DecimalMax;
import javax.validation.constraints.Size;

public class Student {

 @Size(min = 3, max = 30, message = "User name must be between 3 and 30")
 private String userName;

 @DecimalMax(value="40", message="Age must be less than or equal to 40")
 private int age;

 private List<String> hobbies;
 private Date dateOfBirth;

 public Date getDateOfBirth() {
  return dateOfBirth;
 }

 public void setDateOfBirth(Date dateOfBirth) {
  this.dateOfBirth = dateOfBirth;
 }

 public String getUserName() {
  return userName;
 }

 public void setUserName(String userName) {
  this.userName = userName;
 }

 public int getAge() {
  return age;
 }

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

 public List<String> getHobbies() {
  return hobbies;
 }

 public void setHobbies(List<String> hobbies) {
  this.hobbies = hobbies;
 }

}

Create registration.jsp, welcome.jsp files under WEB-INF/jsp folder.


registration.jsp
<%@taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<html>
<head>
<title>User Information Page</title>
</head>

<body>
 <h2 style="color:red;"><form:errors path="studentInfo.*" /></h2>

 <form method="post" action="/springdemo/registerMe" id="f1">
  <table>
   <tr>
    <td>User Name :</td>
    <td><input type="text" name="userName" value="" /></td>
   </tr>
   <tr>
    <td>Age :</td>
    <td><input type="text" name="age" value="" /></td>
   </tr>
   <tr>
    <td>Hobbies :</td>
    <td><select multiple name="hobbies">
      <option value="cricket">Cricket</option>
      <option value="chess">Chess</option>
      <option value="football">Football</option>
      <option value="tennis">Tennis</option>
    </select></td>
   </tr>
   
   <tr>
    <td>Date Of Birth</td>
    <td><input type="text" name="dateOfBirth" value="" /></td>
   </tr>
   <tr>
    <td><input type="submit" name="submit" value="submit"
     style="font-size: 18px;" /></td>
   </tr>
  </table>
 </form>

</body>
</html>

welcome.jsp
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
 pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Hello World Spring Web MVC</title>
</head>
<body>
 <h1>${message}</h1>

 <h3>
  User Name : ${studentInfo.userName} <br /> 
  Age : ${studentInfo.age} <br />
  Hobbies: ${studentInfo.hobbies} <br />
  Date Of Birth: ${studentInfo.dateOfBirth}
 </h3>
</body>
</html>

Create web.xml, HelloWorld-servlet.xml files under WEB-INF folder.


web.xml
<web-app id="WebApp_ID" version="2.4"
 xmlns="http://java.sun.com/xml/ns/j2ee"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee 
   http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">

 <display-name>Spring MVC Hello WorldApplication</display-name>

 <servlet>
  <servlet-name>HelloWorld</servlet-name>
  <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
  <load-on-startup>1</load-on-startup>
 </servlet>

 <servlet-mapping>
  <servlet-name>HelloWorld</servlet-name>
  <url-pattern>/</url-pattern>
 </servlet-mapping>

</web-app>

HelloWorld-servlet.xml
<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:context="http://www.springframework.org/schema/context"
 xmlns:mvc="http://www.springframework.org/schema/mvc"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="
        http://www.springframework.org/schema/beans     
        http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/context 
        http://www.springframework.org/schema/context/spring-context-3.0.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">
        
 <mvc:annotation-driven />

 <context:component-scan
  base-package="com.sample.myApp" />

 <bean
  class="org.springframework.web.servlet.view.InternalResourceViewResolver">
  <property name="prefix" value="/WEB-INF/jsp/" />
  <property name="suffix" value=".jsp" />
 </bean>

</beans>

Create index.jsp file under webapp folder.


index.jsp
<%@taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<html>
<head>
<title>Welcome Page</title>
</head>

<body>
 <h3>Dear Student, click on below button to register yourself</h3>
 <form method="post" action="/springdemo/registration" id="f1">
  <input type="submit" name="submit" value="submit"
   style="font-size: 18px;" />
 </form>
</body>
</html>

Add maven dependencies in pom.xml file


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/maven-v4_0_0.xsd">
 <modelVersion>4.0.0</modelVersion>
 <groupId>springdemo</groupId>
 <artifactId>springdemo</artifactId>
 <packaging>war</packaging>
 <version>1</version>
 <name>springdemo Maven Webapp</name>
 <url>http://maven.apache.org</url>
 <dependencies>
  <dependency>
   <groupId>junit</groupId>
   <artifactId>junit</artifactId>
   <version>3.8.1</version>
   <scope>test</scope>
  </dependency>

  <!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
  <dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-webmvc</artifactId>
   <version>5.0.6.RELEASE</version>
  </dependency>

  <!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-validator -->
  <dependency>
   <groupId>org.hibernate</groupId>
   <artifactId>hibernate-validator</artifactId>
   <version>6.0.10.Final</version>
  </dependency>

  <!-- https://mvnrepository.com/artifact/javax.validation/validation-api -->
  <dependency>
   <groupId>javax.validation</groupId>
   <artifactId>validation-api</artifactId>
   <version>2.0.1.Final</version>
  </dependency>

 </dependencies>
 <build>
  <finalName>springdemo</finalName>
 </build>
</project>

Project structure looks like below.


Run the application server. You can able to see below screen,
Click on submit button, you can able to see below form window.

I enter Age as 45, user name is ‘AM’, When I click on submit button, spring uses Hibernate-validator api and perform validations.



Previous                                                 Next                                                 Home

No comments:

Post a Comment