SpringMVC controller: how to stay on page if form validation error occurs
spring-mvc, validation
Solution
I tried the solution metioned in this post at this weekend, but it doesn't work for BindingResult.
The code below works but not perfect.
@ModelAttribute("command")
public PlaceOrderCommand command() {
return new PlaceOrderCommand();
}
@RequestMapping(value = "/placeOrder", method = RequestMethod.GET)
public String placeOrder(
@ModelAttribute("command") PlaceOrderCommand command,
ModelMap modelMap) {
modelMap.put(BindingResult.MODEL_KEY_PREFIX + "command",
modelMap.get("errors"));
return "placeOrder";
}
@RequestMapping(value = "/placeOrder", method = RequestMethod.POST)
public String placeOrder(
@Valid @ModelAttribute("command") PlaceOrderCommand command,
final BindingResult bindingResult, Model model,
final RedirectAttributes redirectAttributes) {
if (bindingResult.hasErrors()) {
redirectAttributes.addFlashAttribute("errors", bindingResult);
//it doesn't work when passing this
//redirectAttributes.addFlashAttribute(BindingResult.MODEL_KEY_PREFIX + "command", bindingResult);
redirectAttributes.addFlashAttribute("command", command);
return "redirect:/booking/placeOrder";
}
......
}
Problem
I have next working code in my SpringMVC controller: ``` @RequestMapping(value = "/register", method = RequestMethod.GET) public void registerForm(Model model) { model.addAttribute("registerInfo", new UserRegistrationForm()); } @RequestMapping(value = "/reg", method = RequestMethod.POST) public String create( @Valid @ModelAttribute("registerInfo") UserRegistrationForm userRegistrationForm, BindingResult result) { if (result.hasErrors()) { return "register"; } userService.addUser(userRegistrationForm); return "redirect:/"; } ``` In short `create` method try to validate `UserRegistrationForm`. If form has errors, it leaves user on the same page with filled form fields where error message will be shown. Now I need to apply the same behaviour to another page, but here I have a problem: ``` @RequestMapping(value = "/buy/{buyId}", method = RequestMethod.GET) public String buyGet(HttpServletRequest request, Model model, @PathVariable long buyId) { model.addAttribute("buyForm", new BuyForm()); return "/buy"; } @RequestMapping(value = "/buy/{buyId}", method = RequestMethod.POST) public String buyPost(@PathVariable long buyId, @Valid @ModelAttribute("buyForm") BuyForm buyForm, BindingResult result) { if (result.hasErrors()) { return "/buy/" + buyId; } buyForm.setId(buyId); buyService.buy(buyForm); return "redirect:/show/" + buyId; } ``` I faced with issue of dynamic url. Now if form has errors I should specify the same page template to stay on current page, but also I should pass `buyId` as a path variable. Where are a conflict in this two requirements. If I leave this code as is, I get an error (I'm using Thymeleaf as a template processor): ``` Error resolving template "/buy/3", template might not exist or might not be accessible by any of the configured Template Resolvers ``` I can write something like `return "redirect:/buy/" + buyId`, but in this case I lose all data and errors of form object. What should I do to implement in `buyPost` method the same behaviour as in `create` method?