SignupController.java:

@Controller
public class SignupController {

  @GetMapping(value = "/signup.html")
  public String signupForm(Model model) {
    // ...
    return "signup";
  }

  @PostMapping(value = "/signup.html")
  public String signup(@Valid @ModelAttribute("user") User user, BindingResult bindingResult, Model model, RedirectAttributes redirectAttrs) {
    if (bindingResult.hasErrors()) {
        // Common model, as set in GET handler.
        // model.addAttribute("...", ...);
        return "signup";
    }

    // ...

    // Redirect after POST to prevent double-submit via page refresh
    redirectAttrs.addFlashAttribute(SIGNUP_SUCCESS_ATTR_NAME, Boolean.TRUE);
    return "redirect:/signup-success.html";
  }

    @GetMapping(value = "/signup-success.html")
    public String signupSuccess(HttpServletRequest request) {
        // Request should come from a Redirect after POST.
        Map<String, ?> inputFlashMap = RequestContextUtils.getInputFlashMap(request);
        if (inputFlashMap == null || inputFlashMap.get(SIGNUP_SUCCESS_ATTR_NAME) == null) {
            return "redirect:/signup.html";
        }
        return "signup-success";
    }

}