Spring MVC - Prevent duplicate form submission

[Updated: Jul 27, 2016, Created: Mar 13, 2016]

As we mentioned here, redirect is a useful trick to avoid submitting same form multiple times. As a result of URL redirection client receives the result page with a different HTTP request, idealy with a GET method. The browser address bar shows a different URL instead the original form URL. If user refreshes the same page multiple times he/she will not issue another post submission.



In this complete example of 'user registration' we are going to demonstrate how we can achieve that.



Create the backing/command object

public class User implements Serializable{
    private Long id;

    @Size(min = 5, max = 20)
    private String name;


    @Size(min = 6, max = 15)
    @Pattern(regexp = "\\S+", message = "Spaces are not allowed")
    private String password;

    @NotEmpty
    @Email
    private String emailAddress;

    //getters and setters
}

In above backing object we used JSR 349 constraints annotations.




The Controller

@Controller
@RequestMapping
public class UserRegistrationController {

    @Autowired
    private UserService userService;

    //shows the empty form with get request
    @RequestMapping(value = "register", method = RequestMethod.GET)
    public String handleGetRequest (Model model) {
        model.addAttribute("user", new User());
        return "user-registration";
    }

    //form post handler which redirect to other URL with GET method
    @RequestMapping(value = "register", method = RequestMethod.POST)
    public String handlePostRequest (@Valid @ModelAttribute("user") User user,
                                     BindingResult bindingResult,
                                     RedirectAttributes ra) {

        if (bindingResult.hasErrors()) {
            return "user-registration";
        }

        userService.saveUser(user);
        ra.addFlashAttribute("user", user);
        return "redirect:/registration-success";
    }

    //redirected handler
    @RequestMapping(value = "registration-success", method = RequestMethod.GET)
    public String handleRegistrationDone(@ModelAttribute("user") User user){
        System.out.println("user....: "+user);
        return "registration-done";
    }
}

In above example we used RedirectAttributes#addFlashAttribute. Please see our last example for more details about that.




user-registration.jsp

<%@taglib uri="http://www.springframework.org/tags/form" prefix="frm"%>
<html>
<head>
<style>
.error {
   color: red;
}
</style>
</head>
<body>

<h3> Registration Form <h3>
<br/>
 <frm:form action="register" method="post" commandName="user">
  <pre>
                  Name <frm:input path="name" />
                       <frm:errors path="name" cssClass="error" />

         Email address <frm:input path="emailAddress" />
                       <frm:errors path="emailAddress" cssClass="error" />

              Password <frm:password path="password" />
                       <frm:errors path="password" cssClass="error" />
                                        <input type="submit" value="Submit" />
  </pre>
 </frm:form>
</body>
</html>



registration-done.jsp

<%@ page language="java"
    contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<html>
<body>
<h3> Registration done </h3>
<p>User Name: ${user.name}</p>
<p>User email: ${user.emailAddress}
</body>
</html>

Example Project

Dependencies and Technologies Used :

  • Spring Web MVC 4.2.4.RELEASE: Spring Web MVC.
  • Spring TestContext Framework 4.2.4.RELEASE: Spring TestContext Framework.
  • Java Servlet API 3.0.1
  • Hibernate Validator Engine 5.2.4.Final: Hibernate's Bean Validation (JSR-303) reference implementation.
  • JUnit 4.12: JUnit is a unit testing framework for Java, created by Erich Gamma and Kent Beck.
  • JDK 1.8
  • Maven 3.0.4

Spring Avoid Multiple Form Submit Example Select All Download
  • spring-form-registration
    • src
      • main
        • java
          • com
            • logicbig
              • example
        • webapp
          • WEB-INF
            • views
      • test
        • java
          • com
            • logicbig
              • example

Run the web application by using embedded tomcat:

mvn  clean install tomcat7:run-war

Enter the URL

http://localhost:8080/spring-form-registration/register

The URL in the address bar will change as the result of redirection:

http://localhost:8080/spring-redirect-attributes/test2/5?attr=attrVal


On validation errors:



On successful submission


Notice the URL has been redirected on the successful form submission.

See Also