现在AI越来越火,大多数项目迟早要用上SpringAI啦,而SpringBoot3才支持SpringAI,所以需要对项目进行升级
修改pom依赖 修改父pom依赖 我们需要到若依父项目的pom.xml文件(就是在项目结构最外面的那个xml文件)中修改一下依赖, 下图是我的项目的pom.xml文件(未经修改) 修改后如下图,主要修改了<java.version>、<spring-boot.version>、<tomcat.version>、<logback.version>、<spring-security.version>和<spring-framework.version>,请注意如果你也是升级到SpringBoot3.2.5,可以的话最好就按照我这里的版本来,因为SpringBoot3.2.5是要求对应的tomcat、logback、spring-security、spring-framework版本的: 在pom中新增以下四个依赖配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 <!-- 新增四个配置依赖 --> <!-- Jaxb --> <dependency> <groupId>javax.xml.bind</groupId> <artifactId>jaxb-api</artifactId> <version>2.3.1</version> </dependency> <!-- servlet --> <dependency> <groupId>jakarta.servlet</groupId> <artifactId>jakarta.servlet-api</artifactId> <version>6.0.0</version> </dependency> <!-- mybatis-plus --> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.5.5</version> </dependency> <!-- mysql --> <dependency> <groupId>com.mysql</groupId> <artifactId>mysql-connector-j</artifactId> <version>8.1.0</version> </dependency>
修改admin的pom依赖 修改其mysql驱动包:
1 2 3 4 5 <!-- Mysql驱动包 --> <dependency> <groupId>com.mysql</groupId> <artifactId>mysql-connector-j</artifactId> </dependency>
修改common的pom依赖 修改其servlet包,并添加mybatis-plus和mybatis-spring依赖:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 <!-- 修改 servlet包 --> <dependency> <groupId>jakarta.servlet</groupId> <artifactId>jakarta.servlet-api</artifactId> </dependency> <!-- 添加 mybatis-plus --> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> </dependency> <!-- 添加 mybatis-spring --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>3.0.3</version> </dependency>
修改framework的pom依赖 修改其验证码:
1 2 3 4 5 6 7 8 9 10 11 <!-- 修改 验证码 --> <dependency> <groupId>pro.fessional</groupId> <artifactId>kaptcha</artifactId> <exclusions> <exclusion> <artifactId>servlet-api</artifactId> <groupId>jakarta.servlet</groupId> </exclusion> </exclusions> </dependency>
修改所有pom包内的druid-spring-boot-starter 将所有pom内的druid-spring-boot-starter,修改为druid-spring-boot-3-starter
修改类 DruidConfig类 将类内的
1 2 import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder; import com.alibaba.druid.spring.boot.autoconfigure.properties.DruidStatProperties;
修改为:(就是在boot后面加了个3)
1 2 import com.alibaba.druid.spring.boot3.autoconfigure.DruidDataSourceBuilder; import com.alibaba.druid.spring.boot3.autoconfigure.properties.DruidStatProperties;
SecurityConfig类 由于版本变化,SecurityConfig类的写法也发生了变化,变化后的整个类为:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 package com.ruoyi.framework.config; import com.ruoyi.framework.security.filter.JwtAuthenticationTokenFilter; import com.ruoyi.framework.security.handle.AuthenticationEntryPointImpl; import com.ruoyi.framework.security.handle.LogoutSuccessHandlerImpl; 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.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration; import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity; import org.springframework.security.config.annotation.web.builders.HttpSecurity; 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.web.filter.CorsFilter; /** * spring security配置 * * @author ruoyi */ @EnableMethodSecurity(securedEnabled = true, jsr250Enabled = true) @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; @Bean public AuthenticationManager authenticationManager(AuthenticationConfiguration authenticationConfiguration) throws Exception { return authenticationConfiguration.getAuthenticationManager(); } @Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { http // 使用Lambda DSL重构配置链 .csrf(csrf -> csrf.disable()) // 禁用CSRF[2,5](@ref) .headers(headers -> headers .cacheControl(cache -> cache.disable()) // 禁用缓存控制头 .frameOptions(frame -> frame.disable()) // 禁用X-Frame-Options ) .exceptionHandling(exceptions -> exceptions .authenticationEntryPoint(unauthorizedHandler) // 认证失败处理器[2](@ref) ) .sessionManagement(session -> session .sessionCreationPolicy(SessionCreationPolicy.STATELESS) // 无状态会话[2,4](@ref) ) .authorizeHttpRequests(auth -> auth // 新版授权配置方式[2,3](@ref) // 开放端点配置 .requestMatchers( "/login", "/register", "/captchaImage" ).permitAll() // 静态资源访问 .requestMatchers( HttpMethod.GET, "/", "/*.html", "/*/*.html", "/*/*.css", "/*/*.js", "/profile/*" ).permitAll() // 开放Swagger和Druid端点 .requestMatchers( "/swagger-ui.html", "/swagger-resources/*", "/webjars/*", "/*/api-docs", "/druid/*" ).permitAll() // 其他请求需要认证 .anyRequest().authenticated() ) // 登出配置 .logout(logout -> logout .logoutUrl("/logout") .logoutSuccessHandler(logoutSuccessHandler) // 登出成功处理器[6,8](@ref) ) // 过滤器配置 .addFilterBefore(authenticationTokenFilter, UsernamePasswordAuthenticationFilter.class) // JWT过滤器[6,8](@ref) .addFilterBefore(corsFilter, JwtAuthenticationTokenFilter.class) // CORS过滤器 .addFilterBefore(corsFilter, LogoutFilter.class); return http.build(); } /** * 强散列哈希加密实现 */ @Bean public BCryptPasswordEncoder bCryptPasswordEncoder() { return new BCryptPasswordEncoder(); } /** * 身份认证接口 */ protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.userDetailsService(userDetailsService).passwordEncoder(bCryptPasswordEncoder()); } }
Java EE转Jakarta EE 如果你的IDEA是2022.3以上的版本,可以使用IDEA来进行转换
而如果你的IDEA版本是2022.2以下的版本,那么你需要手动进行转换。 比如把import javax.annotation 替换成 import jakarta.annotation:
1 2 3 4 javax.annotation 替换成 jakarta.annotation javax.servlet 替换成 jakarta.servlet javax.validation 替换成 jakarta.validation javax.xxxxxxxxxx 替换成 jakarta.xxxxxxxxxx
但是,以下包不用转:
1 2 3 4 5 6 7 8 javax.imageio.ImageIO; javax.net.ssl.HostnameVerifier; javax.net.ssl.HttpsURLConnection; javax.net.ssl.SSLContext; javax.net.ssl.SSLSession; javax.net.ssl.TrustManager; javax.net.ssl.X509TrustManager; javax.sql.DataSource
yml文件内redis配置 修改application.yml的spring.redis配置为spring.data.redis
1 2 3 4 spring: data: redis: ......
其他问题 这是因为使用了@PathVariable接收参数的接口,导致报错 解决办法:指定接收参数名,如@PathVariable(“dictType”)或者@PathVariable(name = “dictType”)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 // 调用这个接口会报错 @GetMapping(value = "/type/{dictType}") public AjaxResult dictType(@PathVariable String dictType) { List<SysDictData> data = dictTypeService.selectDictDataByType(dictType); if (StringUtils.isNull(data)) { data = new ArrayList<SysDictData>(); } return success(data); } // 修改之后 @GetMapping(value = "/type/{dictType}") public AjaxResult dictType(@PathVariable("dictType") String dictType) { List<SysDictData> data = dictTypeService.selectDictDataByType(dictType); if (StringUtils.isNull(data)) { data = new ArrayList<SysDictData>(); } return success(data); }
报错No static resource api/option/batchEditScore Spring Boot 3.x 对 URL 路径匹配规则更加严格,请检查对应的接口的路径 以下是我报错时的代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 前端代码: export function batchEditScore(optionIds) { return request({ url: '/api/option/batchEditScore/', method: 'post', data: optionIds }) } 后端对应接口: /** * 完成一次投票后批量修改选项分数,并批量插入投票记录 */ @PostMapping("/api/option/batchEditScore") public AjaxResult batchEditScore(@RequestBody List<Integer> selectedCardsIds, HttpServletRequest request) { ........ return success(); }
因为前端代码路径里多了一个/,所以报错了,由此可见Spring Boot 3.x 对 URL 路径匹配规则更加严格了,去掉后即可解决:
1 2 3 4 5 6 7 8 前端代码: export function batchEditScore(optionIds) { return request({ url: '/api/option/batchEditScore', method: 'post', data: optionIds }) }