In my Spring Boot application I have an "edit user" form, the form is bound to a SecurityUser bean, but has an additional (non-bean) field for confirming the password. The GET mapping in my controller looks like this:
@GetMapping("/security/user/{username}")
public String showEditUserForm(@PathVariable("username") String username, Model model) {
model.addAttribute("securityUser",securityUserService.findByUsername(username));
return "/security/edituser";
}
In the POST mapping, I want to check the password confirmation input's value and compare it to the password field value, so I coded it like this:
@PostMapping("/security/user/{username}")
public String processEditUser(@Valid SecurityUser securityUser, @RequestParam String confirmPassword, BindingResult bindingResult, RedirectAttributes redirectAttributes) {
if (bindingResult.hasErrors()) {
return "security/edituser";
}
logger.debug(securityUser.toString());
logger.debug(confirmPassword);
redirectAttributes.addFlashAttribute("flashstatus","success");
redirectAttributes.addFlashAttribute("flashmessage","You successfully submitted an edituser form");
return "redirect:/security/success";
}
If the form is valid, everything works fine (granted, it's just logging and a redirect to a success page). But if any form field is invalid, a 405 error (HTTP method not supported) is the result.
In the logs it's:
2020-02-06 15:44:39.114 WARN 20496 --- [nio-8080-exec-7] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.web.HttpRequestMethodNotSupportedException: Request method 'POST' not supported]
Originally the GET and POST endpoints were different, so I made them the same, as you can see, and that obviously wasn't the solution. If I eliminate the @BindingResult variable from the POST mapping, the bug goes away, but then I obviously can't check the password confirmation.
How can I access a form input that's not a bean field in a Spring Boot POST mapping without this error occurring?
BindingResultparameter right after the bean you want to validate, i.e.SecurityUser?public String processEditUser(@Valid SecurityUser securityUser, BindingResult bindingResult, @RequestParam String confirmPassword, RedirectAttributes redirectAttributes) {}. But why? How???