SpringBoot CRUD应用更新删除报错:Request method 'POST' not supported
问题描述
基于Spring Boot开发CRUD应用,使用PostgreSQL数据库并集成Spring Security,查询和创建功能正常,但执行更新或删除操作时出现如下错误:
2022-11-01 08:51:14.602 WARN 12149 --- [io-8080-exec-10] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.web.HttpRequestMethodNotSupportedException: Request method 'POST' not supported]
问题原因
浏览器原生表单仅支持GET和POST请求方法,但你的Controller中更新用了@PatchMapping、删除用了@DeleteMapping,直接提交POST请求无法匹配这些映射。Spring MVC需要通过HiddenHttpMethodFilter来将POST请求转换为对应的HTTP方法,而你的HTML表单中缺少触发该转换的关键配置。
解决方案
1. 修改HTML表单,添加请求方法转换隐藏域
删除功能表单修改:
<!DOCTYPE html> <html lang="en" xmlns:th="https://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>Student</title> </head> <body> <h1 th:text="${student.get().getFullStudentName()}"></h1> <hr> <form method="post" th:action="@{/students/{id}(id=${student.get().getId()})}"> <!-- 添加隐藏域指定真实请求方法为DELETE --> <input type="hidden" name="_method" value="DELETE"> <input type="submit" value="Delete"> </form> </body> </html>
更新功能表单(edit.html)修改示例:
<!DOCTYPE html> <html lang="en" xmlns:th="https://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>Edit Student</title> </head> <body> <h1>Edit Student</h1> <form method="post" th:action="@{/students/{id}(id=${student.getId()})}"> <!-- 添加隐藏域指定真实请求方法为PATCH --> <input type="hidden" name="_method" value="PATCH"> <!-- 其他表单字段示例 --> <input type="text" th:field="*{fullStudentName}" placeholder="Full Name"> <!-- 其他字段省略 --> <input type="submit" value="Update"> </form> </body> </html>
2. 确保HiddenHttpMethodFilter生效
Spring Boot 2.x及以上版本中,HiddenHttpMethodFilter默认已自动配置启用。如果项目是自定义配置,需确保在配置类中注册该过滤器:
import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.filter.HiddenHttpMethodFilter; @Configuration public class WebConfig { @Bean public FilterRegistrationBean<HiddenHttpMethodFilter> hiddenHttpMethodFilter() { FilterRegistrationBean<HiddenHttpMethodFilter> registrationBean = new FilterRegistrationBean<>(); registrationBean.setFilter(new HiddenHttpMethodFilter()); registrationBean.addUrlPatterns("/*"); return registrationBean; } }
原理说明
当表单提交POST请求时,HiddenHttpMethodFilter会检查请求参数中是否存在_method字段,若存在则将请求的HTTP方法替换为该字段的值,这样后台的@PatchMapping和@DeleteMapping就能正确匹配到请求,避免出现方法不支持的错误。
内容的提问来源于stack exchange,提问作者John

