Hi guys,

Today I am going to tell you how to prevent duplicate form submission in a Spring MVC based project.

This issue is not actually a technology specific issue. It can arise with any technology and every technology has different way to resolve it but the concept for resolving the issue remains the same.

So, let starts with the issue that we face. Below is the typical approach of form submission where we face this issue.

@Controller
public class FormController {

	@RequestMapping(value = "/submitform", method = RequestMethod.POST)
	public ModelAndView submitForm(FormBean obj, SomeOtherObject sobj) {

		/**
		* Form submission code. 
		*/

		ModelAndView modelView = new ModelAndView("resultAction");

                // Adding objects to avail at JSP
                modelView.addObject("msg", msgObjectX);
                modelView.addObject("someObjectY", someObjectY);
		return modelView;
	}
}

The above code processes the form and data is inserted into database and is forwarded to a desired view. Let’s say that view is “resultAction page”. When you refresh this page, the above code gets executed again and duplicate values are entered into the database.  Big problem!!!

So, the solution to this problem is to end the scope of form submission request. A typical solution for this in a Servlet based application is:

response.sendRedirect("resultAction_page");

Logic:

When a request is made for form submission using HTTP POST/GET method, the scope of this HTTP POST/GET request is ended by introducing redirection to a “view page” using a GET method. So, when the “view page” is refreshed, then the last GET method is called and hence “view page” is only refreshed.

So, all we need is to use the same fundamental as that of Servlet based application in Spring MVC. There is an object called RedirectView in Spring MVC which helps us to achieve the very same thing. But there is a catch. Whatever objects that you add/inject using:

modelView.addObject("msg", msgObjectX);
modelView.addObject("someObjectY", someObjectY);

will not be accessible on “resultAction page”. So, we need another object called RedirectAttribute for this purpose. It was method called addFlashAttribute that help in adding objects.

So, the above controller can be re-written as below:

@Controller
public class FormController {

	@RequestMapping(value = "/submitform", method = RequestMethod.POST)
	public ModelAndView submitForm(FormBean obj, SomeOtherObject sobj, RedirectAttribute ra) {

		/**
		* Form submission code. 
		*/

		ModelAndView modelView = new ModelAndView(new RedirectView("resultAction"));

                // Adding objects to avail at JSP
                ra. addFlashAttribute ("msg", msgObjectX);
                ra. addFlashAttribute ("someObjectY", someObjectY);
		return modelView;
	}
}

That’s it!

In case you don’t want to use RedirectAttribute there is another option. Use session. Add object like below:

session.setAttribute("msg", msgObjectX);
session.setAttribute("someObjectY", someObjectY);

And retrieve the objects on view like below:

session.getAttribute("msg");
session.getAttribute("someObjectY");

But make sure that you destroy the objects in this case immediately after accessing them, as objects are in session and will be carried throughout until session is expired.

 

That’s all folks!

Questions/feedbacks are very much welcome.

Have a nice day ahead.

Loading