这篇文章分享一下Spring Boot 升级到2.7的踩坑总结,还是挺全面的,希望对大家有所帮助~

说明

2.7.2为2.x的最后一个稳定版本。

3开始最低要求 Java 17,所以暂时不到3.x。

以下的处理方法主要针对我们的项目,可能并不通用。

1、hibernate-validator包下的类报错

Springboot从2.3以后,spring-boot-starter-web中不再引入hibernate-validator,需要手动引入。

在父pom中引入,已经加入software-center-modules模块中,子模块不需要加:

<dependency><groupId>org.hibernate.validator</groupId><artifactId>hibernate-validator</artifactId><version>6.0.18.Final</version><scope>compile</scope>
</dependency>

2、ErrorController无getErrorPath方法

去掉该方法

3、logback和log4j冲突

org.apache.logging.log4j.LoggingException: log4j-slf4j-impl cannot be present with log4j-to-slf4jat org.apache.logging.slf4j.Log4jLoggerFactory.validateContext(Log4jLoggerFactory.java:60)at org.apache.logging.slf4j.Log4jLoggerFactory.newLogger(Log4jLoggerFactory.java:44)at org.apache.logging.slf4j.Log4jLoggerFactory.newLogger(Log4jLoggerFactory.java:33)at org.apache.logging.log4j.spi.AbstractLoggerAdapter.getLogger(AbstractLoggerAdapter.java:53)at org.apache.logging.slf4j.Log4jLoggerFactory.getLogger(Log4jLoggerFactory.java:33)at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:363)at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:388)at com.ld.CreditTaskManageApplication.<clinit>(CreditTaskManageApplication.java:40)... 34 more

排除掉springboot的logging

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-batch</artifactId><exclusions><!-- spring boot 默认的日志框架是Logback,所以在引用log4j之前,需要先排除该包的依赖,再引入log4j2的依赖 --><exclusion><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-logging</artifactId></exclusion></exclusions>
</dependency>

4、循环依赖:The dependencies of some of the beans in the application context form a cycle

[credit-task-manage]2022-08-04 13:54:43.411 [WARN]:Exception encountered during context initialization - cancelling refresh attempt: org.springframework.context.ApplicationContextException: Unable to start web server; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'webMainConfig': Unsatisfied dependency expressed through field 'handlerAdapter'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration$EnableWebMvcConfiguration': Unsatisfied dependency expressed through method 'setConfigurers' parameter 0; nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'webMainConfig': Requested bean is currently in creation: Is there an unresolvable circular reference?   org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:591) The dependencies of some of the beans in the application context form a cycle:┌─────┐
|  webMainConfig (field private org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter com.ld.common.config.WebMainConfig.handlerAdapter)
↑     ↓
|  org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration$EnableWebMvcConfiguration
└─────┘Action:Relying upon circular references is discouraged and they are prohibited by default. Update your application to remove the dependency cycle between beans. As a last resort, it may be possible to break the cycle automatically by setting spring.main.allow-circular-references to true.org.springframework.boot.diagnostics.LoggingFailureAnalysisReporter.report(LoggingFailureAnalysisReporter.java:40)

WebMainConfig类中 去掉报错的方法和属性handlerAdapter,修改写法

@Bean
public ConversionService getConversionService(DateConverter dateConverter) {ConversionServiceFactoryBean factoryBean = new ConversionServiceFactoryBean();Set<Converter<String, Date>> converters = new HashSet<>();converters.add(dateConverter);factoryBean.setConverters(converters);return factoryBean.getObject();
}

日期转换器,依赖hutool的日期工具类处理,如不满足再自行扩展

import java.util.Date;import org.springframework.context.annotation.Configuration;
import org.springframework.core.convert.converter.Converter;import cn.hutool.core.date.DateUtil;/*** @Description 表单形式的全局时间类型转换器*/
@Configuration
public class DateConverter implements Converter<String, Date> {// 可以根据前端传递的时间格式自动匹配格式化@Overridepublic Date convert(String source) {return DateUtil.parse(source);}}

代码中应该尽量避免循环依赖的情况,如果出现了,加@Lazy注解,懒加载。

代码中不鼓励依赖循环引用,默认情况下禁止使用循环引用。如果能消除bean之间的依赖循环最好消除,如果实在改动太大,还有一种不推荐的处理方法,设置 spring.main.allow-circular-references=true

5、swagger错误:Failed to start bean 'documentationPluginsBootstrapper'

Application run failed   org.springframework.boot.SpringApplication.reportFailure(SpringApplication.java:824)
org.springframework.context.ApplicationContextException: Failed to start bean 'documentationPluginsBootstrapper'; nested exception is java.lang.NullPointerExceptionat org.springframework.context.support.DefaultLifecycleProcessor.doStart(DefaultLifecycleProcessor.java:181) ~[spring-context-5.3.22.jar:5.3.22]
复制代码

启动报了“Failed to start bean 'documentationPluginsBootstrapper'”,再往下面看到“springfox.documentation.spring.web.plugins.WebMvcRequestHandlerProvider”就可以断定是跟Swagger相关的问题。

查资料发现是新版本Spring Boot将Spring MVC默认路径匹配策略由AntPathMatcher更改为PathPatternParser,因此我们可以通过配置让其仍使用AntPathMatcher即可。关注公号:码猿技术专栏,回复关键词:1111,获取阿里内部调优手册

解决方案:在application.properties里配置:

# 路径匹配策略使用旧版本的
spring.mvc.pathmatch.matching-strategy= ANT_PATH_MATCHER

顺便升级swagger到swagger3,已经加到base公共包里了

5.1、修改后路径需要修改,默认首页由swagger-ui.html变成了

/swagger-ui/index.html

5.2、如果还想使用扩展的2个ui的版本也需要跟着升级

<swagger-ui-layer.version>1.1.3</swagger-ui-layer.version>
<swagger-bootstrap-ui.version>1.9.6</swagger-bootstrap-ui.version>

我这里直接删除了那2个ui使用了swagger-bootstrap-ui的升级版:knife4j。base模块中已经引入

<knife4j.version>3.0.3</knife4j.version>
……
<dependency><groupId>com.github.xiaoymin</groupId><artifactId>knife4j-spring-boot-starter</artifactId><version>${knife4j.version}</version>
</dependency>

5.3、swagger的配置类,注解@EnableSwagger2去掉,名字改为更通用的SwaggerConfig

@Configuration
//@EnableSwagger2
@Slf4j
public class SwaggerConfig {}

5.4、删除项目中自定义的pringfox.documentation.spring.web.readers包

5.5、去掉自定义的页面,如果想修改找到新的jar包复制出页面进行调整,否则可能看到的页面里没有内容

src/main/resources/META-INF/resources/doc.html

5.6 调整过滤器路径配置

#============================ 安全访问配置(SecurityFilter)========================
# 需要过滤的urlPatterns,多个用^分隔,没有或为空则不限制
security.access.urlPatterns = /doc.html^/docs.html^/swagger-ui.html^/swagger-ui/index.html^/v2/api-docs^/swagger-resources

6、跳转登录页出错

如果出现跳转时出错:

Cannot forward to error page for request [/a/] as the response has already been committed. As a result, the response may have the wrong status code. If your application is running on WebSphere Application Server you may be able to resolve this problem by setting com.ibm.ws.webcontainer.invokeFlushAfterService to false   org.springframework.boot.web.servlet.support.ErrorPageFilter.handleCommittedResponse(ErrorPageFilter.java:219)

解决方案同5

7、日期转换出错

升级后发现java中是Date类型,数据库中datetime类型(Timestamp类型没有问题)的数据不是转换为Timestamp,而是直接转为LocalDateTime类型了,解决办法:com.ld.shieldsb.dao.MyBeanProcessor修改type2Bean方法,增加LocalDateTime和LocalDate的处理

if (value != null && fieldType.equals(Date.class)) {if (value.getClass().equals(String.class)) {SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");try {field.set(model, sdf.parse((String) value));} catch (ParseException e) {log.error("日期字段读取失败," + fieldType + ",error:" + e.getMessage());}} else if (value.getClass().equals(LocalDateTime.class)) {field.set(model, DateTimeUtil.localDateTime2Date((LocalDateTime) value));} else if (value.getClass().equals(LocalDate.class)) {field.set(model, DateTimeUtil.localDate2Date((LocalDate) value));} else {field.set(model, value);}
}

我们使用的是mysql查看依赖jar包看到mysql-connector-java的版本从8.0.19变成了8.0.29

原因找到com.mysql.cj.jdbc.result.ResultSetImpl类的getObject(int columnIndex)方法可以看到Datetime类型的确实换了类型

case DATETIME:return getTimestamp(columnIndex);
// 改为了
case DATETIME:return getLocalDateTime(columnIndex);

8、flyway:org.flywaydb.core.api.FlywayException: Unsupported Database: MySQL 5.7

Application run failed   org.springframework.boot.SpringApplication.reportFailure(SpringApplication.java:824)
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'flywayInitializer' defined in class path resource [org/springframework/boot/autoconfigure/flyway/FlywayAutoConfiguration$FlywayConfiguration.class]: Invocation of init method failed; nested exception is org.flywaydb.core.api.FlywayException: Unsupported Database: MySQL 5.7at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1804) ~[spring-beans-5.3.22.jar:5.3.22]……at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:343) [bootstrap.jar:9.0.31]at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:474) [bootstrap.jar:9.0.31]
Caused by: org.flywaydb.core.api.FlywayException: Unsupported Database: MySQL 5.7at org.flywaydb.core.internal.database.DatabaseTypeRegister.getDatabaseTypeForConnection(DatabaseTypeRegister.java:106) ~[flyway-core-8.5.13.jar:?]……org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1800) ~[spring-beans-5.3.22.jar:5.3.22]... 49 more

flyway对数据库版本有要求,例如flyway-core的当前版本V8.4.3,不能使用 MySQL 5.7, 当flyway-core 降低到V7.15.0后 问题解决,所以匹配flyway-core和数据库版本后问题即可解决。

<properties>
……<flyway.version>7.15.0</flyway.version>
</properties>
……<!-- 添加 flyway 的依赖,flyway需要区分版本,不同版本对不同数据库版本支持不同 --><dependency><groupId>org.flywaydb</groupId><artifactId>flyway-core</artifactId><version>${flyway.version}</version></dependency>
……

9、Junit运行后没有反应

升级后默认使用junit5,而依赖的jar包中引入了junit4的jar包冲突了,去掉junit4的jar包即可。

注意使用junit5后包的名字发生了变化,下面箭头前后分别是junit4和junit5的

org.junit.Test》org.junit.jupiter.api.Test
org.junit.runner.RunWith》org.junit.jupiter.api.extension.ExtendWith
//使用时
@RunWith(SpringRunner.class)》@ExtendWith(SpringExtension.class)

10、升级后json中Long类型字段精度丢失

出现如下情况,前面是真实值后面为json传递后的值

344280995828072448》344280995828072450
344268472663932928》344268472663932900
343301120241696768》343301120241696800

原项目中是有Long转字符串的处理的。

问题原因:经查看,默认已经有多个消息转换器了。而 configureMessageConverters 方法中是一个 list 参数。直接向其中添加 HttpMessageConverter 后,默认是排在最后的。就造成了你自定义的消息转换器不生效。其实是被其他转换器接管了。

解决办法:加到第一个就行了。add(0, customConverter())

    @Overridepublic void configureMessageConverters(List<HttpMessageConverter<?>> converters) {FastJsonHttpMessageConverter fastConverter = new FastJsonHttpMessageConverter();……// 支持text 转stringconverters.add(0, customJackson2HttpMessageConverter());converters.add(0, new StringHttpMessageConverter(StandardCharsets.UTF_8));converters.add(0, fastConverter);}

如果使用的是@bean注解,覆盖的fastjson则不需要改,如下:

@Beanpublic HttpMessageConverters customConverters() {FastJsonHttpMessageConverter fastConverter = new FastJsonHttpMessageConverter();// 创建配置类FastJsonConfig fastJsonConfig = new FastJsonConfig();fastJsonConfig.setSerializerFeatures(SerializerFeature.WriteNullListAsEmpty, SerializerFeature.WriteMapNullValue,SerializerFeature.WriteNullStringAsEmpty);// 解决 Long 转json 精度丢失的问题SerializeConfig serializeConfig = SerializeConfig.globalInstance;serializeConfig.put(BigInteger.class, ToStringSerializer.instance);serializeConfig.put(Long.class, ToStringSerializer.instance);serializeConfig.put(Long.TYPE, ToStringSerializer.instance);fastJsonConfig.setSerializeConfig(serializeConfig);// 此处是全局处理方式fastJsonConfig.setDateFormat(DATE_FORMAT);fastJsonConfig.setCharset(StandardCharsets.UTF_8);fastConverter.setFastJsonConfig(fastJsonConfig);List<MediaType> supportedMediaTypes = new ArrayList<>();supportedMediaTypes.add(MediaType.APPLICATION_JSON);fastConverter.setSupportedMediaTypes(supportedMediaTypes);// 支持text 转stringStringHttpMessageConverter stringHttpMessageConverter = new StringHttpMessageConverter();return new HttpMessageConverters(fastConverter, stringHttpMessageConverter);}

麻了!Spring Boot 从 2.2.5 升级到 2.7.2 之后,一堆BUG相关推荐

  1. 001-Spring Cloud Edgware.SR3 升级最新 Finchley.SR1,spring boot 1.5.9.RELEASE 升级2.0.4.RELEASE注意问题点...

    一.前提 升级前 => 升级后 Spring Boot 1.5.x => Spring Boot 2.0.4.RELEASE Spring Cloud Edgware SR3 => ...

  2. Spring Boot 2.3.5.RELEASE正式升级,SpringBoot新版本发布

    版本升级 spring boot 正式版本于今日升级到2.3.5.Release. 应用案例 微服务:https://github.com/matevip/matecloud SpringBoot也同 ...

  3. Spring Boot 2.0正式发布,升还是不升呢?

    Spring帝国 Spring几乎是每一位Java开发人员都耳熟能详的开发框架,不论您是一名初出茅庐的程序员还是经验丰富的老司机,都会对其有一定的了解或使用经验.在现代企业级应用架构中,Spring技 ...

  4. Spring Boot 中文参考指南

    Spring Boot 版本 2.7.8 原文:https://docs.spring.io/spring-boot/docs/2.7.8/reference/htmlsingle/ - 笔者注: S ...

  5. 54. spring boot日志升级篇—logback【从零开始学Spring Boot】

    在<44. Spring Boot日志记录SLF4J>章节中有关相关的介绍,这里我们在深入的了解下logback框架. 为什么要使用logback ? --在开发中不建议使用System. ...

  6. Spring Boot发布2.6.2、2.5.8:升级log4j2到2.17.0

    12月22日,Spring官方发布了Spring Boot 2.5.8(包括46个错误修复.文档改进和依赖项升级)和2.6.2(包括55个错误修复.文档改进和依赖项升级). 这两个版本均为缺陷修复版本 ...

  7. Spring boot升级到2.3.2.Release和Spring framework升级到5.28.Release踩过的坑

    目录 1. 利用下面方法启动spring boot 项目是系统参数不生效 2. org.drools.template.parser.DecisionTableParseException: Fail ...

  8. Spring boot admin 升级到2.3.1 遇到的问题总结

    目录 问题1 :注册到Spring boot admin 服务器上的项目,在项目关闭或者重启的时候不会自动注销. 问题2 :如果spring boot admin server 已经是spring w ...

  9. Spring Boot 从1.0 升级到 2.0 所踩的坑

    先给大家晒一下云收藏的几个数据,作为一个 Spring Boot 的开源项目(https://github.com/cloudfavorites/favorites-web)目前在 Github 上面 ...

最新文章

  1. Ubuntu 16.04 LTS, 64bit,cuda 8, Caffe环境配置编译和安装
  2. C++ Primer 5th笔记(chap 16 模板和泛型编程)模板类型别名
  3. kaggle notebook在git push时附带用户民和密码(一行搞定,全部写在一行中)
  4. 倒计时 时间校准android,android倒计时器时间
  5. Python实现单向链表
  6. C#输出带有换行符的字符串
  7. jQuery源码分析 整体框架部分及部分常用方法
  8. 怎么样才显示暗=安装好了mysql_linux mysql安装
  9. 独家插件!非常好用的CASS地形图绘制插件
  10. 概率论和数理统计知识点汇总
  11. 3.46 OrCAD软件怎么输出物料清单BOM表格?
  12. 【26】Superscalar和VLIW:如何让CPU的吞吐率超过1?
  13. vue插槽,内容分发
  14. c语言定义未知长度一维数组,c++ 如何定义未知元素个数的数组
  15. 3D打印机故障问题与解决总集
  16. 主流报表开发工具FastReport.Net全新发布,邀您体验最新版试用
  17. 效果超好的自制美白面膜大汇总 - 健康程序员,至尚生活!
  18. 添加/删除windows组件中没有IIS选项 怎么办
  19. 【shell】Linux Shell远程执行命令
  20. Gitee第三方登录

热门文章

  1. TIS107桥错误报告——笔记
  2. 第一篇:0到9的数字游戏的介绍与性质
  3. 基于瞬态自适应的麻雀搜索算法
  4. nodejs+Vue网上图书购物销售_旧书回收系统
  5. 几行代码,就可以让系统自动按Enter键,帮了大忙
  6. 从“四跨”测试看车联网产业现状和趋势
  7. js中some和every用法
  8. 介绍一个优质的学习分类网站-学吧导航
  9. 数据库 E-R图实例
  10. MDX语句(初学者)