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 版本不兼容

  • 原来使用的是:

    <web-app version="4.0">
  • 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 以获得更现代的体验


相关推荐
晴空月明9 分钟前
Spring IoC容器与依赖注入深度解析
java
Java初学者小白11 分钟前
秋招Day14 - MySQL - 数据库架构
java·数据库·数据库架构
转码的小石24 分钟前
深入Java大厂面试:从Spring框架到微服务架构的技术解析
java·spring boot·spring cloud·微服务·junit·spring security·hibernate
大熊程序猿36 分钟前
quartz 表达式最近10次执行时间接口编写
java·服务器·前端
小猫咪怎么会有坏心思呢1 小时前
华为OD机试-云短信平台优惠活动-完全背包(JAVA 2024E卷)
java·开发语言·华为od
PHP武器库1 小时前
想学编程,java,python,php先学哪个比较好?
java·python·php
jarctique1 小时前
java 找出两个json文件的不同之处
java·json
ybdesire1 小时前
MCPServer编程与CLINE配置调用MCP
android·java·数据库
转码的小石2 小时前
深入Java面试:从Spring Boot到微服务
java·spring boot·kafka·spring security·oauth2
程序员的世界你不懂2 小时前
将生成的报告通过jenkins发送邮件通知
java·servlet·jenkins