Java Web项目需JDK、Servlet容器及类路径隔离三者缺一不可:JDK版本须匹配框架要求(如Spring Boot 3.x需JDK 17),必须部署于Tomcat/Jetty/Undertow等Servlet容器,Maven的provided作用域确保servlet-api等由容器提供,IDE运行≠环境正确,最终应通过mvn package后手动部署验证。

Java Web 项目不是装个 JDK 就能跑的,它依赖一套分层运行环境,缺一不可——最常被忽略的是 Servlet 容器和类路径隔离机制。
必须装 JDK,但版本不能乱选
Java Web 项目(尤其用 Spring Boot 2.x 或传统 Servlet 3.1+)至少需要 JDK 8,但很多新框架(如 Spring Boot 3.x、Jakarta EE 9+)已要求 JDK 17 或更高。用 java -version 确认实际运行版本,别只看 IDE 里配的 SDK;Maven 编译插件(maven-compiler-plugin)的 source 和 target 必须与运行时一致,否则出现 UnsupportedClassVersionError。
Web 项目必须跑在 Servlet 容器里
Java 普通类库不处理 HTTP 请求,main 方法起不来 Web 服务。你需要一个实现了 Servlet 规范的容器:
-
Tomcat(最常用,轻量、调试友好,支持 WAR 部署) -
Jetty(嵌入式场景多,Spring Boot 默认内置的就是它) -
Undertow(WildFly 默认,高性能,但生态工具链少)
注意:Spring Boot 的 spring-boot-starter-web 默认拉取 spring-boot-starter-tomcat,若想换 Jetty,得排除 Tomcat 并显式引入 spring-boot-starter-jetty;WAR 包部署到外部 Tomcat 时,需把 spring-boot-starter-tomcat 的 scope 设为 provided,否则会冲突。
立即学习“Java免费学习笔记(深入)”;
构建工具决定依赖怎么加载
Maven 或 Gradle 不只是打包用的——它们控制着 WEB-INF/lib 下放哪些 JAR、是否传递依赖、是否排除冲突包:
- Maven 的
scope=provided(如servlet-api)表示“容器已提供,编译需要但不打进 WAR” - 没加
provided却打了servlet-api.jar进 WAR,Tomcat 启动会报java.lang.ClassCastException: javax.servlet.http.HttpServletRequest cannot be cast to org.apache.catalina.connector.Request -
spring-boot-maven-plugin打jar包时默认内嵌容器,打war包则需继承SpringBootServletInitializer并重写configure
IDE 跑起来 ≠ 环境就对了
IntelliJ/Eclipse 内置的 Tomcat 运行配置容易掩盖真实问题:
- IDE 可能用自己缓存的 classpath 而非项目 target/classes,改了代码没生效,以为是热部署失败
- IDE 自动添加
tomcat-servlet-api到编译路径,但部署到生产 Tomcat 时反而因版本不匹配抛NoClassDefFoundError - 调试时看到
ClassNotFoundException,先检查WEB-INF/lib目录下有没有对应 JAR,再确认其 MANIFEST.MF 里没声明Optional: true或冲突的Import-Package
真正可靠的验证方式:用 mvn clean package 生成 WAR,手动丢进干净安装的 Tomcat webapps/ 下启动,看 logs/catalina.out。










