Spring Boot+Thymeleaf th:method=put/delete报405问题咨询
问题背景
- 基于start.spring.io初始化Spring Boot v2.7.0项目,集成Thymeleaf依赖,父POM管理的关联依赖版本如下:
- thymeleaf-spring5:v3.0.15.RELEASE
- thymeleaf-extras-java8time:v3.0.4.RELEASE
- 业务需求:使用
<form th:method="put/delete".../>形式的表单提交REST风格请求 - 参考资料:《Taming Thymeleaf Practical Guide to building a web application with Spring Boot and Thymeleaf - Wim Deblauwe》及公开技术文档
初始配置与报错现象
配置步骤
- 首先在
application.properties中添加配置项spring.mvc.hiddenmethod.filter.enabled=true,配置未生效后切换为application.yaml编写等效配置:
spring: mvc: hiddenmethod: filter: enabled: true
- 前端表单按规范编写
th:method="put"、th:method="delete"属性 - 后端控制器使用
@PutMapping、@DeleteMapping注解完成请求映射
报错信息
完成上述配置后访问对应接口抛出405错误,核心报错日志如下:
There was an unexpected error (type=Method Not Allowed, status=405). Request method 'POST' not supported org.springframework.web.HttpRequestMethodNotSupportedException: Request method 'POST' not supported at org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMapping.handleNoMatch(RequestMappingInfoHandlerMapping.java:253) at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.lookupHandlerMethod(AbstractHandlerMethodMapping.java:442)
临时解决方案
通过手动注册HiddenHttpMethodFilter过滤器Bean的方式解决了问题,注册代码如下:
@Bean public FilterRegistrationBean<HiddenHttpMethodFilter> hiddenHttpMethodFilter() { FilterRegistrationBean<HiddenHttpMethodFilter> filterRegistrationBean = new FilterRegistrationBean<>(new HiddenHttpMethodFilter()); filterRegistrationBean.setUrlPatterns(Arrays.asList("/*")); return filterRegistrationBean; }
核心疑问
为何配置spring.mvc.hiddenmethod.filter.enabled=true后,Spring Boot没有自动注册所需的HiddenHttpMethodFilter Bean,必须手动注册才能正常使用th:method绑定的PUT/DELETE提交模式?
原因解答
Spring Boot 2.7.x对HiddenHttpMethodFilter的自动配置有明确的前置条件,不是只开配置项就一定会生效:
- 负责注册该过滤器的自动配置类为
WebMvcAutoConfiguration,除了要求spring.mvc.hiddenmethod.filter.enabled=true配置为真,还需要满足以下约束才会自动注册默认过滤器:- 类路径下存在
spring-webmvc依赖(常规Spring Web场景都会自带,几乎不会缺失) - 当前Spring容器中不存在用户自定义的
HiddenHttpMethodFilter或OrderedHiddenHttpMethodFilter类型Bean。只要容器里已经有同类型的过滤器Bean,自动配置会直接跳过,不再读取配置项注册默认实例。
- 类路径下存在
- 配置不生效的核心原因基本都是这两类:
- 项目引入的第三方starter、或者其他自定义Web配置类提前注册了
HiddenHttpMethodFilter实例,但没有配置正确的拦截路径,默认拦截规则没有覆盖业务请求路径。这种情况下带_method隐藏参数的POST请求不会被过滤器转换请求方法,会直接以POST形式打到仅接收PUT/DELETE的控制器方法上,触发405报错。 - 如果项目集成了Spring Security,默认过滤器链的排序会让
HiddenHttpMethodFilter排在Security过滤器之后执行,此时请求已经被Security按POST规则完成校验,后续的方法转换不会生效,也会报方法不支持的错误。
- 项目引入的第三方starter、或者其他自定义Web配置类提前注册了
- 手动通过
FilterRegistrationBean注册过滤器并明确指定拦截路径为/*,相当于直接覆盖了容器中已有的不完整过滤器注册逻辑,请求能被正常拦截、完成POST到PUT/DELETE的方法转换,功能自然恢复正常。如果是Security排序问题,还需要在注册过滤器时设置order值,确保它在Spring Security过滤器链之前执行。
内容的提问来源于stack exchange,提问作者Thomas_Mylonas
相关产品推荐
相关产品推荐

