Goal
In this post we will see hoe can we operate on simple html forms using Spring and Java Objects. Spring MVC provides a special controller SimpleFormController for this.
[Note : This controller was deprecated in Spring 3.0 and is no longer available (I am using 4.0.4.RELEASE version). So we will strictly be using annotations based programming which is the future.]
DisplacherServlet looks for some default beans -
How they work is depicted in following diagram
DisplacherServlet looks for some default beans -
- HandlerMapping
- HandlerAdapter
- ViewResolver
- HanadlerExceptionResolver
How they work is depicted in following diagram
Project Structure
Code
ivy.xml
<?xml version="1.0" encoding="ISO-8859-1"?> <!-- Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --> <ivy-module version="2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://ant.apache.org/ivy/schemas/ivy.xsd"> <info organisation="OpenSourceForGeeks" module="SpringDemoWebProject" status="integration"> </info> <dependencies> <dependency org="org.springframework" name="spring-webmvc" rev="4.0.4.RELEASE"> <exclude org="javax.servlet" name="javax.servlet-api" /> <exclude org="javax.servlet.jsp" name="jsp-api" /> <exclude org="javax.el" name="javax.el-api" /> </dependency> <dependency org="com.google.code.gson" name="gson" rev="2.2.4"/> </dependencies> </ivy-module>
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>Test Spring App</display-name> <servlet> <servlet-name>action</servlet-name> <servlet-class> org.springframework.web.servlet.DispatcherServlet </servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>action</servlet-name> <url-pattern>*.htm</url-pattern> </servlet-mapping>
action-servlet.xml
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.springframework.org/schema/beans" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd" > <context:annotation-config /> <context:component-scan base-package="controllers" /> <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix"> <value>/pages/</value> </property> <property name="suffix"> <value>.jsp</value> </property> </bean> </beans>
Employee.java
package model; public class Employee { private String name; private int age; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } }
FormController.java
package controllers; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import model.Employee; import org.springframework.stereotype.Controller; import org.springframework.ui.ModelMap; import org.springframework.validation.Errors; 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.bind.annotation.SessionAttributes; @Controller @SessionAttributes({FormController.COMMAND_NAME}) public class FormController { public static final String EMPLOYEE_FORM= "employeeForm"; public static final String COMMAND_NAME= "empForm"; @RequestMapping(value="/getEmployeeInfoForm.htm",method=RequestMethod.GET) public String getEmployeeInfoForm(HttpServletRequest request, ModelMap modelMap){ Employee empForm = new Employee(); empForm.setName("DefaultName"); empForm.setAge(18); modelMap.addAttribute(COMMAND_NAME, empForm); return EMPLOYEE_FORM; } @RequestMapping(value="/submitEmployeeInfoForm.htm",method = RequestMethod.POST) public void saveEmployeeInfo( @ModelAttribute(COMMAND_NAME) Employee empForm, Errors errors, ModelMap model, HttpServletRequest request, HttpServletResponse response) { System.out.println("Receive Employee Information"); System.out.println("Name : " + empForm.getName()); System.out.println("Age :" + empForm.getAge()); } }
employeeForm.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"> <%@ taglib uri="http://www.springframework.org/tags/form" prefix="form"%> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <title>Employee Information Form</title> <script> function submitForm(){ var formVar = document.forms["form"]; formVar.action="/SpringDemoWebProject/submitEmployeeInfoForm.htm"; formVar.submit(); } </script> </head> <body> <form:form id="form" name="form" method="post" commandName="empForm"> <table> <tr> <td>Employee Name : </td> <td> <form:input path="name"/> </td> </tr> <tr> <td>Employee Age : </td> <td> <form:input path="age"/> </td> </tr> </table> <input type="submit" value="Submit" onclick="submitForm()"/> </form:form> </body> </html>
Important points
- When you add a @ModelAttribute("empForm") controller method argument you're telling Spring MVC to look for it in the model or create a new instance if not found. It is not necessary that your JSP pahe has a command object called empForm. Let's get this clear in next point.
- When you add multiple attributes in your model map the commandName that you use can be any one of the attribute name. Now when you submit your form it is not necessary that the ModelAttribute is same as that of command name. The way it works is as follows - Spring will create a new object of that class (is not already present eg. in session by using @SessionAttributes tag). After creating it will try to scan request parameters and put in your new ModelAttribute Object created.
- As mentioned above If you also add @SessionAttributes({"empForm"}), Spring MVC will not attempt to create a new instance and will expect the object to be either in the model or in the session.
Related Links
- Spring MVC hello world example(OSFG)
- java.lang.ClassNotFoundException: org.springframework.web.servlet.DispatcherServlet (OSFG)
- A simple Spring based Web App project(Git)