重新打包 WAR 部署后报 404 是 Java Web 项目(如 Spring Boot/Spring MVC)部署的高频问题,核心原因是打包产物异常、部署配置不匹配、上下文路径 / 资源映射错误。以下是按优先级排序的完整排查与解决步骤:
一、先确认核心问题方向(快速定位)
- 先判断:是 "应用没启动" 还是 "资源找不到"
查看服务器容器日志(Tomcat/Jetty):
bash
运行
Tomcat 示例(找到 catalina.out 或 localhost_access_log)
tail -f TOMCAT_HOME/logs/catalina.out
如果日志中无应用启动日志 → 应用未部署成功(WAR 损坏 / 容器未识别);
如果有启动日志但报 404 → 上下文路径 / 接口路径 / 静态资源映射错误。
检查容器 webapps 目录:
bash
运行
查看 WAR 是否被解压(Tomcat 会自动解压 WAR)
ls TOMCAT_HOME/webapps/
如果只有 your-app.war 无解压文件夹 → WAR 损坏 / 容器权限不足;
如果有解压文件夹但仍 404 → 上下文路径或资源路径错误。
二、分步排查与解决(核心步骤)
步骤 1:验证 WAR 包本身是否正常(最常见原因)
重新打包的 WAR 可能因编译 / 打包配置错误导致内容缺失:
本地先验证 WAR 包有效性
bash
运行
1. 解压 WAR 包查看内容(本地/服务器均可)
unzip your-app.war -d temp-war
2. 检查关键文件是否存在
ls temp-war/WEB-INF/classes/ # 编译后的 class 文件是否齐全
ls temp-war/WEB-INF/lib/ # 依赖包是否完整
ls temp-war/static/ # 静态资源(js/css/html)是否存在
❌ 异常情况:
classes 目录为空 / 缺少核心类 → 打包时未编译代码(如 Maven/Gradle 打包命令错误);
静态资源缺失 → 打包时未包含 static/templates 目录;
lib 目录缺少核心依赖 → 打包时依赖未引入(如 provided 范围错误)。
重新打包(确保打包命令正确)
Maven 项目(推荐清理后打包):
bash
运行
先清理旧产物,再打包(避免缓存)
mvn clean package -DskipTests
Spring Boot 打包(需指定打包类型为 war):
bash
运行
确保 pom.xml 中war
mvn clean package -DskipTests -Pprod # 如有环境配置需指定 profile
✅ 验证:打包后检查 target/your-app.war 大小,与之前可用的 WAR 对比,差距过大(如从几十 M 变几 K)说明打包失败。
步骤 2:检查上下文路径配置(404 核心原因)
重新部署后上下文路径可能变化,导致访问路径与实际不符:
确认容器上下文路径
Tomcat 默认上下文路径 = WAR 包名(如 your-app.war → 访问路径 http://ip:port/your-app/xxx);
如果之前是 "根路径"(http://ip:port/xxx),重新打包后 WAR 名变化 → 404。
✅ 解决方式:
方式 1:重命名 WAR 为 ROOT.war(Tomcat 根上下文):
bash
运行
mv your-app.war TOMCAT_HOME/webapps/ROOT.war
方式 2:修改 Tomcat server.xml 配置固定上下文路径:
xml
检查应用内上下文路径配置Spring Boot 项目需确认 application.yml/application.properties 中是否配置了上下文路径:
yaml
application.yml
server:
servlet:
context-path: / # 确保为根路径(或与访问路径一致)
❌ 错误:如果配置了 context-path: /app,访问时需加 /app 前缀,否则 404。
步骤 3:检查资源 / 接口映射是否正常
静态资源 404(如 HTML/CSS/JS)
检查 WAR 包内静态资源路径(如 static/ templates/)是否存在;
Spring Boot 项目确认静态资源映射配置:
java
运行
// 确保有静态资源映射配置(默认已包含,若自定义需检查)
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/static/**")
.addResourceLocations("classpath:/static/");
}
}
接口 404
检查 Controller 注解路径是否正确(如 @RequestMapping("/api/xxx"));
检查启动类是否扫描到 Controller(@SpringBootApplication 包扫描范围是否包含 Controller):
java
运行
// 启动类需放在根包下,或指定扫描包
@SpringBootApplication(scanBasePackages = "com.xxx")
public class YourAppApplication extends SpringBootServletInitializer {
// Spring Boot WAR 部署必须重写此方法
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(YourAppApplication.class);
}
public static void main(String[] args) {
SpringApplication.run(YourAppApplication.class, args);
}
}
❌ 常见错误:WAR 部署时未继承 SpringBootServletInitializer → 应用启动但未加载 Spring 上下文 → 接口 404。
步骤 4:检查服务器容器配置与权限
容器版本兼容性
重新打包的应用若升级了依赖(如 Spring Boot 2.x → 3.x),需确认 Tomcat 版本兼容(Spring Boot 3.x 需 Tomcat 10+);
查看容器启动日志,是否有 ClassNotFoundException/NoClassDefFoundError → 依赖版本不兼容。
服务器权限
Tomcat 运行用户无 WAR 解压 / 读写权限 → 解压失败导致 404:
bash
运行
赋予 Tomcat 目录权限
chown -R tomcat:tomcat TOMCAT_HOME/webapps/
chmod -R 755 TOMCAT_HOME/webapps/
容器缓存 / 旧部署残留
删除 Tomcat work 目录缓存(避免旧编译文件干扰):
bash
运行
rm -rf TOMCAT_HOME/work/Catalina/localhost/*
停止容器 → 删除 webapps 下旧 WAR / 解压文件夹 → 重新放入新 WAR → 启动容器。
三、快速验证流程(总结)
本地 mvn clean package 打包 → 解压验证 WAR 内容完整;
服务器停止 Tomcat → 删除 webapps 下旧文件 → 放入新 WAR(重命名为 ROOT.war);
删除 Tomcat work 目录 → 启动 Tomcat;
查看 catalina.out 确认应用启动成功;
访问 http://ip:port/(根路径)测试核心接口 / 页面。
四、常见坑点补充
打包时跳过测试导致编译失败:-DskipTests 仅跳过测试,若代码编译错误(如语法问题),WAR 仍会生成但内容缺失 → 先执行 mvn clean compile 验证编译;
多模块项目打包错误:需在父模块执行 mvn clean package,或确保子模块打包为 war;
配置文件未生效:打包时未将 application.yml 放入 resources 目录 → 应用使用默认配置导致路径错误。