开发喵星球

若依升级springboot到最新版本3.x(243)

需求提出:

将若依框架升级到 Spring Boot 3.x 版本。Spring Boot 3.x 要求使用 Java 17 或更高版本,所以需要确保项目使用的 Java 版本符合要求。

解决思路:

所需技术:

项目结构:

com.ruoyi
├── ruoyi-admin
├── ruoyi-common
└── ruoyi-framework

代码实现:

1. 修改 pom.xml 文件

<!-- java.version版本8更换为17 -->
<java.version>17</java.version>

<!-- 新增mybatis节点,版本为3.0.2 -->
<mybatis-spring-boot.version>3.0.2</mybatis-spring-boot.version>

<!-- spring-boot版本2.5.15更换为3.1.5 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-dependencies</artifactId>
    <version>3.1.5</version>
    <type>pom</type>
    <scope>import</scope>
</dependency>

<!-- 新增四个配置依赖 -->
<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>${mybatis-spring-boot.version}</version>
</dependency>

<dependency>
    <groupId>com.mysql</groupId>
    <artifactId>mysql-connector-j</artifactId>
    <version>8.1.0</version>
</dependency>

<dependency>
    <groupId>javax.xml.bind</groupId>
    <artifactId>jaxb-api</artifactId>
    <version>2.3.1</version>
</dependency>

<dependency>
    <groupId>jakarta.servlet</groupId>
    <artifactId>jakarta.servlet-api</artifactId>
    <version>6.0.0</version>
</dependency>

第二步: 修改 ruoyi-admin/pom.xml 文件 MySQL 依赖

<!-- Mysql驱动包 -->
<dependency>
    <groupId>com.mysql</groupId>
    <artifactId>mysql-connector-j</artifactId>
</dependency>

第三步: 修改 ruoyi-framework/pom.xml 文件 kaptcha 依赖

<!-- 验证码 -->
<dependency>
    <groupId>pro.fessional</groupId>
    <artifactId>kaptcha</artifactId>
    <exclusions>
        <exclusion>
            <artifactId>servlet-api</artifactId>
            <groupId>jakarta.servlet</groupId>
        </exclusion>
    </exclusions>
</dependency>

第四步: 修改 ruoyi-common/pom.xml 文件 servlet 依赖为 jakarta

<!-- servlet包 -->
<dependency>
    <groupId>jakarta.servlet</groupId>
    <artifactId>jakarta.servlet-api</artifactId>
</dependency>

第五步: 处理 Java EE 转 Jakarta EE 的变更

javax.xxxx 替换为 jakarta.xxxx,例如:

第六步: 修改 DruidConfig.java

package com.ruoyi.framework.config;

public class DruidConfig
{
    .......

    @Bean
    public DruidStatProperties druidStatProperties()
    {
        return new DruidStatProperties();
    }

    .......
}

第七步: 修改 PermitAllUrlProperties.java

package com.ruoyi.framework.config.properties;

@Configuration
public class PermitAllUrlProperties implements InitializingBean, ApplicationContextAware
{
    .........

    @Override
    public void afterPropertiesSet()
    {
        RequestMappingHandlerMapping mapping = applicationContext.getBean(RequestMappingHandlerMapping.class);
        Map<RequestMappingInfo, HandlerMethod> map = mapping.getHandlerMethods();

        map.keySet().forEach(info -> {
            HandlerMethod handlerMethod = map.get(info);

            // 获取方法上边的注解 替代path variable 为 *
            Anonymous method = AnnotationUtils.findAnnotation(handlerMethod.getMethod(), Anonymous.class);
            Optional.ofNullable(method).ifPresent(anonymous -> Objects.requireNonNull(info.getPathPatternsCondition().getPatternValues()) //
                    .forEach(url -> urls.add(RegExUtils.replaceAll(url, PATTERN, ASTERISK))));

            // 获取类上边的注解, 替代path variable 为 *
            Anonymous controller = AnnotationUtils.findAnnotation(handlerMethod.getBeanType(), Anonymous.class);
            Optional.ofNullable(controller).ifPresent(anonymous -> Objects.requireNonNull(info.getPathPatternsCondition().getPatternValues())
                    .forEach(url -> urls.add(RegExUtils.replaceAll(url, PATTERN, ASTERISK))));
        });
    }

    .........
}

第八步: 修改 SecurityConfig.java

package com.ruoyi.framework.config;

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.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;
import com.ruoyi.framework.config.properties.PermitAllUrlProperties;
import com.ruoyi.framework.security.filter.JwtAuthenticationTokenFilter;
import com.ruoyi.framework.security.handle.AuthenticationEntryPointImpl;
import com.ruoyi.framework.security.handle.LogoutSuccessHandlerImpl;

@EnableMethodSecurity(prePostEnabled = true, securedEnabled = true)
@Configuration
public class SecurityConfig
{
    // 省略部分代码

    @Bean
    SecurityFilterChain filterChain(HttpSecurity httpSecurity) throws Exception
    {
        return httpSecurity
                // CSRF禁用,因为不使用session
                .csrf(csrf -> csrf.disable())
                // 禁用HTTP响应标头
                .headers(headersCustomizer -> headersCustomizer.cacheControl().disable())
                // 认证失败处理类
                .exceptionHandling(exception -> exception.authenticationEntryPoint(unauthorizedHandler))
                // 基于token,所以不需要session
                .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
                .headers(headers -> headers.cacheControl().disable())
                // 注解标记允许匿名访问的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", "/profile/**").permitAll()
                            .requestMatchers("/swagger-ui.html", "/swagger-resources/**", "/webjars/**", "/*/api-docs", "/*/api-docs/**", "/druid/**").permitAll()
                            // 除上面外的所有请求全部需要鉴权认证
                            .anyRequest().authenticated();
                })
                // 添加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();
    }
}

第九步: 修改 application.yml 的 spring.redis 配置为 spring.data.redis

spring:
  data:
    redis:
      # Redis数据库索引(默认为0)
      database: 0
      # Redis服务器地址
      host: localhost
      # Redis服务器连接端口
      port: 6379
      # Redis服务器连接密码(默认为空)
      password:
      # 连接池最大连接数(使用负值表示没有限制)
      lettuce:
        pool:
          max-active: 200
          max-wait: -1
          max-idle: 10
          min-idle: 0
      # 连接超时时间(毫秒)
      timeout: 1000
   
分类:Java/OOP 作者:无限繁荣, 吴蓉 发表于:2024-06-19 15:06:54 阅读量:404
<<   >>


powered by kaifamiao