Spring MVC Command Object Example on Eclipse and Tomcat

This article is continuation of the Spring MVC Tutorial with Eclipse and Tomcat. Now, let us add the next practical aspect to our code – form or what Spring MVC calls it – command object. So we write a Spring MVC Command Object example using Eclipse IDE and deploy it on Tomcat server.If you remember the starting days of servlet, or days of unavailability of frameworks like Struts, Spring MVC, we used to retrieve the data submitted from a HTML page using HTTP request object. Some of you must have hated the chain of request.getAttribute(..) calls. This problem is addressed by these presentation tier frameworks and we have a POJO, some people call it Java bean, associated with the html. The framework will do the job of retrieval of attributes and setting those in POHO for us, and we get an instance of POJO, populated with the values entered by user. The first article did not contain any handling of form/command object (now onwards we call it as command object only). But in practical scenario, we will mostly have the command objects. These changes we are going to make to the code in previous example.

Changes Required for Spring MVC Command Object Example:

  •  Add new jars for the tag libraries.
  • Java side changes contain addition of HelloVisitorController and Visitor command object, and modifications to HelloWorldController.
  • Jsp changes include addition of hellovisitor.jsp and changes to helloworld.jsp.
  • Changes to the configuration xml.

Add New Jars:

We are going to use Spring’s ‘form’ tag library and Jstl’s core tag library. For the JSTL core tag library, I have included following two jars. You can add other Jstl tag libraries also. Add these libraries to ‘WEB-INF/lib’ directory and refresh the project in eclipse. Add these libraries to the project libraries through ‘Right Click on Project’ – properties – Java Build Path – Libraries – Add Jars.

jstl.jar

standard.jar

Java Changes:

On Java side, to make this Spring MVC Command object exmaple work, we need to add two classes. First is HelloVisitorController, it handles our HTML form submission, and redirects to a new page. Second is the command object – Visitor. It has the three attributes to manage our functionality. Ok, the functionality is – We ask user to enter first name and last name on first screen, and on submission, we concatenate those two and present complete name on second screen. Elementary thing right? No complex functional business.

Next we change the HelloWorldController to fulfill the requirement of Spring MVC with respect to command object; we create an instance of the command object and return it.

Here is our first new class, notice the change in this controller. It extends from SimpleFormController to get support for the command object handling. I found extending from this class enough to give most of the features required for a command object based application. We are not making this change to the HelloWorldController because this controller does not expect command object to be available in its submission handler method.

HelloVisitorController.java

package com.myorg.springmvctutorial.web.controller;

import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.validation.BindException;
import org.springframework.web.bind.ServletRequestDataBinder;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.SimpleFormController;

import com.myorg.springmvctutorial.web.command.Visitor;

public class HelloVisitorController extends SimpleFormController {

	protected void initBinder(HttpServletRequest request,
			ServletRequestDataBinder binder) throws Exception {
	}

	protected ModelAndView disallowDuplicateFormSubmission(
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		BindException errors = getErrorsForNewForm(request);
		errors.reject("duplicateFormSubmission", "Duplicate form submission");
		return showForm(request, response, errors);
	}

	protected final ModelAndView onSubmit(HttpServletRequest request,
			HttpServletResponse response, Object commandObject,
			BindException errors) throws Exception {
		try {
			Visitor visitor = (Visitor)commandObject;
			logger.trace("First Name" + visitor.getFirstName()+
					"Last Name:" + visitor.getLastName());
			visitor.setCompleteName(visitor.getFirstName() + " "
					+ visitor.getLastName());
			Map dataMap = new HashMap();
			dataMap.put("visitor", visitor);
			return new ModelAndView("hellovisitor.jsp", dataMap);
		} catch (Exception e) {
			logger.error(e);
			e.printStackTrace();
			throw e;
		}
	}

}

Next is the command object. I hope you will override the hashCode, equals and toString methods as required.

Visitor.java

package com.myorg.springmvctutorial.web.command;

public class Visitor {
	private String firstName = "";
	private String lastName = "";
	private String completeName = "";

	public String getFirstName() {
		return firstName;
	}
	public void setFirstName(String aFirstName) {
		this.firstName = aFirstName;
	}
	public String getLastName() {
		return lastName;
	}
	public void setLastName(String aLastName) {
		this.lastName = aLastName;
	}
	public String getCompleteName() {
		return completeName;
	}
	public void setCompleteName(String completeName) {
		this.completeName = completeName;
	}

}

Now the changed HelloWorldController.java.

HelloWorldController.java

package com.myorg.springmvctutorial.web.controller;

import org.springframework.web.servlet.mvc.Controller;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.myorg.springmvctutorial.web.command.Visitor;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

public class HelloWorldController implements Controller {
	protected final Log logger = LogFactory.getLog(getClass());

	public ModelAndView handleRequest(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		logger.info("Return View");
		Map dataMap = new HashMap();
		Visitor visitor = new Visitor();
		dataMap.put("visitor", visitor);
		return new ModelAndView("helloworld.jsp", dataMap);
	}
}

JSP Changes:

We add hellovisitor.jsp. It shows the visitor.completeName using ‘out’ element of Jstl core tag library.

 hellovisitor.jsp

In helloworld.jsp we add the first name and last name text fields, and button which submits the form.

 helloworld.jsp

Changes to the Configurations:

We need to add the new controller and the command object association to it. I am going to keep this command object to request scope, hence not adding the sessionForm property. Add this bean element to our SpringMVCTutorial-servlet.xml.

SpringMVCTutorial-servlet.xml

See Our Spring MVC Command Object Example Working:

This is how the first page hello world will look like with changes after running it on tomcat (as directed in previous tutorial) and calling the shown url (http://localhost:8080/SpringMVCTutorial/helloworld.htm).

 WithformhelloworldPage

On Submit button press, here is our complex job done!!!

 AfterSubmitButtonPress

16 Comments

  1. Hello,
    I’ve tried using the codes provided in this tutorial and in the previous one, which was a nice one by the way, however, when I try to launch the new codes used above, I get this error:

    HTTP Status 500 –

    ——————————————————————————–

    type Exception report

    message

    description The server encountered an internal error () that prevented it from fulfilling this request.

    exception

    javax.servlet.ServletException: javax.servlet.jsp.JspTagException: Neither BindingResult nor plain target object for bean name ‘visitor’ available as request attribute
    org.apache.jasper.runtime.PageContextImpl.doHandlePageException(PageContextImpl.java:852)
    org.apache.jasper.runtime.PageContextImpl.handlePageException(PageContextImpl.java:781)
    org.apache.jsp.helloworld_jsp._jspService(helloworld_jsp.java:203)
    org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:806)
    org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:369)
    org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:342)
    org.apache.jasper.servlet.JspServlet.service(JspServlet.java:267)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:806)
    org.springframework.web.servlet.view.InternalResourceView.renderMergedOutputModel(InternalResourceView.java:236)
    org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:257)
    org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1183)
    org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:902)
    org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:807)
    org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:571)
    org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:501)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:693)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:806)

    root cause

    javax.servlet.jsp.JspTagException: Neither BindingResult nor plain target object for bean name ‘visitor’ available as request attribute
    org.springframework.web.servlet.tags.BindTag.doStartTagInternal(BindTag.java:121)
    org.springframework.web.servlet.tags.RequestContextAwareTag.doStartTag(RequestContextAwareTag.java:77)
    org.apache.jsp.helloworld_jsp._jspService(helloworld_jsp.java:96)
    org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:806)
    org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:369)
    org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:342)
    org.apache.jasper.servlet.JspServlet.service(JspServlet.java:267)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:806)
    org.springframework.web.servlet.view.InternalResourceView.renderMergedOutputModel(InternalResourceView.java:236)
    org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:257)
    org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1183)
    org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:902)
    org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:807)
    org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:571)
    org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:501)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:693)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:806)

    Do you have any idea what the cause of the problem might be?
    Thanks.

    • I would clean and rebuild project. Second check the configuration xmls and see if the object is available at right place with right configuration.

  2. Hi admin

    thanks for such a nice tutorial i had ever seen on web …i like to know more about command object what else thing a command object can do, and how it is different then httpservletreq and response object…or what are the benefit of using it….thanks

    • Command object encapsulates data getting transfer between client and server. Earlier we used to retrieve the data from request object. This is a neater way and we don’t need to deal with request and response objects in general while using such frameworks.

  3. Hi admin,
    Iam new to spring framework.This site was very helpful for starting simple springframework example. I was trying to run the above code, but it was giving errors, which i am unable to understand. can u tell me where am i doing the mistake, and can u tell me which books are good to study springframework from scratch.

    Error:

    HTTP Status 500 –

    type Exception report

    message

    description The server encountered an internal error () that prevented it from fulfilling this request.

    exception

    org.apache.jasper.JasperException: An exception occurred processing JSP page /helloworld.jsp at line 18

    15: This is Spring MVC Tutorial
    16: Our Tutorial is successful.
    17:
    18:
    19:
    20: FirstName:  
    21:

    Stacktrace:
    org.apache.jasper.servlet.JspServletWrapper.handleJspException(JspServletWrapper.java:505)
    org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:410)
    org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:342)
    org.apache.jasper.servlet.JspServlet.service(JspServlet.java:267)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:717)

    root cause

    java.lang.IllegalStateException: No WebApplicationContext found: no ContextLoaderListener registered?
    org.springframework.web.servlet.support.RequestContextUtils.getWebApplicationContext(RequestContextUtils.java:84)
    org.springframework.web.servlet.support.RequestContext.initContext(RequestContext.java:211)
    org.springframework.web.servlet.support.JspAwareRequestContext.initContext(JspAwareRequestContext.java:76)
    org.springframework.web.servlet.support.JspAwareRequestContext.(JspAwareRequestContext.java:50)
    org.springframework.web.servlet.tags.RequestContextAwareTag.doStartTag(RequestContextAwareTag.java:74)
    org.apache.jsp.helloworld_jsp._jspService(helloworld_jsp.java:103)
    org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
    org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:374)
    org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:342)
    org.apache.jasper.servlet.JspServlet.service(JspServlet.java:267)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:717)

    note The full stack trace of the root cause is available in the Apache Tomcat/6.0.18 logs.

    Do you have any idea on this error.

    Thanks,
    Deepthi

  4. Hi, admin.
    It is one of the best articles.
    I like to know the lifecycle of SimpleFormController. I see a number of methods in this class and not sure the methods I have to override in my class where I extend SimpleFormController.

    Please explain what methods I need to override and why should I override.

    Can you please explain the sequence of actions inside this class?

    Thanks,
    Kanthappan

  5. Hi Admin

    This is the best & the fastest SpringMVC tutorial that i could found through the internet !! Thank you so much brother .. Keep up the good work !

    Hope more tutorials from you by continuing the same tutorial further to integrate with hibernate.

    Thanks !

    Nomesh

  6. Hi

    I tried your example its working fine but not able to avoid the duplicate submit.what i have done is first time i have submitted the data then using back button i wne t back and resumitted the data

    it took that but no exption from thegiven example is it works in that way

    if there is any solution please let me know

  7. I tried this example and when I click on submit on helloworld.jsp view, onSubmit() method starts executing in class HelloVisitorController.
    when I cast Command object that has been passed to the onSubmit() method into Visitor i get a Visitor object with all properites as empty strings…
    In another words binding between helloworld.jsp properties and HelloVisitorController’s Command Object didn’t happen.

  8. Hello, im getting an error like thisl

    INFO: Destroying singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@132021a: defining beans [/helloworld.htm,/hellovisitor.htm]; root of factory hierarchy
    Aug 26, 2010 2:48:42 PM org.springframework.web.servlet.FrameworkServlet initServletBean
    SEVERE: Context initialization failed
    org.springframework.beans.factory.BeanCreationException: Error creating bean with name ‘/hellovisitor.htm’ defined in ServletContext resource [/WEB-INF/SpringMVCTutorial-servlet.xml]: Initialization of bean failed; nested exception is org.springframework.beans.InvalidPropertyException: Invalid property ‘commandName’ of bean class [controller.HelloWorldController]: No property ‘commandName’ found
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:480)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory$1.run(AbstractAutowireCapableBeanFactory.java:409)

  9. Hello ,
    When i tried i am getting this error. plz any one tosolve this ??

    org.springframework.beans.factory.BeanCreationException: Error creating bean with name ‘/helloworld.htm’ defined in ServletContext resource [/WEB-INF/SpringMVCTutorial-servlet.xml]: Error setting property values; nested exception is org.springframework.beans.NotWritablePropertyException: Invalid property ‘commandName’ of bean class [com.myorg.springmvctutorial.web.controller.HelloWorldController]: Bean property ‘commandName’ is not writable or has an invalid setter method. Does the parameter type of the setter match the return type of the getter?

  10. hi admin…. i am getting this eror
    jasperexception:java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name ‘user’ available

Leave a Reply

Your email address will not be published.


*