由于原部署在阿里云上的基于spring4的springmvc项目,阿里云提示Spring Framework 特定条件下目录遍历漏洞,要求spring的版本不低于spring5.3.39版本,于是将目前项目中的spring4.16版本升级到了spirng5.3.39版本,这也是spring5.0的最高版本了。后面想着既然spring6都已经出来好几年了,干脆一口气把他升级到spring6.0以上版本得了,于是选择了将spring5.3.39版本升级到spring6.1.12版本,这次升级要比spirng4升级到spring5问题多不少,现在把主要遇到的问题记录起来,算是升级的一个总结。
1 第一个问题,由于spring4版本的项目是用的eclipse开发,升级到spring5版本后,想着放个开发环境,于是升级过程是在idea2020版本过程上进行的,一切还算胜利。但在接下来spring5升级到spring6的过程中,由于spring6需要jdk17以及以上版本才支持,于是卸载原来使用了N多年的jdk8,安装上了jdk17,于是出现了第一个问题,idea2020版本不支持jdk17,然后重新下载idea2024版本,问题解决。
2 第二个问题,jdk升级到1.7以后,由于放弃了一些jdk8以下版本的方法,导致项目中部分代码包引用错误,编译不通过,于是找到编译报错的项目类文件,挨个解决。
3 第四个问题,spring5升级到spring6后,Controller层面的代码全面爆红,编译不通过,原因是HttpServletRequest原型来自于javax.servlet.http包,升级到spring6以后,java.servlet被抛弃,继承者是jakarta.servlet,于是修改pom.xml文件,增加如下依赖,这个时候需要修改所以原先引用import javax.servlet.批量更改成为import jakarta.servlet,编译爆红的问题得到解决
<dependency> <groupId>jakarta.servlet</groupId> <artifactId>jakarta.servlet-api</artifactId> <version>6.0.0</version> <scope>provided</scope> </dependency>
修改完后,重新启动服务器,启动过程发现一个奇怪的问题,说是找不到
javax.servlet. ServletRequestListener类,由于web.xml文件中配置的监听器已经使用
jakarta. servlet. ServletRequestListener了,不应该在去找老版本的监听器啊,搞了半天,竟然是idea的问题,在maven中次进行clean,问题就解决了。
4 第三个问题,解决完系统重代码的编译错误后,开始启动tomcat服务器,发现启动的过程中遇到的第一错误,Caused by: java.lang.IllegalArgumentException: 找到多个名为spring_web的片段。这是不合法的相对排序。有关详细信息,请参阅Servlet规范的第8.2.2 2c节。
解决方法,在web.xml文件中增加<absolute-ordering/>
5 在次启动tomcat服务器,还是报错,这次的错误大致是不能加载org.hibernate.dialect.MySQL5InnoDBDialect,原来spring6升级后,hibernate也需要升级到hibernate6,hibernate6不在支持MySQL5InnoDBDialect方言,修改修改为hibernate.dialect=org.hibernate.dialect.MySQL8Dialect,问题得到解决。但是在把hibernate5升级到hibernate6以后,dao层的很多代码开始报错,编译不通过,所先是
import org.hibernate.Query;
不在支持,需要将import org.hibernate.Query修改为import org.hibernate.query.Query;
其次原来的this.getCurrentSession().createSQLQuery(sql)方法需要修改为
this.getCurrentSession().createNativeQuery(sql)方法 然后将import javax.persistence.*;修改为import jakarta.persistence.*;
反正dao层的代码和entity层的包引用需要修改。
6 在修改了上面提到的问题,以及一些没有提到的小问题后,服务器终于起来了,登入系统后,发现后台数据流程从Controller到service在到dao层的数据流转是正常的。但是jsp页面展示数据的时候出错了,打开index.jsp一看,如下两行代码编译不通过,原因是找不到对应的ctl文件。
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> <%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions"%>
解决办法,pom.xml文件中加入如下依赖
<dependency> <groupId>jakarta.servlet.jsp.jstl</groupId> <artifactId>jakarta.servlet.jsp.jstl-api</artifactId> <version>3.0.0</version> </dependency> <dependency> <groupId>org.glassfish.web</groupId> <artifactId>jakarta.servlet.jsp.jstl</artifactId> <version>3.0.1</version> </dependency>
终于登入到了系统首页,但是后面点击相关功能子页面,还是会报错。
7 进入系统首页后,点击相关功能子页面,开始报错,
java.lang.IllegalArgumentException: Name for argument of type [java.lang.String] not specified, and parameter name information not available via reflection. Ensure that the compiler uses the '-parameters' flag.at
解决办法如下
刚开始以为是代码错误,这是因为使用Spring 6.0以上版本的问题,如果不想降版本,在项目pom文件build节点添加如下代码:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>17</source>
<target>17</target>
<encoding>UTF-8</encoding>
<!-- 启用 -parameters 编译器标志 -->
<compilerArgument>-parameters</compilerArgument>
</configuration>
</plugin>
8 上传文件失败
spring6不在支持
org.springframework.web.multipart.commons.CommonsMultipartResolver文件解析类,甚至直接删除掉了commons包,因此需要重新配置文件解析类org.springframework.web.multipart.support.StandardServletMultipartResolver
同时web.xml中添加
<multipart-config> <max-file-size>20480000</max-file-size> <max-request-size>10485760</max-request-size> <file-size-threshold>0</file-size-threshold> </multipart-config>
到此,系统终于能够正常访问。