Spring 4.3升级至5.3.32后ControllerClassNameHandlerMapping类缺失求助
问题描述
我有一个基于Tomcat的Java应用,原Spring 4.3版本存在漏洞,将所有Spring JAR替换为5.3.32版本后启动失败,抛出ClassNotFoundException,提示找不到org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping类。已修改security-config.xml和spring-web-servlet.xml但问题仍未解决,本人无代码权限且对Spring不熟悉,需要无需修改Java代码的解决方案。
错误日志
02-Jun-2024 13:48:10.535 SEVERE [main] org.springframework.web.context.ContextLoader.initWebApplicationContext Context initialization failed org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping': Invocation of init method failed; nested exception is org.springframework.beans.factory.CannotLoadBeanClassException: Cannot find class [org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping] for bean with name 'org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping#0' defined in ServletContext resource [/WEB-INF/spring-web-servlet.xml]; nested exception is java.lang.ClassNotFoundException: org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping Related cause: org.springframework.beans.factory.CannotLoadBeanClassException: Cannot find class [org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping] for bean with name 'org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping#0' defined in ServletContext resource [/WEB-INF/spring-web-servlet.xml]; nested exception is java.lang.ClassNotFoundException: org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1804) ...(省略重复栈信息)
WEB-INF/lib 依赖列表
classmate-0.8.0.jar aopalliance-1.0.jar commons-collections4-4.0.jar commons-logging-1.1.3-api.jar commons-io-1.2.jar commons-fileupload-1.3.jar commons-dbcp-1.2.2.jar hibernate-validator-5.0.1.Final.jar jersey-client-1.18.5.jar jboss-logging-3.3.1.Final.jar jboss-el-2.0.0.GA.jar jstl-1.2.jar jira-rest-java-client-core-3.0.0.jar servlet-api-2.5.jar validation-api-1.1.0.Final.jar stringtemplate-3.2.jar sqlite-jdbc-3.8.11.2.jar spring-core-5.3.32.jar spring-web-5.3.32.jar spring-webmvc-5.3.32.jar spring-security-web-5.3.2.RELEASE.jar spring-security-taglibs-5.3.3.RELEASE.jar spring-security-core-5.3.3.RELEASE.jar spring-jdbc-5.3.32.jar spring-expression-5.3.32.jar spring-beans-5.3.32.jar spring-aop-5.3.32.jar spring-context-5.3.32.jar spring-security-config-5.3.13.RELEASE.jar spring-tx-5.3.32.jar
spring-config.xml 配置内容
<beans:beans xmlns="http://www.springframework.org/schema/security" xmlns:beans="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd"> <http security="none" pattern="/triagefileupload" /> <http security="none" pattern="loadtriageupload" /> <http auto-config="true" use-expressions="true"> <intercept-url pattern="/load**" access="hasRole('ROLE_USER')" /> <intercept-url pattern="/logout" access="permitAll" /> <intercept-url pattern="/login" access="permitAll" /> <access-denied-handler error-page="/accessdenied" /> <form-login login-page="/login" default-target-url="/loadmenu" authentication-failure-url="/login" login-processing-url="/j_spring_security_check" username-parameter="username" password-parameter="password" /> <logout logout-url="/logout" invalidate-session="true" delete-cookies="JSESSIONID" logout-success-url="/login" /> <csrf /> <session-management> <concurrency-control max-sessions="10" error-if-maximum-exceeded="true" expired-url="/login" /> </session-management> </http> <authentication-manager id="authenticationManager"> <authentication-provider> <user-service> <user name="****" password="****" authorities="ROLE_USER,ROLE_ADMIN" /> <user name="****" password="****" authorities="ROLE_USER,ROLE_ADMIN" /> <user name="****" password="****" authorities="ROLE_USER,ROLE_ADMIN" /> </user-service> </authentication-provider> </authentication-manager> </beans:beans>
解决方案
问题根源
org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping在Spring 3.1后标记为过时,Spring 5.x直接移除了该类,替换Spring版本后自然找不到这个类。
无需修改Java代码的处理步骤
- 打开项目中的
/WEB-INF/spring-web-servlet.xml(错误日志明确指出该文件定义了缺失类的bean) - 找到类似如下的bean定义:
<bean class="org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping" />
- 二选一处理:
- 替换为兼容类:将上述bean替换为Spring 5.x默认使用的处理器映射器:
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping" /> - 直接删除:如果项目没有特殊定制逻辑,Spring MVC会自动注册默认的
RequestMappingHandlerMapping,删除该bean定义不影响原有功能。
- 替换为兼容类:将上述bean替换为Spring 5.x默认使用的处理器映射器:
额外兼容建议
- 统一Spring Security版本:当前Spring核心为5.3.32,但Spring Security依赖版本分散(5.3.2/5.3.3/5.3.13),建议全部升级到5.3.32版本,避免潜在的版本兼容问题。
- 检查Servlet API与Tomcat版本:Spring 5.3.x要求Servlet API最低为3.0,当前依赖
servlet-api-2.5.jar,若Tomcat版本低于7.0,需升级Tomcat到7.0及以上,否则可能触发其他兼容异常。
内容的提问来源于stack exchange,提问作者Arun Praveen
相关产品推荐
相关产品推荐

