Spring MVC + Tomcat 8.5 踩坑实录:Servlet 版本引发的部署失败


🚧 Spring MVC + Tomcat 8.5 踩坑实录:Servlet 版本引发的部署失败

🌐 作者:劲爽小猴头

🗓️ 时间:2025-05-28

📚 关键词:Spring MVC、Tomcat、Servlet、WAR部署、web.xml、Maven、JDK 22


🧩 项目背景

在搭建一个经典的 Spring MVC 项目时,遇到严重的 Tomcat 启动失败问题。环境配置如下:

  • IDEA:2024.1

  • JDK:22

  • Tomcat:8.5.97

  • Spring Framework:5.3.34

  • Servlet API:原来是 4.0.1

  • 打包方式:Maven + WAR


🚨 遇到的错误信息

部署项目到 Tomcat 后,控制台抛出如下错误:

复制代码
Caused by: java.lang.IllegalArgumentException: 找到名为 [spring_web] 的片段。这不是一个合法的名字...

紧接着部署失败,报错信息中还提示:

复制代码
Cannot deploy artifact springmvc-demo:war
Illegal web fragment name

此外,在 web.xml 文件中 IDEA 出现密集报错,例如:

  • Element web-app must be declared

  • Cannot resolve symbol 'servlet-name'

  • Multiple root tags


🔍 问题根因分析

1️⃣ Servlet 版本冲突

  • Tomcat 8.5 的原生支持为 Servlet 3.0/3.1

  • 但项目中引入了 Servlet 4.0.1,导致 web fragment 名称验证失败

2️⃣ web.xml schema 版本不兼容

  • 原来使用的是:

  • IDEA 和 Tomcat 均对这个 schema 支持不佳,IDE 识别失败,Tomcat 启动异常。


🛠️ 解决方案(最终稳定方案)

✅ 一、降级 Servlet API 到 3.0.1

pom.xml 中修改依赖:

复制代码
<dependency>
  <groupId>javax.servlet</groupId>
  <artifactId>javax.servlet-api</artifactId>
  <version>3.0.1</version>
  <scope>provided</scope>
</dependency>

⚠️ 注意:scope 必须是 provided,否则会导致 WAR 包重复引入 servlet 相关类。


✅ 二、重写 web.xml 使用 Servlet 3.0 schema

替换为如下配置(位于 src/main/webapp/WEB-INF/web.xml):

复制代码
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
                             http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
         version="3.0">

    <display-name>Spring MVC Demo</display-name>

    <servlet>
        <servlet-name>dispatcher</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>/WEB-INF/dispatcher-servlet.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>dispatcher</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

    <!-- 关闭 web-fragment 检查 -->
    <absolute-ordering/>
</web-app>

🧪 重启部署流程

复制代码
mvn clean package

然后重新部署 springmvc-demo.war 到 Tomcat。

如果使用的是 IntelliJ:

  1. Build Artifact → springmvc-demo:war exploded

  2. 在 Run Configuration 中部署该 exploded artifact

  3. 启动 Tomcat


✅ 最终结果

🚀 浏览器访问 http://localhost:8080/springmvc-demo/,看到页面输出:

复制代码
👾 Hello Spring MVC!

✅ 不再出现 IllegalArgumentException

✅ IDEA 中的 web.xml 不再红色报错

✅ Tomcat 启动顺利,部署成功!


📌 总结 & 教训

问题 解决方式
Servlet 版本过高 使用 3.0.1,避免 Tomcat 8.5 不兼容
web.xml 报错 降级 schema 至 3.0
Tomcat 部署失败 关闭 web-fragment 排序

🧠 技术启示:

  • servlet-api 版本要和 Tomcat 版本精确匹配

  • IDEA 对 XML schema 的识别和语义检查十分敏感

  • Spring MVC 老项目依然稳定,但对配置正确性要求更高


🧙 Bonus:下一步可以做什么?

  • ☁️ 升级为 Spring Boot 避免 WAR 配置烦恼

  • 🧪 加入表单登录、拦截器、REST API

  • 🚀 用 Thymeleaf 替代 JSP 以获得更现代的体验


相关推荐
Java成神之路-14 小时前
基于 Spring AI+MCP 协议实现大模型调用本地自定义工具
java·spring·springaialibaba
会编程的吕洞宾14 小时前
Spring Boot多环境配置实战 配置文件加载顺序与切换不再翻车
java·后端
额鹅恶饿呃14 小时前
随着CentOS官方停服的时间越来越久,大量仍在使用CentOS7的企业和运维从业者
java·python·算法·c#·ruby
秋名RG14 小时前
Java 异常处理全攻略:从入门到实战(JDK 21 版)
java·开发语言
SQL-First布道者14 小时前
我为什么把 MyBatis 从项目中删了?
java·spring·tomcat·mybatis·mybatis plus·spring jdbc
公爵爱学习14 小时前
无人机多点导航笔记
java·前端·笔记
萧瑟余晖15 小时前
Java深入解析篇五十五之Unsafe 机制详解
java
kakawzw15 小时前
mybatis源码笔记1——JDBC和整体架构
java·mybatis
sunshine22 girl15 小时前
Java学习一 环境配置1 安装JDK,配置环境变量
java·开发语言·学习
秋饼15 小时前
Spring AI Session API 深度实战:从 ChatMemory 平滑迁移到事件溯源的企业级短期记忆
java·ai·技术分享·后端开发