Spring MVC Fix Duplicate Form Submission Use Redirect Url Example

When you submit a spring form, it will show a successful web result page in general. But when you refresh the form submit result page by clicking the browser refresh button. The browser will pop up a dialog telling you that the form data will be resubmitted again, this is always not what we want. So this article will tell you how to avoid duplicate form submission use spring page redirection.

1. Why Duplicate Form Submission?

  1. The reason for this issue is that the submit form web page URL is the same as the form submit result web page URL in the web browser URL address text box.
  2. So to resolve it, after the form submit you need to send a redirect to the web browser to tell it to browse another web page. So after page redirection, the web page URL will be changed.
  3. There are two methods in spring to make web page redirect, use RedirectView object or use ModelAndView redirect keyword.
  4. This example is based on Spring MVC Form Submit Example, so please read the article first, we will change the source code in that article to implement the spring web page redirect.

2. Use RedirectView To Resolve Spring Form Resubmission.

2.1 Change EmployeeFormController.java Source Code.

  1. Remove the controller class’s @RequestMapping(“/employee.html”) annotation.
    @Controller
    //@RequestMapping("/employee.html")
    public class EmployeeFormController {
  2. Change the displayEmployeeInfo() method to below code. And add a new method redirectToEmplInfoPage().
    /* Use RedirectView to redirect the result page to client to avoid spring form resubmit.*/
    @RequestMapping(value="/employee.html", method=RequestMethod.POST)
    public RedirectView displayEmployeeInfo(Model model, @ModelAttribute(EMPLOYEE_INFO) EmployeeInfoDTO employeeInfo, RedirectAttributes atts) {
          
        /* Flash attribute can be passed to the redirect web page. Then you can read the form submit data 
           in the redirected jsp page.*/
        atts.addFlashAttribute(EMPLOYEE_INFO, employeeInfo);
        // Redirect request to the redirectToEmplInfoPage() method.
        return new RedirectView("/redirect_to_employee_info_display.html",true);
    }
    
    @RequestMapping(value="/redirect_to_employee_info_display.html", method=RequestMethod.GET)
    public String redirectToEmplInfoPage(){
        // This method simply return the target redirect web page. 
        return "employee_info_display";
    }
  3. Also add the value attribute to the displayEmployeeInfoInput() method’s @RequestMapping annotation. Because we have removed the controller class’s @RequestMapping(“/employee.html”) annotation.
    /* When request the url in GET method. */
    @RequestMapping(value="/employee.html", method=RequestMethod.GET)
    public String displayEmployeeInfoInput(Model model) {

3. Use ModelAndView redirect Keyword.

3.1 Change EmployeeFormController.java Source Code.

  1. Remove the controller class’s @RequestMapping(“/employee.html”) annotation.
  2. And add @RequestMapping(value=”/employee.html” to both existing displayEmployeeInfoInput() and displayEmployeeInfo() method.
  3. Change displayEmployeeInfo() method source code to below. And add the redirectToEmplInfoPage() method also.
    /* Use ModelAndView and redirect: keyword to redirect to the form submit result page. */
    @RequestMapping(value="/employee.html", method=RequestMethod.POST)
    public ModelAndView displayEmployeeInfo(RedirectAttributes atts, @ModelAttribute(EMPLOYEE_INFO) EmployeeInfoDTO employeeInfo) {
        atts.addFlashAttribute(EMPLOYEE_INFO, employeeInfo);
        return new ModelAndView("redirect:/redirect_to_employee_info_display.html");
    }
    
    @RequestMapping(value="/redirect_to_employee_info_display.html", method=RequestMethod.GET)
    public String redirectToEmplInfoPage(){
        return "employee_info_display";
    }

3.2 Add UrlBasedViewResolver Bean In Spring Java Config Class.

  1. Because the ModelAndView object uses the redirect keyword to redirect the client browser to a none existing Html page, so we need to add a UrlBasedViewResolver configuration bean in the spring java-config class. Otherwise, it will throw errors like below.
    javax.servlet.ServletException: Could not resolve view with name 'redirect:/redirect_to_employee_info_display.html' in servlet with name 'DispatcherServlet'
  2. ContextConfig.java, add below code in ContextConfig.java.
    @Bean(name="urlBasedViewResolver")
    public UrlBasedViewResolver getUrlBasedViewResolver() {
        UrlBasedViewResolver ret = new UrlBasedViewResolver();
        ret.setPrefix("/pages/");
        ret.setSuffix(".jsp");
        ret.setCache(false);
        ret.setOrder(0);
        ret.setViewClass(JstlView.class);
        return ret;
    }

4. Transfer Form Data To The Redirect Web Page.

  1. If you want to pass the form data to the redirected JSP web page, you need to use org.springframework.web.servlet.mvc.support.RedirectAttributes class object as the controller’s request handler method input parameter.
  2. This class provides the addFlashAttribute(attribute_name, attribute_value) method to add a flash-scoped object, and this type of object can be transferred during the web page redirection.
  3. But flash-scoped objects will not exist after the page redirection, so when you refresh the form submit result web page again, all the form data will be lost.
  4. To resolve this issue, you can use a session-scoped object instead. This is beyond this example, you can read the article Spring MVC Request And Session Scoped Bean Example to learn more.

Reference

  1. Spring MVC Form Submit Example

Leave a Comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.