如何让Tomcat运行Spring/React应用(部署后出现404错误)
我之前也踩过Spring Boot + React打包部署Tomcat的404坑,结合你的配置和描述,咱们一步步排查解决:
1. 先确认War包的部署上下文路径
本地运行Spring Boot默认是根路径(/),但Tomcat部署War包时,如果你的War包名字不是ROOT.war,访问路径会变成http://localhost:8080/你的War包名称/。如果React打包时没适配这个路径,静态资源和路由都会找不到。
解决办法:
在React项目的package.json中添加homepage配置:
"homepage": "."
或者如果你明确知道部署的上下文路径(比如War包名叫map-runner),可以直接指定:
"homepage": "/map-runner/"
这个配置会让React打包时生成的资源路径变为相对路径或对应上下文的绝对路径,避免找不到静态文件。
2. 检查静态资源是否被正确打包进War包
你的Maven配置里用maven-resources-plugin把React的build目录复制到了${project.build.outputDirectory}/static,也就是War包的WEB-INF/classes/static目录下。但要确保:
${frontend-src-dir}是否正确指向了src/main/frontend?检查pom.xml里的properties配置,比如:<properties> <frontend-src-dir>src/main/frontend</frontend-src-dir> <!-- 其他配置 --> </properties>- 打包后解压War包,查看
WEB-INF/classes/static下是否有React打包后的index.html、css、js等文件。如果没有,说明maven-resources-plugin的执行时机或路径配置有误,可以调整<phase>为process-resources试试。
3. 废弃开发环境的代理配置,改用相对路径请求API
你提到的React代理配置(package.json里的proxy)只在开发环境(npm start)生效,打包部署后,前端静态资源和后端接口都在Tomcat里,不需要代理。如果前端代码里的API请求写死了http://localhost:3000/api/xxx,部署后会去请求3000端口,自然找不到后端接口。
解决办法:
把前端的API请求改成相对路径,比如把http://localhost:3000/api/user改成/api/user。这样部署后,请求会自动带上Tomcat的上下文路径,比如http://localhost:8080/map-runner/api/user,就能正确打到Spring Boot的后端接口。
4. 确认Spring Boot的War打包配置正确
- 确保pom.xml里设置了
<packaging>war</packaging>,否则Maven默认会打Jar包,Tomcat无法正确识别。 - 你的主类已经继承了
SpringBootServletInitializer并重写了configure方法,这部分是正确的,确保主类能被Tomcat正确加载。
5. 检查Spring Boot和Tomcat的版本兼容性
Spring Boot和Tomcat版本不兼容也会导致部署后无法正常启动:
- Spring Boot 2.x 适配 Tomcat 9.x
- Spring Boot 3.x 必须用 Tomcat 10.x 及以上(因为改用了Jakarta EE规范)
如果你的Tomcat版本和Spring Boot不匹配,升级或降级到兼容版本即可。
按照上面的步骤逐一排查,应该就能解决你的404问题。我当时就是因为没加homepage配置,导致静态资源路径错误,加上之后就正常了。
内容的提问来源于stack exchange,提问作者guido




