Reputation: 2485
I have a problem with controller in my spring mvc application.
I am getting all the entities from database and put them in the table in my jsp page.
I am adding an entity, the function works well, it adds an entity and refresh the page. But there is a problem when I try to refresh page...the same entity is added again, in general after adding an entity every refresh execute the post method again and finally i have many same entities.
This is the post method to add new entities:
@RequestMapping(value = "/adminpanel", method = RequestMethod.POST)
public ModelAndView addNewSoftware(@ModelAttribute VersionInformation versionInformation)
{
ModelAndView model = new ModelAndView("panel");
persistanceDAO.insertVersionInformation(versionInformation);
systemVersionsList.clear();
systemVersionsList.addAll(persistanceDAO.getSystemVersions());
model.addObject("systemVersionsList",systemVersionsList);
model.addObject("versionInformation", new VersionInformation());
return model;
}
This is my GET method:
@RequestMapping(value = "/adminpanel/add", method = RequestMethod.POST)
public ModelAndView addNewSoftware(@ModelAttribute VersionInformation versionInformation)
{
ModelAndView model = new ModelAndView("panel");
persistanceDAO.insertVersionInformation(versionInformation);
systemVersionsList.clear();
systemVersionsList.addAll(persistanceDAO.getSystemVersions());
model.addObject("systemVersionsList",systemVersionsList);
model.addObject("versionInformation", new VersionInformation());
return model;
}
Another problem is that when I am deleting an entity, the entity is deleted, but the site doesn't refresh. This is my post method responsible for deleting entity:
@RequestMapping(value = "/adminpanel/delete", method = RequestMethod.POST)
public ModelAndView deleteSoft(@ModelAttribute(value="currentId") int currentId, @ModelAttribute VersionInformation versionInformation)
{
ModelAndView model = new ModelAndView("panel");
persistanceDAO.deleteSystemVersion(currentId);
systemVersionsList.clear();
systemVersionsList.addAll(persistanceDAO.getSystemVersions());
model.addObject("systemVersionsList",systemVersionsList);
model.addObject("versionInformation", new VersionInformation());
return model;
}
Upvotes: 2
Views: 982
Reputation: 5474
You probably are looking at Post/Redirect/Get pattern. If you are using Spring 3.1 and above, implementing this would be easy using flash attribute.
Modification of your code with Post/Redirect/Get Pattern applied
@RequestMapping(value = "/adminpanel/add", method = RequestMethod.POST)
public String addNewSoftware(@ModelAttribute VersionInformation versionInformation,
final RedirectAttributes redirectAttributes){
ModelAndView model = new ModelAndView("panel");
persistanceDAO.insertVersionInformation(versionInformation);
systemVersionsList.clear();
systemVersionsList.addAll(persistanceDAO.getSystemVersions());
redirectAttributes.addFlashAttribute("systemVersionsList",systemVersionsList);
redirectAttributes.addFlashAttribute("versionInformation", new VersionInformation());
return "redirect:/adminpanel/show-panel";
}
@RequestMapping(value = "/adminpanel/show-panel", method = RequestMethod.GET)
public ModelAndView showSoftwarePanel(@ModelAttribute("systemVersionsList") List<YouDidNotShowTheTypeOFSystemVersionList> systemVersionsList,
@ModelAttribute("versionInformation") VersionInformation versionInformation){
ModelAndView model = new ModelAndView("panel");
model.addObject("systemVersionsList", systemVersionsList);
model.addObject("versionInformation", versionInformation);
return model;
}
After doing that, your page is now safe from multiple form submit problem.
Upvotes: 1
Reputation: 2578
I think the problem is that when you refresh the page you are resending the data. If so you need to use the Redirect-after-POST pattern.
Try this
@RequestMapping(value = "/adminpanel/add", method = RequestMethod.POST)
public ModelAndView addNewSoftware(@ModelAttribute VersionInformation versionInformation)
{
ModelAndView model = new ModelAndView("redirect:/admin/panel");
// move these lines
persistanceDAO.insertVersionInformation(versionInformation);
systemVersionsList.clear();
systemVersionsList.addAll(persistanceDAO.getSystemVersions());
model.addObject("systemVersionsList",systemVersionsList);
model.addObject("versionInformation", new VersionInformation());
// end
return model;
}
NOTE: You should move the commented lines into a GET method otherwise, your version etc will appear in the URL after redirect
Upvotes: 0
Reputation: 7283
What about using redirect after updating the data.
"Another reason to perform a redirect before displaying the result is to eliminate the possibility of the user submitting the form data multiple times. In this scenario, the browser will first send an initial POST; it will then receive a response to redirect to a different URL; and finally the browser will perform a subsequent GET for the URL named in the redirect response. " quoted from Spring mvc doc
Upvotes: 1
Reputation: 33412
GET
methods must only be used for idempotent operations. For deletes and inserts you must use POST
. And after successful non-idempotent operation you must send a redirect to user, so if he hits refresh no kittens harmed.
Upvotes: 0