Spring 引导 POST 使用经过验证的表单 bean *和* RequestParam 的映射在无效表单上给出 405 错误

Spring Boot POST mapping with a validated form bean *and* a RequestParam gives 405 error on invalid form

在我的 Spring 引导应用程序中,我有一个 "edit user" 表单,该表单绑定到一个 SecurityUser bean,但有一个额外的(非 bean)字段用于确认密码。我的控制器中的 GET 映射如下所示:

@GetMapping("/security/user/{username}")
public String showEditUserForm(@PathVariable("username") String username, Model model) {
    model.addAttribute("securityUser",securityUserService.findByUsername(username));
    return "/security/edituser";
}

在 POST 映射中,我想检查密码确认输入的值并将其与密码字段值进行比较,所以我这样编码:

@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";
}

如果表单有效,则一切正常(当然,它只是记录并重定向到成功页面)。但是,如果任何表单字段无效,则会导致 405 错误(不支持 HTTP 方法)。

在日志中是:

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]

最初 GET 和 POST 端点是不同的,所以我让它们相同,如您所见,这显然不是解决方案。如果我从 POST 映射中删除 @BindingResult 变量,错误就会消失,但显然我无法检查密码确认。

如何在 Spring 引导 POST 映射中访问不是 bean 字段 的表单输入 而不会发生此错误?

这是参数顺序真正重要的罕见情况之一。 BindingResult 参数必须紧跟在您要验证的对象之后。

来自the documentation

You must declare an Errors, or BindingResult argument immediately after the validated method argument.