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?

Original source

Related problems