Spring MVC provides powerful way to manage form inputs. It also provides form validation functionality which is easy to integrate in any application. But other than the normal form bean mapping, recently I had a requirement to map dynamic values like key-value pairs in an HTML form and retrieve the same in Spring Controller. So basically HashMap came to rescue. Let us see how to map a key-value pair based HashMap in a Spring command object using Spring MVC. The example will show a simple form which renders a Map.
Related: Spring 3 MVC Tutorial Series (Must Read)
Tools and Technologies
- Java 5 or above
- Eclipse 3.3 or above
- Spring MVC 3.0
Step 1: Create Project Structure
Open Eclipse and create a Dynamic Web Project.
Enter project name as SpringMVC_Hashmap and press Finish.
Step 2: Copy Required JAR files
Once the Dynamic Web Project is created in Eclipse, copy the required JAR files under WEB-INF/lib folder. Following are the list of JAR files:
Don’t worry if you dont have these JARs. You can download all the JAR files with complete source code at the end of this tutorial.
Step 3: Adding Spring MVC support
Once the basic project setup is done, we will add Spring 3 MVC support. For that first modify default web.xml and add springs DispatcherServlet.
File: /WebContent/WEB-INF/web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
id="WebApp_ID" version="2.5">
<display-name>Spring3MVC-Hashmap</display-name>
<servlet>
<servlet-name>spring</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>spring</servlet-name>
<url-pattern>*.html</url-pattern>
</servlet-mapping>
</web-app>
Code language: HTML, XML (xml)
Related: Tutorial: Learn Spring MVC Lifecycle
Now add spring-servlet.xml file under WEB-INF folder.
File: /WebContent/WEB-INF/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">
<context:annotation-config />
<context:component-scan base-package="net.viralpatel.spring3.controller" />
<bean id="jspViewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass"
value="org.springframework.web.servlet.view.JstlView" />
<property name="prefix" value="/WEB-INF/jsp/" />
<property name="suffix" value=".jsp" />
</bean>
</beans>
Code language: HTML, XML (xml)
Note that in above spring-servlet file, line 10, 11 defines context:annotation-config and component-scan tags. These tags let Spring MVC knows that the spring mvc annotations are used to map controllers and also the path from where the controller files needs to be loaded. All the files below package net.viralpatel.spring3.controller
will be picked up and loaded by spring mvc.
Step 4: Add Spring Controller and Form classes
File: /src/net/viralpatel/spring3/form/ContactForm.java
package net.viralpatel.spring3.form;
import java.util.HashMap;
import java.util.Map;
public class ContactForm {
private Map<String, String> contactMap = new HashMap<String, String>();
public Map<String, String> getContactMap() {
return contactMap;
}
public void setContactMap(Map<String, String> contactMap) {
this.contactMap = contactMap;
}
}
Code language: Java (java)
Note line 8 in above code how we have defined a HashMap which will hold the key-value pair data.
File: /src/net/viralpatel/spring3/controller/ContactController.java
package net.viralpatel.spring3.controller;
import java.util.HashMap;
import java.util.Map;
import net.viralpatel.spring3.form.ContactForm;
import org.springframework.stereotype.Controller;
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;
@Controller
public class ContactController {
private static Map<String, String> contactMap = new HashMap<String, String>();
static {
contactMap.put("name", "John");
contactMap.put("lastname", "Lennon");
contactMap.put("genres", "Rock, Pop");
}
@RequestMapping(value = "/show", method = RequestMethod.GET)
public ModelAndView get() {
ContactForm contactForm = new ContactForm();
contactForm.setContactMap(contactMap);
return new ModelAndView("add_contact" , "contactForm", contactForm);
}
@RequestMapping(value = "/add", method = RequestMethod.POST)
public ModelAndView save(@ModelAttribute("contactForm") ContactForm contactForm) {
return new ModelAndView("show_contact", "contactForm", contactForm);
}
}
Code language: Java (java)
In above ContactController class, we have defile two methods: get()
and save()
. get() method: This method is used to display Contact form with pre-populated values. Note we added a map of contacts (Contacts map is initialized in static block) in ContactForm
bean object and set this inside a ModelAndView
object. The add_contact.jsp is displayed which in turns display all contacts in tabular form to edit. save() method: This method is used to fetch contact data from the form submitted and save it in the static map. Also it renders show_contact.jsp
file to display contacts in tabular form.
Step 5: Add JSP View files
Add following files under WebContent/WEB-INF/jsp/ directory.
File: /WebContent/WEB-INF/jsp/add_contact.jsp
<%@taglib uri="http://www.springframework.org/tags" prefix="spring"%>
<%@taglib uri="http://www.springframework.org/tags/form" prefix="form"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<html>
<head>
<title>Spring 3 MVC HashMap Form - viralpatel.net</title>
</head>
<body>
<h2>Spring 3 MVC HashMap Form</h2>
<form:form method="post" action="add.html" modelAttribute="contactForm">
<table>
<tr>
<th>Key</th>
<th>Value</th>
</tr>
<c:forEach items="${contactForm.contactMap}" var="contactMap" varStatus="status">
<tr>
<td>${contactMap.key}</td>
<td><input name="contactMap['${contactMap.key}']" value="${contactMap.value}"/></td>
</tr>
</c:forEach>
</table>
<br/>
<input type="submit" value="Save" />
</form:form>
</body>
</html>
Code language: HTML, XML (xml)
In above JSP file, we display contact details map in a table. Also each attribute is displayed in a textbox. Note that modelAttribute=”contactForm” is defined in tag. This tag defines the modelAttribute name for Spring mapping. On form submission, Spring will parse the values from request and fill the ContactForm bean and pass it to the controller. Also note how we defined textboxes name. It is in form contactMap[‘key’]. Thus Spring knows that we want to display the Map item with key key. contactMap['${contactMap.key}']
will generate each rows as follows: contactMap[‘name’] // mapped to key ‘name’ in hashmap contactMap contactMap[‘lastname’] // mapped to key ‘lastname’ in hashmap contactMap contactMap[‘genres’] // mapped to key ‘genres’ in hashmap contactMap Here we used JSTL to iterate through an HashMap.
Spring 3 MVC and path attribute and square bracket
One thing here is worth noting that we haven’t used Spring’s tag to render textboxes. This is because Spring MVC 3 has a unique way of handling path attribute for tag. If we define the textbox as follows:
<form:input path="contactMap['${contact.key}']" />
Code language: HTML, XML (xml)
Then instead of converting it to following HTML code:
<input name="contactMap['name']" />
<input name="contactMap['firstname']" />
<input name="contactMap['genres']" />
Code language: HTML, XML (xml)
It converts it into following:
<input name="contactMap'name'" />
<input name="contactMap'firstname'" />
<input name="contactMap'genres'" />
Code language: HTML, XML (xml)
Note how it removed square brackets [ ] from name attribute. In previous versions of Spring (before 2.5) the square bracket were allowed in name attribute. It seems w3c has later changed the HTML specification and removed [ ] from html input name. Read the specification http://www.w3.org/TR/html4/types.html#type-name. It clearly says that:
ID and NAME tokens must begin with a letter ([A-Za-z]) and may be followed by any number of letters, digits ([0-9]), hyphens (“-“), underscores (“_”), colons (“:”), and periods (“.”).
Thus, square brackets aren’t allowed in name attribute! And thus Spring 3 onwards this was implemented. So far I haven’t got any workaround to use springs <form:input />
tag instead of plain html <input />
to render and fetch data from multiple rows.
File: /WebContent/WEB-INF/jsp/show_contact.jsp
<%@taglib uri="http://www.springframework.org/tags" prefix="spring"%>
<%@taglib uri="http://www.springframework.org/tags/form" prefix="form"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<html>
<head>
<title>Spring 3 MVC HashMap Form - viralpatel.net</title>
</head>
<body>
<h2>Show Contact</h2>
<table>
<tr>
<th>Key</th>
<th>Value</th>
</tr>
<c:forEach items="${contactForm.contactMap}" var="contactMap"
varStatus="status">
<tr>
<td>${contactMap.key}</td>
<td>${contactMap.value}</td>
</tr>
</c:forEach>
</table>
<br />
<input type="button" value="Back" onclick="javascript:history.back()" />
</body>
</html>
Code language: HTML, XML (xml)
File: /WebContent/index.jsp
<jsp:forward page="show.html"></jsp:forward>
Code language: HTML, XML (xml)
Final Project Structure
Once we have added all relevant source files and jar files, the project structure should look like following:
Step 6: Execute it
Execute the web application Right click on project > Run As > Run on Server. Add Contact page
Show Contact page
Download Source Code
SpringMVC_Hashmap.zip (2.8 MB)
very useful tutorial. thanks you.
well, how do you handle the validation?
Hi,
I’ve followed every step, but once I ran the application it comes out with 404 errors. Any idea of why?
Hi, Please check if you errors in server logs. Most of the time when application is not compiled and the classes folder is not updated in WEB-INF/ of your server root, this error comes.
It is better to keep the jar files in WEB-IF/lib folder or
-Right click –> web project –> PROPERTIES
– Choose the J2EE Module Dependencies
– Click on the Add External JARs… and then point on your library file (ZIP or JAR)
which is recommended method?
Hi,
its nice example, You have explained in very good manner and can be understand easily.
I tried to change the this example by using ArrayList and having checkboxes instead of input texts. But my modelattribute is not populating my list at controller when I submits by clicking some checkboxes.
What should be the value name attribute for list as in your example for map name=”contactMap[‘${contactMap.key}’]”?
Thank you,
Swapnil
Hi Swapnil, May be you are looking for: Spring MVC ArrayList Form mapping. Basically you have to map the inputs by name
arrayname[index]
. Please go through that example.Iam new to Spring 3 , it is good tutorial to learn basics but for Data is not coming up in the jsp which is set in Controller.please tell me how can i get the data in jsp , i used the same code
The coding was very helpful to me …. and thank u so much friend……
Any example of saving a foreign key value by using spring form ? e.g. let’s say you have one Category to many Products. After saving categories when you come to save a product you’ll have categories as a dropdown list, so you’ll be saving a product with category id as a foreign key.
Iam using netbeans 7.0,created web project,1 dout..u r using spring-servlet.xml right..?what is the use of that file, where u including in the project?did u telling that file’s path in web.xml any?
Hi Viral, very great tutorial. I have followed all the steps and was able to manipulate the code too. Right now I have to do something similar to this, however I have a config (XML) file that I am currently reading from. I need to have the same kind of a form and have someone add data and click the save button, then the data is written in XML to the config file(not removing the old data, but adding to it. The config file should change and remain what it has been changed to even if the browser was closed and opened again. Also if you could have the functionality to delete from the config file it would be great.
Thanks in advance.
Thanks a lot!
Your tutorials are easy to understand, and are very useful!
You saved a lot of my time!
Thanks again!
HTTP Status 404 – /SpringIntegration/show.html on running same example…. please help
Please mention how to perform validation in this example. This issue has been troubling a lot.
What is the path need to be mentioned for form:errors tag . And what is the key need to be used inside the Validator.
Hi it is a good tutorial to learn spring annotations basics But . data is not coming in the jsp which is set in Controller Class.can you please tell me know how can i display the data in jsp , i used the same code,It is not workout.But I can able to get the data through request.setAttribute().
most people get error, could you correct it ? 404 error , can not find hello page , even i change the “hello.html” or patten to be / …
hello all,
Thanks in advance.
i am new to roo and jspx . i have created the mvc based project with roo . but when i try to display foriegn key value in a table it dispays all the fields values of the primery key table. i only want to dispay only 1 field value.
IF U show 404 errors.
fix contactcontroller.java
wrong -> @RequestMapping(value = “/show”, method = RequestMethod.GET)
FIX -> @RequestMapping(value = “/”, method = RequestMethod.GET)
Thanks lot of
Hi Viral,
I followed same approch but it didn’t work for me.I have following hashMap in form.
private Map volumnGoalMap;.
I can iterate and display content on jsp but when i update the same and submit to save changes, the form is not populated with HashMap.HashMap in form in for is empty.
Your help will be appreciated.
due to some reason my hashmap key and value is not displayed in comments.So i am explaining…i have hashMap with key as String and value as ManageGoalForm (object).
It is very useful… thank you So much .. :) :)
Thank you. Helpful!
Why did you stop blogging? Your site is great.
Hi,
I tried your tutorial, my program was doing well at first i can show the data in the input fields but when i click on show to display/submit content my hashmap doesn’t have any value in it.
Can you please help me with Maven in Java
hi viralpatel your tutorial is good ,but if you known guidewire &gosu language sample project send me .plzzzz
It is extremely useful example thanx for posting, good to see variety of concepts form you
Nice Article
awesome…..
In ContactController.java class u puted Map value in contactMap and used into jsp file in el language but I want to use this map in scriplate in same jsp how i use this?
The Source Code link is down
Very useful page. Helped for my hashmap binding issues. Thanks a lot!
spring mvc hashmap source code link is not working.