最后更新:2026-10-29
适用场景:Spring Boot 3.x、Spring MVC,接口因 HTTP 方法不匹配返回 405
URL 看着没错,直接贴进浏览器能访问,换成前端请求却是 405。这时先看请求真正用了什么 HTTP 方法,不要马上重写路径,更不要把 Controller 改成接受所有方法来试运气。405 的关键是当前返回层如何处理这个方法。
第一眼看方法和 Allow
HTTP 405 表示这个请求方法不被目标资源支持。标准要求响应携带 Allow,列出当前支持的方法,例如:
HTTP/1.1 405 Method Not Allowed
Allow: GET, HEAD
这是示意响应,不是所有应用都会原样展示。代理、过滤器或自定义异常处理也可能修改响应,所以 Allow 是线索,还要确认错误来自 Nginx、网关还是 Spring MVC。RFC 9110说明了 405 与 Allow 的含义。
在浏览器 Network 中保留完整 URL、实际方法、状态码、响应头与重定向链。地址栏访问默认用 GET,不能用它证明 POST、PUT 或 DELETE 接口一定正常。curl 的 -I 会发 HEAD,也不要把它当成普通 GET 的完整替代。
用一个最小映射做对照
下面的 Controller 只声明一个 GET 查询接口。放在已正确扫描 Controller 的测试项目里,再观察请求方法的差别:
import java.util.Map;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/api/orders")
public class OrderQueryController {
@GetMapping("/{id}")
public Map<String, Object> find(@PathVariable("id") long id) {
return Map.of("id", id);
}
}
在没有额外安全过滤器、代理和其他路由干扰的隔离测试环境里,对同一地址分别发 GET 和 POST:
curl -i 'http://127.0.0.1:8080/api/orders/42'
curl -i -X POST 'http://127.0.0.1:8080/api/orders/42'
GET 应匹配这个方法;POST 没有对应映射时,才会进入方法不支持的处理。测试命令中的地址是本地示例,不要对真实的下单、支付接口随意变换方法做试验。
类级路径与方法级路径要一起看,server.servlet.context-path、代理添加的前缀也要算进去。如果实际是 404,先转到接口 404 排查,别把所有请求失败都套进 405。
核对前端实际发出的那一笔请求
检查请求封装里的默认方法、表单提交方式,以及修改接口后有没有部署对应版本。某一处手工调试用 GET,业务代码却走了 POST,单看代码里那串 URL 很难发现差异。
还要逐跳看重定向。不同重定向状态和客户端策略可能改变后续请求方法;先记录原始响应的 Location 和每一步实际请求,再决定是否跟随跳转。排查开始时就给 curl 加上自动跟随,反而可能把第一次返回的关键信息藏掉。
如果应用已经安全启用了 Actuator,可在受控环境查看 mappings,核对当前运行实例真正注册的方法与路径。不要为了定位一个映射就把管理端点公开,也不要只凭本地源代码推断服务器运行的 Jar 内容。
OPTIONS 预检要单独看
浏览器可能先发 OPTIONS,再发业务请求。如果失败的是 OPTIONS,而业务请求根本还没发出,给 Controller 再加一个 POST 映射通常解决不了问题。
Spring MVC 对 HEAD 和 OPTIONS 有相应的默认处理,CORS 配置、安全过滤器和前置网关也都可能参与。应先确认是谁拒绝了预检,再按当前架构配置允许的来源、方法和请求头。相关链路见跨域预检请求 403 排查。Spring MVC 映射文档介绍了方法映射及 HEAD、OPTIONS 的处理。
如果是网关直接返回 405,先看它是否把请求落到了静态文件处理、错误的 location 或受限路由。此时改后端注解,未必会影响那个根本没到达应用的请求。
修复方法契约,再做完整复测
需要查询就使用约定的查询方法;需要创建或更新,就在接口设计中明确对应方法、鉴权和参数格式。不要为消除 405,把一个有写入副作用的操作顺手开放给 GET。
同时分清其他错误:缺少资源路径可能是 404,鉴权或安全拦截可能返回 401/403,请求媒体类型不匹配常见为 415。把 JSON 的 Content-Type 改来改去,不一定能解决一个真实的方法映射问题。
修复后,在浏览器与命令行使用同一方法、同一路径和必要请求头复测,核对实际部署版本和应用日志。如果修改了全局异常处理,也要检查它有没有把原本的状态码与 Allow 响应头吞掉,相关实现可看全局异常处理。
参考资料
RFC 9110:405 Method Not Allowed
Spring Framework 6.2:请求映射
Spring Boot 3.5:Actuator 端点
更新记录
2026-10-29:创建文章,整理 HTTP 方法、Allow、重定向与 OPTIONS 的排查顺序。
Spring Boot 接口返回 405 怎么排查
https://java.li/archives/spring-boot-http-405
评论