You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring 6.0.5部署Tomcat 8.5.81时DispatcherServlet类型转换异常求助

Spring 6.0.5部署Tomcat 8.5.81的ClassCastException问题分析与解决

场景说明

在Tomcat 8.5.81上部署Spring 6.0.5应用,通过web.xml配置org.springframework.web.servlet.DispatcherServlet,运行时抛出类转换异常。

相关配置

web.xml配置

<servlet>
    <servlet-name>dispatcher</servlet-name>
    <servlet-class>
        org.springframework.web.servlet.DispatcherServlet
    </servlet-class>
</servlet>
<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/spring/dispatcher-config.xml</param-value>
</context-param>

<listener>
    <listener-class>
        org.springframework.web.context.ContextLoaderListener
    </listener-class>
</listener>

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

dispatcher-config.xml配置

<mvc:annotation-driven/> 
<mvc:resources mapping="/resources/**" location="/resources/"/> 
<context:component-scan base-package="org.mainPackage" /> 
<context:annotation-config/>
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="prefix">
        <value>/WEB-INF/views/</value>
    </property>
    <property name="suffix">
        <value>.jsp</value>
    </property>
</bean>

pom.xml相关依赖

<properties>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
    <java.version>17</java.version>
    <tomcat.version>8.5.81</tomcat.version>
    <servlet-api.version>3.1.0</servlet-api.version>
</properties>

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-web</artifactId>
    <version>6.0.5</version>
</dependency>

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-core</artifactId>
    <version>6.0.5</version>
</dependency>

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>6.0.5</version>
</dependency>

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>3.1.0</version>
    <scope>provided</scope>
</dependency> 
<dependency>
    <groupId>jakarta.servlet.jsp.jstl</groupId>
    <artifactId>jakarta.servlet.jsp.jstl-api</artifactId>
    <version>3.0.0</version>
</dependency>

<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>jstl</artifactId>
    <version>1.2</version>
</dependency>

异常信息

javax.servlet.ServletException: Class [org.springframework.web.servlet.DispatcherServlet] is not a servlet
根因:
java.lang.ClassCastException: class org.springframework.web.servlet.DispatcherServlet cannot be cast to class javax.servlet.Servlet (org.springframework.web.servlet.DispatcherServlet is in unnamed module of loader org.apache.catalina.loader.ParallelWebappClassLoader @4ac6da24; javax.servlet.Servlet is in unnamed module of loader java.net.URLClassLoader @28c97a5)

异常原因

  1. 核心API包名不兼容:Spring 6基于Jakarta EE 9+规范,依赖的是jakarta.servlet.Servlet接口;而Tomcat 8.5.x属于传统Servlet容器,使用的是javax.servlet.Servlet API。两者属于不同的包空间,类加载器无法将实现Jakarta接口的DispatcherServlet转换为Tomcat期望的javax版本接口。
  2. 依赖混乱与版本不匹配:
    • pom.xml同时引入了javax版本的Servlet API和Jakarta版本的JSTL,包名冲突导致类加载异常;
    • Java编译级别设置为1.8,但Spring 6要求最低Java 17,编译与运行环境不匹配;
    • 同时手动引入Spring核心依赖和spring-boot-starter-web,存在依赖重复或版本不一致风险。

解决方案

方案一:升级Tomcat版本(推荐)

Spring 6要求Servlet 5.0+(对应Jakarta EE 9),只有Tomcat 10.x及以上版本支持Jakarta Servlet API(包名从javax.servlet改为jakarta.servlet)。将Tomcat升级到10.1.x(兼容Java 17,与Spring 6完美匹配),可直接解决核心包名冲突问题。

方案二:降级Spring版本(仅当无法升级Tomcat时使用)

若必须保留Tomcat 8.5.x,需将Spring版本降级到5.3.x(Spring 5.x基于javax.servlet API,与Tomcat 8.5完全兼容),同时将所有Spring相关依赖版本统一为5.3.x系列。

配套依赖配置调整

  1. 统一Java编译级别:
    修改pom.xml的编译配置,确保与运行环境一致(以Java 17为例):
    <properties>
        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>
        <java.version>17</java.version>
        <!-- 若用Tomcat 10.x,使用Jakarta Servlet版本 -->
        <jakarta.servlet.version>5.0.0</jakarta.servlet.version>
    </properties>
    
  2. 清理冲突依赖:
    • 若升级Tomcat到10.x,移除所有javax.servlet相关依赖,替换为Jakarta版本:
      <!-- 移除javax.servlet-api和javax.servlet:jstl -->
      <dependency>
          <groupId>jakarta.servlet</groupId>
          <artifactId>jakarta.servlet-api</artifactId>
          <version>${jakarta.servlet.version}</version>
          <scope>provided</scope>
      </dependency>
      <dependency>
          <groupId>org.glassfish.web</groupId>
          <artifactId>jakarta.servlet.jsp.jstl</artifactId>
          <version>3.0.1</version>
      </dependency>
      
    • 移除重复的Spring依赖:如果使用spring-boot-starter-web,无需手动引入spring-web、spring-core、spring-context,starter会自动管理这些依赖,避免版本冲突。
  3. 更新web.xml命名空间(仅Tomcat 10.x需做):
    将web.xml的根命名空间替换为Jakarta EE的标准命名空间:
    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns="https://jakarta.ee/xml/ns/jakartaee"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_5_0.xsd"
             version="5.0">
        <!-- 原servlet、listener等配置内容保持不变 -->
    </web-app>
    

内容的提问来源于stack exchange,提问作者Sam

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 18:15:11