How to prevent duplicate form submission in Spring MVC

Upasana | May 07, 2019 | 3 min read | 3,553 views


Duplicate form submission may happen due to wrong coding practice at the Spring MVC controller side. A poorly coded controller may cause duplicate form submission when a user hits F5 button after submitting the HTML form. PRG Web Design Pattern is specifically designed to get take care of this scenario.

You can use RedirectAttributes object which was introduced in Spring MVC 3.1 and populate it with data you want to keep for redirection. This is a very common usecase in web app development.

PRG - Post/Redirect/Get Pattern

Post/Redirect/Get (PRG) is a web development design pattern that prevents some duplicate form submissions, creating a more intuitive interface for user agents (users). PRG supports bookmarks and the refresh button in a predictable way that does not create duplicate form submissions.

How to Implement PRG in Spring MVC?

We shall always return a redirect view upon successful form submission in Spring MVC. This prevents duplicate form submission. Spring provides mechanism to pass attributes to redirected controller using RedirectAttributes.

Spring MVC Controller using RedirectAttributes & PRG Pattern
 @RequestMapping(value = "/accounts", method = RequestMethod.POST)
 public String handle(Account account, BindingResult result, RedirectAttributes redirectAttrs) {
   if (result.hasErrors()) {
     return "accounts/new";
   }
   // Save account ...
   redirectAttrs.addAttribute("id", account.getId());  (1)
   redirectAttrs.addFlashAttribute("message", "Account created!");  (2)
   return "redirect:/accounts/{id}";
 }
1 attribute id will be added to request parameters after redirect.
2 attribute message will be stored inside flashmap inside session.

Difference between addFlashAttribute and addAttribute

addFlashAttribute

addFlashAttribute actually stores the attributes in a flashmap which is internally maintained in the users session and removed once the next redirected request gets fulfilled.

addAttribute

on the other addAttribute essentially constructs request parameters out of your attributes and redirects to the desired page with the request parameters. So the advantage will be that you can store pretty much any object in your flash attribute(as it is not serialized into request params at all, but maintained as an object), whereas with addAttribute since the object that you add gets transformed to a normal request param, you are pretty limited to the object types like String or primitives.

Spring Documentation

A FlashMap provides a way for one request to store attributes intended for use in another. This is most commonly needed when redirecting from one URL to another — e.g. the Post/Redirect/Get pattern. A FlashMap is saved before the redirect (typically in the session) and is made available after the redirect and removed immediately.

A FlashMap can be set up with a request path and request parameters to help identify the target request. Without this information, a FlashMap is made available to the next request, which may or may not be the intended recipient. On a redirect, the target URL is known and a FlashMap can be updated with that information. This is done automatically when the org.springframework.web.servlet.view.RedirectView is used.

References

Buy my ebook for complete question bank

Most of these questions has been answered in my eBook "Cracking the Core Java Interview" updated on June 2018, that you can buy from this link:

Buy from Shunya (DRM Free PDF download with updates)

Top articles in this category:
  1. Prevent Lost Updates in Database Transaction using Spring Hibernate
  2. Spring Boot multipart file upload server
  3. Testing web layer in Spring Boot using WebMvcTest
  4. Spring RestTemplate Basic Authentication
  5. Java 8 date time JSON formatting with Jackson
  6. Multipart file upload with RestTemplate
  7. Setting a Random Port in Spring Boot Application at startup

Recommended books for interview preparation:

Find more on this topic:
Buy interview books

Java & Microservices interview refresher for experienced developers.