You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot应用异常:请求已抵达Tomcat但未到达Spring控制器

排查Spring Boot API上游调用异常的思路

这问题确实有点棘手——明明Tomcat日志显示200,但Spring控制器没收到请求,上游还报"Not found",自测却完全正常。结合你说的默认Tomcat配置,咱们可以从这几个方向一步步排查:

1. 先揪出请求的「细微差异」

自测用Postman/JMeter没问题,但上游不行,大概率是请求本身的细节不一样:

  • 检查路径大小写:Spring的@RequestMapping默认是大小写敏感的,比如你控制器是/api/user,上游如果调/api/User,DispatcherServlet匹配不到,Tomcat的默认Servlet会接手返回200(比如返回空页面或默认资源),但上游拿到的不是预期的API响应,就会判定为"Not found"。
  • 路径后缀/斜杠:比如上游请求多了.html后缀(/api/user.html),或者末尾多了斜杠(/api/user/),而你的控制器路径没有,同样会触发默认Servlet。
  • 请求方法不匹配:比如你控制器是POST接口,上游用GET调用,Tomcat默认Servlet处理GET请求返回200,但Spring不会处理,上游自然拿不到正确响应。

2. 检查Tomcat默认Servlet的「越权」行为

当Spring DispatcherServlet匹配不到任何请求映射时,Tomcat的DefaultServlet会自动接手处理请求,它通常返回静态资源、默认页面或者空内容,状态码都是200。这时候你可以:

  • 查看Tomcat访问日志的响应大小:如果响应字节数很小(比如几十字节),大概率是返回了空内容或Tomcat默认的空白页面,上游解析不到预期数据就报"Not found"。
  • 临时修改Spring Boot配置:在application.properties里加server.servlet.path=/*,把DispatcherServlet的映射路径改成/*(默认是/),这样所有请求都会先经过Spring,避免默认Servlet介入。

3. 排查请求头的「隐形坑」

上游的请求头可能和自测时不一样,导致Spring跳过处理:

  • Accept头:如果上游带了Spring不支持的媒体类型(比如text/plain但你的控制器只返回application/json),内容协商机制可能找不到合适的返回格式,进而触发默认Servlet。
  • Content-Type头:如果上游的请求体格式和声明的Content-Type不匹配(比如传JSON但写了application/x-www-form-urlencoded),Spring无法解析请求,可能直接跳过控制器处理。
  • 反向代理相关头:比如上游带了X-Forwarded-*这类头,而Spring Boot默认没开启相关配置,导致路径解析出错。

4. 高并发场景下的「连接池/线程池」问题

99%的请求失败,只有1%成功,可能和并发有关:

  • Tomcat默认的maxConnections(默认10000)和maxThreads(默认200)如果不足以支撑上游的并发量,可能会导致部分请求被Tomcat直接处理(而非转发给Spring),返回200但无有效响应。
  • 上游客户端的连接复用问题:比如上游用了错误的连接池配置,导致请求格式异常(比如请求体截断、头信息错误),Spring无法识别,交给默认Servlet处理。

5. 日志级别「遗漏关键信息」

你说没在应用日志里查到请求,可能是Spring的日志级别太高了:

  • 临时把org.springframework.web.servlet.DispatcherServlet的日志级别改成DEBUG,这样可以看到DispatcherServlet是否收到了请求,以及为什么没转发到控制器(比如会打印「No mapping found for HTTP request with URI...」这类关键日志)。
  • 检查Tomcat的localhost.log(不是访问日志),里面可能有请求处理的详细错误信息,比如参数绑定失败、路径匹配错误。

快速排查步骤

  1. 抓包对比请求:用工具捕获上游的请求和你自测的请求,逐字段对比(路径、方法、头、参数、请求体),找差异。
  2. 调整日志级别:开启DispatcherServlet的DEBUG日志,确认请求是否到达Spring层。
  3. 临时修改DispatcherServlet映射:加server.servlet.path=/*配置,强制所有请求经过Spring,看是否还会出现异常。
  4. 模拟上游请求:用Postman/JMeter完全复制上游的请求参数和头,测试是否能复现问题——如果能,就缩小排查范围到请求本身的问题。

内容的提问来源于stack exchange,提问作者Aditya Krishna Namdeo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.27 16:32:28