最后更新:2026-10-28
适用场景:Spring Boot 3.x、Spring MVC、反向代理部署

本地访问接口正常,部署到服务器后全是 404;或者浏览器请求 404,直接用 curl 访问应用端口却能成功。看到 404 先别去改 Controller 的业务代码。它只说明这次请求没找到目标资源,还不能说明请求到过 Spring MVC。

先看 404 是谁返回的

在浏览器 Network 里记下完整 URL、HTTP 方法、状态码和响应头。若前面有 Nginx、网关或 CDN,再对照它们的访问日志与应用日志。应用日志里完全没有这次请求,先查域名解析、代理路由和路径重写;请求已到应用,再查 Spring 的映射。

在可信测试环境里,对同一条路径分别经域名和直连应用端口请求:

curl -i 'https://example.com/api/users/42'
curl -i 'http://127.0.0.1:8080/api/users/42'

第二条只适用于应用端口可安全直连的环境,不要为排查把内网服务临时暴露到公网。两条结果不同,优先检查代理转发了什么路径;两条都 404,再看应用映射。

把“最终路径”拼完整

下面的方法最终对应 GET /api/users/42,不是 /users/42:

@RestController
@RequestMapping("/api/users")
public class UserController {
    @GetMapping("/{id}")
    public String find(@PathVariable Long id) {
        return "user=" + id;
    }
}

类上的路径、方法上的路径要合起来看;@GetMapping 只接 GET,请求用 POST 时不能简单归为“URL 写错”,应先看实际响应状态和服务端日志。再检查 server.servlet.context-path。若它设为 /app,上述路径在应用入口就会带上 /app。代理若已经加了 /app,前端又加一次,就会出现双前缀。不要同时修改代理与应用配置来碰运气。Spring MVC 映射文档解释了类级和方法级映射规则。

映射根本没有注册时

先确认启动的是新构建的 Jar,而非旧版本;再看 Controller 是否带 @RestController / @Controller,是否位于启动类包或其子包下。类文件存在不等于被 Spring 扫描。包扫描的排查可接着看Spring Boot 找不到 Bean 怎么排查。

若项目已经安装并安全配置了 Actuator,可在受控环境查看 mappings 端点,确认这条 URL 和方法是否真的注册。不要为了查一条映射就把管理端点公开到互联网。Spring Boot Actuator 文档说明了 mappings 的用途与访问控制。

只在部署后 404:重点看代理与前端路由

例如代理把 /api/users/42 转发成了 /users/42,后端自然匹配不到。检查代理配置时,记录转发前后的实际路径,尤其注意 location 与 proxy_pass 的斜杠处理。前端单页应用刷新某个页面返回 404,则可能是静态站点回退路由问题,和后端 /api/** 的 Controller 不是同一件事。两类 404 要分开处理。

最后做一次完整复测:用同一 HTTP 方法、同一 URL、同一请求头从浏览器和命令行各请求一次,核对代理日志、应用日志、最终响应。若真正报的是跨域预检 403,应转到跨域预检排查,不要把所有浏览器请求失败都叫 404。

参考资料

Spring Framework 6.2:Mapping Requests
Spring Boot 3.5:Actuator Endpoints
Spring Boot 3.5:Common Application Properties

更新记录

2026-10-28:创建文章,补充代理、路径映射与部署版本排查。