-
情况一:spring-boot-starter
-
公共部分
Jackson | 2.12.0 | 2.18.2 |
mybatisplus | 3.3.1 | 3.5.9 |
mybatis-plus-boot-starter | mybatis-plus-spring-boot3-starter | |
log4j | 2.16.0 | 2.24.3 |
gson | 2.8.9 | 2.11.0 |
fastjson | 1.2.78 | 2.0.48 |
maven-compiler-plugin | 3.8.1及以下 | 3.11.0 |
spring-boot-maven-plugin | 2.5.15 | 3.2.0 |
1.1 找不到符号PaginationInterceptor
修改部分:分页插件平替
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
// 添加分页插件(如果有多个DB类型这里可以不指定)
PaginationInnerInterceptor paginationInnerInterceptor = new PaginationInnerInterceptor(DbType.ORACLE);
// 默认优化不需要开启
interceptor.addInnerInterceptor(paginationInnerInterceptor);
// 添加乐观锁插件
interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
return interceptor;
}
1.2 找不到符号getOrders()
修改部分:
page.getOrders()->page.orders()
1.3 MybatisPlusException: @TableId can't more than one in Class:
修改部分:
@TableId("REF_ID")->@TableField("REF_ID")
1.4 javax.validation.ValidationException: Unable to create a Configuration, because no Bean Validation provider could be found
文件位置:
pom.xml
修改部分:
添加依赖
<!--ValidationException解决报错--> <dependency> <groupId>org.apache.bval</groupId> <artifactId>bval-jsr303</artifactId> <version>0.5</version> </dependency> |
1.5 测试类修改
修改范围:所有业务下测试类
修改内容:
import org.junit.Test | import org.junit.jupiter.api.Test |
@RunWith(SpringJUnit4ClassRunner.class) @EnableAutoConfiguration(exclude = { DataSourceAutoConfiguration.class }) | @ComponentScan(excludeFilters = @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE,classes = DataSourceAutoConfiguration.class)) |
@Before | @BeforeEach |
-
业务部分
- java部分
1.1 java: 不兼容的类型: jakarta.servlet无法转换为javax.servle
修改部分:
①将javax.servlet.*替换为jakarta.servlet.*
②注释未使用引入
1.2 找不到符号.Base64Utils
修改部分:
①将Base64Utils.*替换为Base64.*
原代码 | 替换代码 |
Base64Utils.decodeFromString(*) | Base64.getDecoder().decode(*) |
②注释未使用引入
1.3 找不到符号.JSON
修改部分:
①将com.alibaba.fastjson.*替换为com.alibaba.fastjson2.*
1.4 java: 不兼容的类型: java.lang.Long无法转换为int
各业务模块改动
示例:
1.5 The dependencies of some of the beans in the application context form a cycle:
循环依赖问题:配置类加参数
spring main: #将循环依赖的方式打开 allow-circular-references: true |
1.6 启动报错反射异常
添加启动参数:--add-opens java.base/java.util=ALL-UNNAMED
参数允许你指定模块和包,让它们对指定的模块或所有模块开放,以便通过反射进行访问。
1.7 手動替換javax.annotation->jakarta.annotation
javax.validation->jakarta.validation
1.8 java.lang.UnsupportedOperationException: null
具体信息:at java.base/java.lang.Thread.stop(Thread.java:1667)
解决方案:因为stop方法已被启用,改用interrupt
// 使用 interrupt 方法来停止线程 daemonTread.interrupt(); try { // 等待线程安全退出,避免立即消亡 daemonTread.join(1000); // 等待1秒让线程完成清理工作 } catch (InterruptedException e) { Thread.currentThread().interrupt(); // 重新设置中断标志 } |
1.9 java.lang.ClassCastException:
具体信息: class org.springframework.scheduling.config.Task$OutcomeTrackingRunnable cannot be cast to class com.ylink.hwss.timmer.common.run.SchedulingRunnable (org.springframework.scheduling.config.Task$OutcomeTrackingRunnable and com.ylink.hwss.timmer.common.run.SchedulingRunnable are in unnamed module of loader 'app')
解决方案:Springboot3中cronTask.getRunnable()改为了OutcomeTrackingRunnable。所以不能直接强制转换,通过反射获取,代码如下
// 获取 taskRunnable 的内部委托字段 Runnable taskRunnable = cronTask.getRunnable(); Field delegateField = taskRunnable.getClass().getDeclaredField("runnable"); delegateField.setAccessible(true); // 获取委托对象并检查是否是 SchedulingRunnable Runnable delegate = (Runnable) delegateField.get(taskRunnable); if (delegate instanceof SchedulingRunnable) { SchedulingRunnable newTask = (SchedulingRunnable) delegate; } |
1.10 java.lang.InterruptedException: sleep interrupted
解决方案:加trycatch
情况二:spring-boot-dependencies
pom文件修改
名称 | 当前版本 | 升级版本 | 备注(默认版本号) |
java | 1.8 | 21 | |
spring-boot | 2.5.15 | 3.4.1 | |
maven-compiler | 3.1 | 3.13.0 | 不修改也行 |
maven-jar-plugin | 3.1.1 | 3.4.2 | 不修改也行 |
mysql-connector-java | 废弃 | ||
mysql-connector-j | 9.1.0 | 代替上面的mysql | |
jaxb-api | 2.3.1 | 需显示指定版本号 | |
java.servlet-api | | 棄用,替換為 tomcat-embed-core | |
tomcat-embed-core | 10.1.34 | 在父工程中顯示聲明,解決找不到servlet | |
httpclient | 4.5.13 | 需显示指定版本号 | |
<fork> | 注释掉,已弃用 | ||
mybatis-plus-jsqlparser | 3.5.9 | 新增 |
1.1 未显示指定版本号,执行maven的clear操作会导致报错图如下
java文件修改
1.1 java: 程序包javax.*不存在
将所有的javax.*改为jakarta.*
举例
javax.annotation 替换成 jakarta.annotation
javax.servlet 替换成 jakarta.servlet
javax.validation 替换成 jakarta.validation
javax.mail 替换成 jakarta.mail
javax.jms 替換 jakarta.jms
javax.xxxxxxxxxx 替换成 jakarta.xxxxxxxxxx
不需要改的
import javax.imageio.ImageIO;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import javax.sql.DataSource
1.2 找不到jakarta.servlet
父工程顯示聲明,子模塊引用
1.3 java: 找不到符号 类 WebSecurityConfigurerAdapter
package com.ylink.hwss.framework.config;
import com.ylink.hwss.framework.config.properties.PermitAllUrlProperties;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.ProviderManager;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
//import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer;
import org.springframework.security.config.annotation.web.configurers.HeadersConfigurer;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.authentication.logout.LogoutFilter;
import org.springframework.security.web.firewall.HttpFirewall;
import org.springframework.security.web.firewall.StrictHttpFirewall;
import org.springframework.web.filter.CorsFilter;
import com.ylink.hwss.framework.security.filter.JwtAuthenticationTokenFilter;
import com.ylink.hwss.framework.security.handle.AuthenticationEntryPointImpl;
import com.ylink.hwss.framework.security.handle.LogoutSuccessHandlerImpl;
/**
* spring security配置
*
* @author ruoyi
*/
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
//public class SecurityConfig extends WebSecurityConfigurerAdapter
@Configuration
public class SecurityConfig
{
/**
* 自定义用户认证逻辑
*/
@Autowired
private UserDetailsService userDetailsService;
/**
* 认证失败处理类
*/
@Autowired
private AuthenticationEntryPointImpl unauthorizedHandler;
/**
* 退出处理类
*/
@Autowired
private LogoutSuccessHandlerImpl logoutSuccessHandler;
/**
* token认证过滤器
*/
@Autowired
private JwtAuthenticationTokenFilter authenticationTokenFilter;
/**
* 跨域过滤器
*/
@Autowired
private CorsFilter corsFilter;
/**
* 允许匿名访问的地址
*/
@Autowired
private PermitAllUrlProperties permitAllUrl;
/**
* 解决 无法直接注入 AuthenticationManager
*
* @return
* @throws Exception
*/
@Bean
AuthenticationManager authenticationManager()
{
DaoAuthenticationProvider daoAuthenticationProvider = new DaoAuthenticationProvider();
// 身份认证接口
daoAuthenticationProvider.setUserDetailsService(userDetailsService);
daoAuthenticationProvider.setPasswordEncoder(bCryptPasswordEncoder());
return new ProviderManager(daoAuthenticationProvider);
}
/**
* anyRequest | 匹配所有请求路径
* access | SpringEl表达式结果为true时可以访问
* anonymous | 匿名可以访问
* denyAll | 用户不能访问
* fullyAuthenticated | 用户完全认证可以访问(非remember-me下自动登录)
* hasAnyAuthority | 如果有参数,参数表示权限,则其中任何一个权限可以访问
* hasAnyRole | 如果有参数,参数表示角色,则其中任何一个角色可以访问
* hasAuthority | 如果有参数,参数表示权限,则其权限可以访问
* hasIpAddress | 如果有参数,参数表示IP地址,如果用户IP和参数匹配,则可以访问
* hasRole | 如果有参数,参数表示角色,则其角色可以访问
* permitAll | 用户可以任意访问
* rememberMe | 允许通过remember-me登录的用户访问
* authenticated | 用户登录后可访问
*/
@Bean
SecurityFilterChain filterChain(HttpSecurity httpSecurity) throws Exception {
return httpSecurity
// CSRF禁用,因为不使用session
.csrf(AbstractHttpConfigurer::disable)
// 禁用HTTP响应标头
.headers(header -> header.cacheControl(HeadersConfigurer.CacheControlConfig::disable).frameOptions(HeadersConfigurer.FrameOptionsConfig::disable))
// 认证失败处理类
.exceptionHandling(exception -> exception.authenticationEntryPoint(unauthorizedHandler))
// 基于token,所以不需要session
.sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
// 注解标记允许匿名访问的url
.authorizeHttpRequests((requests) -> {
permitAllUrl.getUrls().forEach(url -> requests.requestMatchers(url).permitAll());
// 对于登录login 注册register 验证码captchaImage 允许匿名访问
requests.requestMatchers("/login", "/register", "/captchaImage").permitAll()
// 静态资源,可匿名访问
.requestMatchers(HttpMethod.GET, "/", "/*.html", "/**/*.html", "/**/*.css", "/**/*.js", "/**/*.map", "/profile/**").permitAll()
.requestMatchers("/swagger-ui.html", "/swagger-resources/**", "/webjars/**", "/*/api-docs", "/*/api-docs/**", "/druid/**").permitAll()
//積木報表
.requestMatchers("/jmreport/**").anonymous()
// 除上面外的所有请求全部需要鉴权认证
.anyRequest().authenticated();
})
//禁用 X-Frame-Options 头,防止点击劫持(Clickjacking)攻击,允许页面被嵌套在框架中
.headers(headers -> headers.frameOptions(HeadersConfigurer.FrameOptionsConfig::disable))
// 添加Logout filter
.logout(logout -> logout.logoutUrl("/logout").logoutSuccessHandler(logoutSuccessHandler))
// 添加JWT filter
.addFilterBefore(authenticationTokenFilter, UsernamePasswordAuthenticationFilter.class)
// 添加CORS filter
.addFilterBefore(corsFilter, JwtAuthenticationTokenFilter.class)
.addFilterBefore(corsFilter, LogoutFilter.class).build();
}
/**
* 强散列哈希加密实现
*/
@Bean
public BCryptPasswordEncoder bCryptPasswordEncoder()
{
return new BCryptPasswordEncoder();
}
/**
* 身份认证接口
*/
protected void configure(AuthenticationManagerBuilder auth) throws Exception
{
auth.userDetailsService(userDetailsService).passwordEncoder(bCryptPasswordEncoder());
}
/**
* 配置地址栏不能识别 特殊字符 的情况
* @return
*/
@Bean
public HttpFirewall allowUrlEncodedSlashHttpFirewall() {
StrictHttpFirewall firewall = new StrictHttpFirewall();
//此处可添加别的规则
firewall.setAllowUrlEncodedDoubleSlash(true);
firewall.setAllowUrlEncodedPercent(true);
return firewall;
}
}
1.4 Invalid bean definition with name 'xxxMapper' defined in file
更新mybatis-plus
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.9</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-jsqlparser</artifactId>
<version>3.5.9</version>
</dependency>
1.5 java: 程序包com.alibaba.druid.spring.boot.autoconfigure不存在
1.6 Parameter 0 of method removeDruidFilterRegistrationBean in com.ylink.hwss.framework.config.DruidConfig required a bean of type 'com.alibaba.druid.spring.boot.autoconfigure.properties.DruidStatProperties' that could not be found.
1.7 Connection refused: getsockopt: localhost/127.0.0.1:6379
升級後,reids在配置文件data下
配置文件同
1.7 Error creating bean with name 'com.github.pagehelper.autoconfigure.PageHelperAutoConfiguration': net/sf/jsqlparser/statement/select/SelectBody
原因是jsqlparser冲突了,分页插件排除依赖
<!-- pagehelper 分页插件 -->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>${pagehelper.boot.version}</version>
<exclusions>
<exclusion>
<groupId>com.github.jsqlparser</groupId>
<artifactId>jsqlparser</artifactId>
</exclusion>
</exclusions>
</dependency>
1.8 java: java.lang.NoSuchFieldError: Class com.sun.tools.javac.tree.JCTree$JCImport does not have member field 'com.sun.tools.javac.tree.JCTree qualid'
build報錯,原因:lombok未显示指定版本,根据Dependency Versions可直接查看对应的版本添加即可
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
</dependency>
1.9 Cannot invoke “org.springframework.web.servlet.mvc.condition.PatternsRequestCondition.getPatterns()“
配置文件添加:更改spring mvc的默认路径匹配规则,默认是正则
spring
mvc:
#Ant风格的路径匹配策略
pathmatch:
matching-strategy: ANT_PATH_MATCHER