Spring MVC form handling example

In Spring MVC, form controller is used to handle the form submission task (binding values to/from Spring’s form tags). Often times, you may just need to extend the SimpleFormController to inherit the form handling ability.

1. Binding Values

In SimpleFormController, you need to tell Spring about how form controller will binds the value to/from the HTML form’s components. See code snippet :

public class YourController extends SimpleFormController{
	//...
	public CustomerController(){
		setCommandClass(Customer.class);
		setCommandName("customerForm");
	}
  1. setCommandClass(Customer.class) – Form’s values will store into this Customer object.
  2. setCommandName(“customerForm”) – If HTML form action value with named “customerForm” is submitted, Spring will forward request to this form controller.

2. Form submission

When HTML form is submitted, form controller’s onSubmit() method will be executed, to handle the submitted form’s value and return a ModelAndView if success. So, onSubmit() method is the ideal place to perform form submission business logic.

public class YourController extends SimpleFormController{
	//...
	@Override
	protected ModelAndView onSubmit(HttpServletRequest request,
		HttpServletResponse response, Object command, BindException errors)
		throws Exception {
 
		Customer customer = (Customer)command;
		System.out.println(customer);
		return new ModelAndView("CustomerSuccess","customer",customer);
	}

3. Initialization

In some cases, you may need to initialize the form component values before render the page, like default value for HTML form component. To do this, just override the formBackingObject() method.

public class YourController extends SimpleFormController{
	//...
	@Override
	protected Object formBackingObject(HttpServletRequest request)
		throws Exception {
 
		Customer cust = new Customer();
		cust.setFavFramework(new String []{"Spring MVC"});
		return cust;
	}
Note
This technique is useful to set a default selected value for HTML components, like checkbox , radio button or select options.

4. Data Referencing

Provide a list of data for HTML components, like checkbox , radio button or select options. To do this, just override the referenceData() method.

public class YourController extends SimpleFormController{
	//...
	@Override
	protected Map referenceData(HttpServletRequest request) throws Exception {
		Map referenceData = new HashMap();
		List<String> webFrameworkList = new ArrayList<String>();
		webFrameworkList.add("Spring MVC");
		webFrameworkList.add("Struts 1");
		webFrameworkList.add("Struts 2");
		referenceData.put("webFrameworkList", webFrameworkList);
		return referenceData;
	}

5. SimpleFormController bean

Finally, declares the SimpleFormController bean and override the “formView” and “successView” property value.

  1. formView – Indicate the form page that will shows to the user. If validation failed, the controller will return this page to the user as well.
  2. successView – If the form is submitted successful, return this page to the user.

With below InternalResourceViewResolver declared :

	<bean class="com.mkyong.customer.controller.CustomerController">
		<property name="formView" value="CustomerForm" />
		<property name="successView" value="CustomerSuccess" />
	</bean>
 
	<bean id="viewResolver"
             class="org.springframework.web.servlet.view.InternalResourceViewResolver" >
             <property name="prefix">
                 <value>/WEB-INF/pages/</value>
             </property>
             <property name="suffix">
                 <value>.jsp</value>
             </property>
       </bean>
  1. “formView” will redirect to “/WEB-INF/pages/CustomerForm.jsp”.
  2. “successView” will redirect to “/WEB-INF/pages/CustomerSuccess.jsp”.

Spring MVC form handling example

In this example, it will use the Spring’s form tags to render the textbox, password, textarea, checkbox, radio button, select option and hidden value field. And all the submitted form values will be handle by the SimpleFormController. Additionally, attach a simple validator to do the empty checking on the HTML form components, if the validation failed, use the form’s error tag to output the error message associated with the field. By studying this example, you should have a very good understanding of the form handling in Spring MVC.

1. Model

A Customer model object for the demonstration.

File : Customer.java

package com.mkyong.customer.model;
 
public class Customer{
 
	//textbox
	String userName;
 
	//textarea
	String address;
 
	//password
	String password;
	String confirmPassword;
 
	//checkbox
	boolean receiveNewsletter;
	String [] favFramework;
 
	//radio button
	String favNumber;
	String sex;
 
	//dropdown box
	String country;
	String javaSkills;
 
	//hidden value
	String secretValue;
 
	//getter and setter methods
}

2. Form Controller

A SimpleFormController class to handle the form submission.

File : CustomerController.java

package com.mkyong.customer.controller;
 
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.validation.BindException;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.SimpleFormController;
import com.mkyong.customer.model.Customer;
 
public class CustomerController extends SimpleFormController{
 
	public CustomerController(){
		setCommandClass(Customer.class);
		setCommandName("customerForm");
	}
 
	@Override
	protected ModelAndView onSubmit(HttpServletRequest request,
		HttpServletResponse response, Object command, BindException errors)
		throws Exception {
 
		Customer customer = (Customer)command;
		System.out.println(customer);
		return new ModelAndView("CustomerSuccess","customer",customer);
 
	}
 
	@Override
	protected Object formBackingObject(HttpServletRequest request)
		throws Exception {
 
		Customer cust = new Customer();
		//Make "Spring MVC" as default checked value
		cust.setFavFramework(new String []{"Spring MVC"});
 
		//Make "Make" as default radio button selected value
		cust.setSex("M");
 
		//make "Hibernate" as the default java skills selection
		cust.setJavaSkills("Hibernate");
 
		//initilize a hidden value
		cust.setSecretValue("I'm hidden value");
 
		return cust;
	}
 
	@Override
	protected Map referenceData(HttpServletRequest request) throws Exception {
 
		Map referenceData = new HashMap();
 
		//Data referencing for web framework checkboxes
		List<String> webFrameworkList = new ArrayList<String>();
		webFrameworkList.add("Spring MVC");
		webFrameworkList.add("Struts 1");
		webFrameworkList.add("Struts 2");
		webFrameworkList.add("JSF");
		webFrameworkList.add("Apache Wicket");
		referenceData.put("webFrameworkList", webFrameworkList);
 
		//Data referencing for number radiobuttons
		List<String> numberList = new ArrayList<String>();
		numberList.add("Number 1");
		numberList.add("Number 2");
		numberList.add("Number 3");
		numberList.add("Number 4");
		numberList.add("Number 5");
		referenceData.put("numberList", numberList);
 
		//Data referencing for country dropdown box
		Map<String,String> country = new LinkedHashMap<String,String>();
		country.put("US", "United Stated");
		country.put("CHINA", "China");
		country.put("SG", "Singapore");
		country.put("MY", "Malaysia");
		referenceData.put("countryList", country);
 
		//Data referencing for java skills list box
		Map<String,String> javaSkill = new LinkedHashMap<String,String>();
		javaSkill.put("Hibernate", "Hibernate");
		javaSkill.put("Spring", "Spring");
		javaSkill.put("Apache Wicket", "Apache Wicket");
		javaSkill.put("Struts", "Struts");
		referenceData.put("javaSkillsList", javaSkill);
 
		return referenceData;
	}
}

3. Form Validator

A form validator class to do the empty checking on the HTML components. If validation failed, get the error message from resource bundle, and associate it with the corresponds error field.

Note
In form views, you can use the <form:errors /> to renders and format the error message that is associated with the field.
package com.mkyong.customer.validator;
 
import org.springframework.validation.Errors;
import org.springframework.validation.ValidationUtils;
import org.springframework.validation.Validator;
import com.mkyong.customer.model.Customer;
 
public class CustomerValidator implements Validator{
 
	@Override
	public boolean supports(Class clazz) {
		//just validate the Customer instances
		return Customer.class.isAssignableFrom(clazz);
	}
 
	@Override
	public void validate(Object target, Errors errors) {
 
		ValidationUtils.rejectIfEmptyOrWhitespace(errors, "userName",
			"required.userName", "Field name is required.");
		ValidationUtils.rejectIfEmptyOrWhitespace(errors, "address",
			"required.address", "Field name is required.");
		ValidationUtils.rejectIfEmptyOrWhitespace(errors, "password",
			"required.password", "Field name is required.");
		ValidationUtils.rejectIfEmptyOrWhitespace(errors, "confirmPassword",
			"required.confirmPassword", "Field name is required.");
		ValidationUtils.rejectIfEmptyOrWhitespace(errors, "sex", 
			"required.sex", "Field name is required.");
		ValidationUtils.rejectIfEmptyOrWhitespace(errors, "favNumber", 
			"required.favNumber", "Field name is required.");
		ValidationUtils.rejectIfEmptyOrWhitespace(
			errors, "javaSkills", "required.javaSkills","Field name is required.");
 
		Customer cust = (Customer)target;
 
		if(!(cust.getPassword().equals(cust.getConfirmPassword()))){
			errors.rejectValue("password", "notmatch.password");
		}
		if(cust.getFavFramework().length==0){
			errors.rejectValue("favFramework", "required.favFrameworks");
		}
		if("NONE".equals(cust.getCountry())){
			errors.rejectValue("country", "required.country");
		}
	}
}

A properties file to store all the error messages.

File : Customer.properties

required.userName = Username is required!
required.address = Address is required!
required.password = Password is required!
required.confirmPassword = Confirm password is required!
required.favFrameworks = Please select at least a web frameworks!
required.sex = Please select a sex!
required.favNumber = Please select a number!
notmatch.password = Password and Conform password is not match!

4. View

This is the “formView“, render the HTML components with Spring’s form tags, display and highlight the error message if any.

File : CustomerForm.jsp

<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<html>
<head>
<style>
.error {
	color: #ff0000;
}
 
.errorblock {
	color: #000;
	background-color: #ffEEEE;
	border: 3px solid #ff0000;
	padding: 8px;
	margin: 16px;
}
</style>
</head>
<body>
	<h2>Spring's form tags example</h2>
 
	<form:form method="POST" commandName="customerForm">
		<form:errors path="*" cssClass="errorblock" element="div" />
		<table>
			<tr>
				<td>UserName :</td>
				<td><form:input path="userName" />
				</td>
				<td><form:errors path="userName" cssClass="error" />
				</td>
			</tr>
			<tr>
				<td>Address :</td>
				<td><form:textarea path="address" />
				</td>
				<td><form:errors path="address" cssClass="error" />
				</td>
			</tr>
			<tr>
				<td>Password :</td>
				<td><form:password path="password" />
				</td>
				<td><form:errors path="password" cssClass="error" />
				</td>
			</tr>
			<tr>
				<td>Confirm Password :</td>
				<td><form:password path="confirmPassword" />
				</td>
				<td><form:errors path="confirmPassword" cssClass="error" />
				</td>
			</tr>
			<tr>
				<td>Subscribe to newsletter? :</td>
				<td><form:checkbox path="receiveNewsletter" />
				</td>
				<td><form:errors path="receiveNewsletter" cssClass="error" />
				</td>
			</tr>
			<tr>
				<td>Favourite Web Frameworks :</td>
				<td><form:checkboxes items="${webFrameworkList}"
					path="favFramework" /></td>
				<td><form:errors path="favFramework" cssClass="error" />
				</td>
			</tr>
			<tr>
				<td>Sex :</td>
				<td><form:radiobutton path="sex" value="M" />Male 
                                       <form:radiobutton path="sex" value="F" />Female</td>
				<td><form:errors path="sex" cssClass="error" />
				</td>
			</tr>
			<tr>
				<td>Choose a number :</td>
				<td><form:radiobuttons path="favNumber" items="${numberList}" />
				</td>
				<td><form:errors path="favNumber" cssClass="error" />
				</td>
			</tr>
			<tr>
				<td>Country :</td>
				<td><form:select path="country">
					   <form:option value="NONE" label="--- Select ---" />
					   <form:options items="${countryList}" />
					</form:select></td>
				<td><form:errors path="country" cssClass="error" />
				</td>
			</tr>
			<tr>
				<td>Java Skills :</td>
				<td><form:select path="javaSkills" items="${javaSkillsList}"
					multiple="true" /></td>
				<td><form:errors path="javaSkills" cssClass="error" />
				</td>
			</tr>
			<form:hidden path="secretValue" />
			<tr>
				<td colspan="3"><input type="submit" /></td>
			</tr>
		</table>
	</form:form>
 
</body>
</html>

This is the “successView“, renders all the submitted values.

Fie : CustomerSuccess.jsp

<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
 
<html>
<body>
	<h2>Spring's form tags example</h2>
 
	<table>
		<tr>
			<td>UserName :</td>
			<td>${customer.userName}</td>
		</tr>
		<tr>
			<td>Address :</td>
			<td>${customer.address}</td>
		</tr>
		<tr>
			<td>Password :</td>
			<td>${customer.password}</td>
		</tr>
		<tr>
			<td>Confirm Password :</td>
			<td>${customer.confirmPassword}</td>
		</tr>
		<tr>
			<td>Receive Newsletter :</td>
			<td>${customer.receiveNewsletter}</td>
		</tr>
		<tr>
			<td>Favourite Web Frameworks :</td>
			<td><c:forEach items="${customer.favFramework}" var="current">
				   [<c:out value="${current}" />]
				</c:forEach>
			</td>
		</tr>
		<tr>
			<td>Sex :</td>
			<td>${customer.sex}</td>
		</tr>
		<tr>
			<td>Favourite Number :</td>
			<td>${customer.favNumber}</td>
		</tr>
		<td>Java Skills :</td>
		<td>${customer.javaSkills}</td>
		</tr>
		<tr>
			<td>Hidden Value :</td>
			<td>${customer.secretValue}</td>
		</tr>
		<tr>
			<td>Hidden Value :</td>
			<td>${customer.secretValue}</td>
		</tr>
	</table>
 
</body>
</html>

5. Spring Bean Configuration

Finally, link the properties file, validator and form controller together.

<beans xmlns="http://www.springframework.org/schema/beans"
	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-2.5.xsd">
 
  <bean 
  class="org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping" />
 
  <bean class="com.mkyong.customer.controller.CustomerController">
	<property name="formView" value="CustomerForm" />
	<property name="successView" value="CustomerSuccess" />
 
	<!-- Map a validator -->
	<property name="validator">
		<bean class="com.mkyong.customer.validator.CustomerValidator" />
	</property>
  </bean>
 
  <!-- Register the Customer.properties -->
  <bean id="messageSource"
	class="org.springframework.context.support.ResourceBundleMessageSource">
	<property name="basename" value="com/mkyong/customer/properties/Customer" />
  </bean>
 
  <bean id="viewResolver"
       class="org.springframework.web.servlet.view.InternalResourceViewResolver" >
       <property name="prefix">
             <value>/WEB-INF/pages/</value>
        </property>
        <property name="suffix">
             <value>.jsp</value>
        </property>
  </bean>
</beans>

6. Demo

Access the page – http://localhost:8080/SpringMVC/customer.htm

SpringMVC-Form-Handle-Example-1

If the user failed the validation, display and highlight the error message.

SpringMVC-Form-Handle-Example-2

If the form is submitted successfully, just display all the submitted values.

SpringMVC-Form-Handle-Example-3

Download Source Code

References

  1. http://static.springsource.org/spring/docs/2.5.x/reference/mvc.html
  2. http://static.springsource.org/spring/docs/2.5.x/api/org/springframework/web/servlet/mvc/SimpleFormController.html
  3. http://static.springsource.org/spring/docs/2.5.x/api/org/springframework/validation/Validator.html
  4. http://static.springsource.org/spring/docs/2.5.x/api/org/springframework/validation/ValidationUtils.html
  5. http://static.springsource.org/spring/docs/2.5.x/reference/validation.html
Tags :

About the Author

mkyong
Founder of Mkyong.com and HostingCompass.com, love Java and open source stuff. Follow him on Twitter, or befriend him on Facebook or Google Plus. If you like my tutorials, consider make a donation to these charities.

Comments

  • Pingback: ionizer loans()

  • Pingback: payment plan()

  • Pingback: more helpful hints()

  • Pingback: house blue()

  • Pingback: Spring MVC Tutorial()

  • Pingback: i d godwin plumbers cheltenham()

  • Pingback: locksmith odessa tx()

  • Pingback: locksmith odessa tx()

  • Pingback: electrical license renewal in texas()

  • Pingback: electrician hourly wage()

  • Pingback: pay per day loan plans()

  • Pingback: alkaline water brands()

  • Pingback: water ionizer plans()

  • Pingback: water ionizer()

  • Pingback: parking()

  • Pingback: laan penge nu og her()

  • Pingback: parking()

  • Pingback: laan penge billigt()

  • Pingback: DIRECTV()

  • Pingback: enagic kangen water()

  • Pingback: kangen water()

  • Pingback: watch movies online()

  • Pingback: watch movies online()

  • Pingback: free movie downloads()

  • Pingback: watch tv show episodes()

  • Pingback: how to increase leptin()

  • Pingback: Blue Coaster33()

  • Jolly Tilo

    Hey Myong,

    1 You forgot to specify the /welcome.htm in the bean for the xxxx-xxxx-servlet.xml. This causes A LOT for confusion making this tutorial USELESS and a headache. With this any xxxx.htm that was included would go to this Controller.

    2. Also you did not specify a “How it works” portion. Making this NOT a tutorial but just a sample code with lacking explanation.

    3. Lastly, yo did not explain WHY THE HELL should the for go to , than ?
    Yes it goes for CustomerForm first but WHY? There nothing seems to specifically indicate it in the code.

    THIS TUTORIAL IS USELESS!!! AND A WASTE OF TIIME!!

  • Ariel

    Hi Yong, in mvc-dispatcher-servlet.xml, you have declared CustomerForm, CustomerSuccess,and CustomerValidator as the properties of CustomerController.How can we declare these as properties of CustomerController. I couldn’t understand this. Can you help me in this regard.

    Thanks

    • Max

      you may refer to the springframe work api. look for the Exposed configuration properties (and those defined by superclass) section along the inheritance hierarchy

  • http://porno-sur-mobile.net Anonymous

    Thank you for sharing your info. I really appreciate your
    efforts and I am waiting for your next post thank you once again.

  • http://sejoe.com/index.php?option=com_blog&view=comments&pid=659963&Itemid=0 free sex cam and chat

    Hi just wanted to give you a quick heads up and let you
    know a few of the images aren’t loading properly. I’m not sure why but I think its a linking issue.
    I’ve tried it in two different web browsers and both show the same results.

  • https://qik.com/grapecornet31 free live adult

    Hi there! I know this is kind of off topic but I was
    wondering if you knew where I could locate a captcha plugin for
    my comment form? I’m using the same blog platform as yours and I’m having trouble
    finding one? Thanks a lot!

  • http://sel2in.com Tushar

    do you have a tutorial on spring 4? plus some notes on what is better?

  • Lakshman

    Hi,Yong u did an excellent work. I am very thank full to you .
    But,I have a small Problem ie if i didn’t specify BeanNameUrlHandlerMapping in mvc-dispatcher-servlet.xml then it throw an WARNING saying that
    WARNING: No mapping found for HTTP request with URI [/SpringMvcSample/welcome.htm] in DispatcherServlet with name ‘dispatcher’.
    if i place

    then not a problem it is working fine.

    But using annotation it is not working fine please help me.
    thank you.