Saturday 26 July 2014

Spring form controller with annotations example

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 -
  1. HandlerMapping 
  2. HandlerAdapter
  3. ViewResolver 
  4. 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>
  

Screenshots


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


t> UA-39527780-1 back to top