Spring MVC Form Validation Tutorial and Example

This tutorial walks you through the step by step instructions in order to support and apply validation example in Spring MVC. Please see Spring MVC Hello World Example to setup spring MVC environment.


  • Required Libraries
      Following libraries will be required over and above your existing spring setup in order to run this example

           spring-modules-validation-0.6.jar

  • spring-config.xml
Let's create a spring configuration file in order to declare and configure various required beans as follow.

<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"
 xsi:schemaLocation="http://www.springframework.org/schema/beans 
 http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
 ">
  
 <context:annotation-config />
 <context:component-scan base-package="com.mycompany.myapp.controller" />
 
 <bean id="viewResolver"
     class="org.springframework.web.servlet.view.InternalResourceViewResolver" >
        <property name="prefix">
            <value>/jsp/</value>
        </property>
        <property name="suffix">
            <value>.jsp</value>
        </property>
    </bean>
 
</beans>


  • Sample Login.jsp

Let's create a sample login.jsp under $WebRoot/jsp folder. This will submit a POST request and will show validation messages in red beside username and password text boxes if user enters invalid values for them and submits the page by clicking Login button .here <form:errros> tag will display validation messages if any. It will not display any message if there is no errors.

<%@taglib uri="http://www.springframework.org/tags" prefix="spring"%>
<%@taglib uri="http://www.springframework.org/tags/form" prefix="form"%>
<html>
<head>
    <title>Spring 3 MVC Series - Login Validation Example</title>
</head>
<body>
 
<form:form method="post" action="login.do" commandName="loginModel">
    <table>
    <tr>
        <td>Username : </td>
  <td><form:input path="username" /></td>
  <td><form:errors path="username" /></td>
 </tr>
    <tr>
        <td>Password : </td>
        <td><form:input path="password" /></td>
        <td><form:errors path="password"/></td>
    </tr>
     <tr>
        <td colspan="3">
            <input type="submit" value="Login"/>
        </td>
    </tr>
</table>  
</form:form>
</body>
</html>



  • LoginModel
Let's create a LoginModel class which represents a model consisting of username and password as its fields

package com.mycompany.myapp.model;

import org.springmodules.validation.bean.conf.loader.annotation.handler.Length;
import org.springmodules.validation.bean.conf.loader.annotation.handler.NotBlank;

public class LoginModel{

 @NotBlank
 private String username;
 
 @NotBlank
 private String password;

 public String getUsername() {
  return username;
 }

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

 public String getPassword() {
  return password;
 }

 public void setPassword(String password) {
  this.password = password;
 }
 
}

Make sure the field names of LoginModel class matches with that of path attributes under <form:input> tag in above login.jsp. See how username and password fields are annotated for not blank values. Explore various such annotations under org.springmodules.validation.bean.conf.loader.annotation.handler package of spring-modules-validation-0.6.jar.

  • LoginController
Let's create a LoginController which will handle login requests. 

package com.mycompany.myapp.controller;

package com.mycompany.myapp.controller;

import javax.servlet.http.HttpServletRequest;

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.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;
import org.springmodules.validation.bean.BeanValidator;
import org.springmodules.validation.bean.conf.loader.annotation.AnnotationBeanValidationConfigurationLoader;

import com.mycompany.myapp.model.LoginModel;

@Controller
public class LoginController {
 private BeanValidator beanValidator = new BeanValidator(new AnnotationBeanValidationConfigurationLoader());
 
 @RequestMapping(value="/login.do",method=RequestMethod.GET)
 protected ModelAndView showLoginPage(HttpServletRequest request
  ) throws Exception {
 
  ModelAndView model = new ModelAndView("login");
  model.getModelMap().put("loginModel", new LoginModel());
  return model;
 }
 
 @RequestMapping(value="/login.do",method=RequestMethod.POST)
 protected ModelAndView doLogin(@ModelAttribute("loginModel") LoginModel loginModel, BindingResult bindingResult){
  beanValidator.validate(loginModel, bindingResult);
  if (bindingResult.hasErrors()){
   ModelAndView model = new ModelAndView("login");
   return model;
  }
  ModelAndView model = new ModelAndView("home");
  return model;
 }
 
}


When login page is opened (http://{hostname}:{port}/{webcontext}/jsp/login.jsp, it will call showLoginPage method and will bind LoginModel class with 'loginModel' command declared in <form:form> tag of login.jsp. And when user clicks Login button, doLogin method will be called and its parameter loginModel will contain values entered by user in login.jsp.



  • Error Messages
'not.blank' is the default message. You can override this by providing your custom message in @NotBlank annotation.


If you want to externalize the message into properties file with i18n, then define a key as '@AnnotationName.object.fieldname'. For example,

NotBlank.loginModel.username = Username cannot be blank
NotBlank.loginModel.password = Password cannot be blank


Please see Spring MVC Internationalization Example  to know how to support internationalization in spring mvc so that you can create properties files and define these error messages in it.

3 comments:

  1. Is there a clean way to add client side validation? Or is it for now just hack the form submit and mix Jquery code before submission to achieve it?

    ReplyDelete
  2. As a best or standard practice, both client and server should have validations. The reason is there could be external client using the server and it may be submitting invalid values OR some intruders capturing server requests and changing them to have invalid values.

    ReplyDelete
  3. Why you are using
    both tags.

    Second one is enough right.

    ReplyDelete