-
Sep 5th, 2008, 09:06 AM
#1
Double Click problem in spring MVC (anootation present)
How to prevent from double click problem in spring 2.5 MVC ? I have annotated with Controller method (which is controller in fact), with "showForm" method to display view, and "handleSubmit" method to handle spring form. When I do "double submit/double click" on submit button, this form is "double handled", and data from submited form are inserted in database twice. How to resolve this "double click" problem in spring with annotation ?
-
Sep 6th, 2008, 11:01 PM
#2
There are a couple things you can do, one on the client side and one on the server-side. On the client side, you can add JavaScript that disables the submit button immediately after the user presses it. On the server side, handle a successful submission by redirecting to the "success" page (whether that's a "thanks!" page or a confirmation page or whatever it is). That way if the user hits the reload button on the browser it won't resubmit your form.
Hope that helps.
-
Sep 8th, 2008, 02:07 AM
#3
I believe I did my controller the second way ("handle a successful submission by redirecting to the "success" page"):
//****************** controller code ****************************//
@Controller
@RequestMapping("/main/create-place.html")
public class CreatePlaceController {
@Autowired
UserDao userDao;
@Autowired
CreatePlaceValidator createPlaceValidator;
@RequestMapping(method = RequestMethod.GET)
public String showForm(ModelMap modelMap) {
//backing bean
CreatePlaceBean createPlaceBean = new CreatePlaceBean();
modelMap.addAttribute("createPlaceBean", createPlaceBean);
return "/main/create-place";
}
@RequestMapping(method = RequestMethod.POST)
public String handleSubmit(@ModelAttribute("createPlaceBean") CreatePlaceBean createPlaceBean, BindingResult result, HttpSession session ) {
createPlaceValidator.validate(createPlaceBean, result);
if(result.hasErrors()){
//if errors, back to the same page
return "/main/create-place";
}
else {
//if there is no errors run this code, and redirect to successfull page
return "redirect:/main/main.html";
}
}
}
//************************************************** *********//
when the form is correctly filled, and I keep quickly clicking on submitt button, until success page (main.html) appears, then I notice that this form, was two or three times (depends on how quick I was) submitted. In my database, there is rows with duplicated data, (only PK is diffrent, according to fact that primary key is unique). So I think I has done my controller with the second way you advise me. This problem occurs, after first click on submit button but before redirect to "success" page. According to my requirements, solution with JavaScript is not allowed. Thanks for your answer, but is there any other solution ? I do some research before first post, and I found post, where someone has written, that this problem was resolved in Web Flow, but not in Spring MVC, but that was post form 2006.
P.S. Thanks for the answer
-
Sep 8th, 2008, 10:35 AM
#4
Makes sense. I can see why JavaScript might not be allowed as the complete solution (some people may have it off) though if it were used in conjunction with a server-side dupe check it would only help. Anyway...
On the server side, I'm not sure of best practices in this area, though I can think of a couple possible approaches.
1) If there's a natural key over which you can define a uniqueness constraint, you might do that. The only thing is that constraint bleeds over into your entire app, not just your form double-submit, so you'd need to make sure the constraint is generally sensible. Also this isn't a general solution since not all data has a natural key.
2) Before serving the form, you might autogenerate a random long value and include it in the form as a hidden field. Then when somebody submits the form you can grab the submitted hidden value and check it against a LAST_SUBMITTED_PLACE_KEY on the session. If it matches then reject the entire submission; otherwise accept it and store the submitted hidden value under the LAST_SUBMITTED_PLACE_KEY.
There are probably more standard approaches to solving this but #2 should be pretty general. You could replace LAST_SUBMITTED_PLACE_KEY with LAST_SUBMITTED_FORM_KEY and still be in good shape, practically speaking.
-
Sep 8th, 2008, 01:09 PM
#5
I followed the 2nd way, and it works. Now my controller looks like this, and works properly:
//****************** controller code ****************************//
@Controller
@RequestMapping("/main/create-place.html")
public class CreatePlaceController {
@Autowired
UserDao userDao;
@Autowired
CreatePlaceValidator createPlaceValidator;
Long PLACE_KEY;
@RequestMapping(method = RequestMethod.GET)
public String showForm(ModelMap modelMap) {
PLACE_KEY = (new Random()).nextLong();
//backing bean
CreatePlaceBean createPlaceBean = new CreatePlaceBean();
modelMap.addAttribute("createPlaceBean", createPlaceBean);
return "/main/create-place";
}
@RequestMapping(method = RequestMethod.POST)
public String handleSubmit(@ModelAttribute("createPlaceBean") CreatePlaceBean createPlaceBean, BindingResult result, HttpSession session ) {
if (((Long) session.getAttribute("LAST_PLACE_KEY"))!=null && ((Long) session.getAttribute("LAST_PLACE_KEY")).equals(PLA CE_KEY)) {
return "redirect:/main/main.html";
}
session.setAttribute("LAST_PLACE_KEY", PLACE_KEY);
createPlaceValidator.validate(createPlaceBean, result);
if(result.hasErrors()){
//if errors, back to the same page
return "/main/create-place";
}
else {
//if there is no errors run this code, and redirect to successfull page
return "redirect:/main/main.html";
}}}
//************************************************** *********//
Again, thanks a lot for your answer, it was good idea to store key in session.
-
Sep 9th, 2008, 12:58 AM
#6
No sweat; glad it helped. :-D
-
May 16th, 2012, 01:27 AM
#7
This was such a huge help to me that I just created an account simply to say thank you! I managed to fix this bug in under two hours from discovery with the help of this thread.
Tags for this Thread
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules