• springboot 项目升级 2.7.16 踩坑


    记录一下项目更新版本依赖踩坑

    这个是项目最早的版本依赖
    在这里插入图片描述

    这里最初是最初是升级到 2.5.7 偷了个懒 这个版本的兼容性比较强 就选了这版本 也不用去修改就手动的去换了一下RabbitMQ的依赖 因为这边项目有AMQP 风险预警
    1.spring-amqp版本低于2.4.17的用户应升级到2.4.17
    2.spring-amqp是3.0.0至3.0.9版本的用户应升级至3.0.10

    之前用的是starter 依赖

        <dependency>
             <groupId>org.springframework.bootgroupId>
             <artifactId>spring-boot-starter-amqpartifactId>
             <version>3.0.10version>
        dependency>        
    
    • 1
    • 2
    • 3
    • 4
    • 5

    然后打包后发现并没有什么用 版本依旧是跟着springboot走的 就手动换成了单个依赖

    单个依赖

        <properties>
            <spring-amqp.version>2.4.17spring-amqp.version>
            <spring-rabbit.version>2.4.17spring-rabbit.version>
        properties>
        
        <dependencyManagement>
              <dependencies>
                
                <dependency>
                    <groupId>org.springframework.amqpgroupId>
                    <artifactId>spring-amqpartifactId>
                    <version>${spring-amqp.version}version>
                dependency>
                <dependency>
                    <groupId>org.springframework.amqpgroupId>
                    <artifactId>spring-rabbitartifactId>
                    <version>${spring-rabbit.version}version>
                dependency>
    
            dependencies>
        dependencyManagement>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    就在我也觉得没啥问题的时候 发现 swagger 在线下运行是正常的 到线上就显示不出来 一开始是以为升级版本后跨域的影响 毕竟后台管理明显提示是有跨域 好嘛 那就改跨域
    这里 着重就是改了一个 addAllowedOriginPattern

    修改前

    @Configuration
    public class WebMvcConfiguration implements WebMvcConfigurer {
       @Bean
        public CorsFilter corsFilter() {
            final UrlBasedCorsConfigurationSource urlBasedCorsConfigurationSource = new UrlBasedCorsConfigurationSource();
            final CorsConfiguration corsConfiguration = new CorsConfiguration();
            /* 是否允许请求带有验证信息 */
            corsConfiguration.setAllowCredentials(true);
            /* 允许访问的客户端域名 */
            corsConfiguration.addAllowedOrigin("*");
            /* 允许服务端访问的客户端请求头 */
            corsConfiguration.addAllowedHeader("*");
            /* 允许访问的方法名,GET POST等 */
            corsConfiguration.addAllowedMethod("*");
            urlBasedCorsConfigurationSource.registerCorsConfiguration("/**", corsConfiguration);
            return new CorsFilter(urlBasedCorsConfigurationSource);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    修改后

    @Configuration
    public class WebMvcConfiguration implements WebMvcConfigurer {
       @Bean
        public CorsFilter corsFilter() {
            final UrlBasedCorsConfigurationSource urlBasedCorsConfigurationSource = new UrlBasedCorsConfigurationSource();
            final CorsConfiguration corsConfiguration = new CorsConfiguration();
            /* 是否允许请求带有验证信息 */
            corsConfiguration.setAllowCredentials(true);
            /* 允许访问的客户端域名 */
            corsConfiguration.addAllowedOriginPattern("*");
            /* 允许服务端访问的客户端请求头 */
            corsConfiguration.addAllowedHeader("*");
            /* 允许访问的方法名,GET POST等 */
            corsConfiguration.addAllowedMethod("*");
            urlBasedCorsConfigurationSource.registerCorsConfiguration("/**", corsConfiguration);
            return new CorsFilter(urlBasedCorsConfigurationSource);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    心想这下总该好了吧 结果一上线又是swagger访问不到 甚至连响应返回的数据都不是json的了 我想着难道 Filter 也要跟着改 这块要改的话变动有点大 心一横 不行就把swagger升级到3.0 说不定就是版本问题

    引了最新版本的Knife4j

          <dependency>
                <groupId>com.github.xiaoymingroupId>
                <artifactId>knife4j-spring-boot-starterartifactId>
           dependency>
    
    • 1
    • 2
    • 3
    • 4

    修改config

    @EnableOpenApi
    @Configuration
    public class SwaggerConfig {
    
        private static final String SPLITOR = ";";
    
        public static Predicate<RequestHandler> basePackage(final String basePackage) {
            return input -> declaringClass(input).map(handlerPackage(basePackage)).orElse(true);
        }
    
        private static Optional<Class<?>> declaringClass(RequestHandler input) {
            return Optional.ofNullable(input.declaringClass());
        }
    
        private static Function<Class<?>, @Nullable Boolean> handlerPackage(final String basePackage) {
            return input -> {
                // 循环判断匹配
                for (String strPackage : basePackage.split(SPLITOR)) {
                    boolean isMatch = input.getPackage().getName().startsWith(strPackage);
                    if (isMatch) {
                        return true;
                    }
                }
                return false;
            };
        }
    
        /**
         * 配置基本信息
         * @return
         */
        @Bean
        public ApiInfo apiInfo() {
            return new ApiInfoBuilder()
                    .title("xxxx sss端API接口文档")
                    .description("swagger app restful api")
                    .termsOfServiceUrl("https://xxx.xxx.xxx")
                    .contact(new Contact("Dotclv","",""))
                    .version("1.0")
                    .build();
        }
    
        /**
         * 配置文档生成最佳实践
         * @param apiInfo
         * @return
         */
        @Bean
        public Docket createRestApi(ApiInfo apiInfo) {
            return new Docket(DocumentationType.OAS_30)
                    .apiInfo(apiInfo)
                    .groupName("SwaggerGroupOneAPI")
                    .select()
                    .apis(RequestHandlerSelectors.withClassAnnotation(RestController.class))
                    .paths(PathSelectors.any())
                    .build()
                    .securitySchemes(Collections.singletonList(securityScheme()))
                    .globalOperationParameters(setHeaderToken());
        }
    
        @Bean
        public Docket groupCommon() {
            return new Docket(DocumentationType.OAS_30)
                    .apiInfo(this.apiInfo())
                    .ignoredParameterTypes(ModelAttribute.class)
                    .groupName("通用模块")
                    .select()
                    //此包路径下的类,才生成接口文档
                    .apis(basePackage("xxx.xxx.xxxx.common"))
                    //加了ApiOperation注解的类,才生成接口文档
                    .apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))
                    .paths(PathSelectors.any())
                    .build()
                    .securitySchemes(Collections.singletonList(securityScheme()))
                    .securityContexts(securityContexts());
    
        }
    
        /**
         * 新增 securityContexts 保持登录状态
         */
        private List<SecurityContext> securityContexts() {
            return new ArrayList(
                    Collections.singleton(SecurityContext.builder()
                            .securityReferences(defaultAuth())
                            .forPaths(PathSelectors.regex("^(?!auth).*$"))
                            .build())
            );
        }
    
        private List<SecurityReference> defaultAuth() {
            AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything");
            AuthorizationScope[] authorizationScopes = new AuthorizationScope[1];
            authorizationScopes[0] = authorizationScope;
            return new ArrayList(
                    Collections.singleton(new SecurityReference(DefContants.X_ACCESS_TOKEN, authorizationScopes)));
        }
    
        /***
         * oauth2配置
         * 需要增加swagger授权回调地址
         * http://localhost:8888/webjars/springfox-swagger-ui/o2c.html
         * @return
         */
        @Bean
        SecurityScheme securityScheme() {
            return new ApiKey(DefContants.X_ACCESS_TOKEN, DefContants.X_ACCESS_TOKEN, "header");
        }
    
        /**
         * JWT token
         *
         * @return
         */
        private List<Parameter> setHeaderToken() {
            ParameterBuilder tokenPar = new ParameterBuilder();
            List<Parameter> pars = new ArrayList<>();
            tokenPar.name(DefContants.X_ACCESS_TOKEN).description("token").modelRef(new ModelRef("string")).parameterType("header").required(false).build();
            pars.add(tokenPar.build());
            return pars;
        }
    
    
        /**
        * 增加如下配置可解决Spring Boot 6.x 与Swagger 3.0.0 不兼容问题
        **/
        @Bean
        public WebMvcEndpointHandlerMapping webEndpointServletHandlerMapping(WebEndpointsSupplier webEndpointsSupplier, ServletEndpointsSupplier servletEndpointsSupplier, ControllerEndpointsSupplier controllerEndpointsSupplier, EndpointMediaTypes endpointMediaTypes, CorsEndpointProperties corsProperties, WebEndpointProperties webEndpointProperties, Environment environment) {
            List<ExposableEndpoint<?>> allEndpoints = new ArrayList();
            Collection<ExposableWebEndpoint> webEndpoints = webEndpointsSupplier.getEndpoints();
            allEndpoints.addAll(webEndpoints);
            allEndpoints.addAll(servletEndpointsSupplier.getEndpoints());
            allEndpoints.addAll(controllerEndpointsSupplier.getEndpoints());
            String basePath = webEndpointProperties.getBasePath();
            EndpointMapping endpointMapping = new EndpointMapping(basePath);
            boolean shouldRegisterLinksMapping = this.shouldRegisterLinksMapping(webEndpointProperties, environment, basePath);
            return new WebMvcEndpointHandlerMapping(endpointMapping, webEndpoints, endpointMediaTypes, corsProperties.toCorsConfiguration(), new EndpointLinksResolver(allEndpoints, basePath), shouldRegisterLinksMapping, null);
        }
        private boolean shouldRegisterLinksMapping(WebEndpointProperties webEndpointProperties, Environment environment, String basePath) {
            return webEndpointProperties.getDiscovery().isEnabled() && (StringUtils.hasText(basePath) || ManagementPortType.get(environment).equals(ManagementPortType.DIFFERENT));
        }
    }
    
    • 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
    • 140
    • 141
    • 142

    你以为完了 不不 它又出问题了 升级到3.0 本地运行没有一点问题 但是一打包到线上运行就报错mapstruct 转换异常 什么swagger-2.0的错误 我就纳闷了我用的是3.0啊 咋报2.0的错误 千搜万搜 找了一堆没有用的解释文章 后面在一个github的评论区看到一老哥说 运行时和编译时依赖不一样
    心想这还玩个花 加个依赖试试

           <dependency>
                <groupId>com.github.xiaoymingroupId>
                <artifactId>knife4j-spring-boot-starterartifactId>
                <exclusions>
                    <exclusion>
                        <artifactId>mapstructartifactId>
                        <groupId>org.mapstructgroupId>
                    exclusion>
                exclusions>
            dependency>
    
            <dependency>
                <groupId>org.mapstructgroupId>
                <artifactId>mapstructartifactId>
            dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    后面编译运行果然没有问题 swagger也正常了 接口也返回数据也正常了 真难
    改都改到这了算了 直接升springboot 版本到2.x最后一个版本算了 就又改了 parent 的版本到2.7.16 后面在运行就没有其他问题了 但是它又报循环依赖 好嘛 这个还要手动配置

    spring:
      main:
        allow-circular-references: true
        lazy-initialization: true
      mvc:
        pathmatch:
          matching-strategy: ant_path_matcher
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    这边循环依赖 懒加载 包括2.6后整合swagger的依赖启动报错 一起配置了 然后这会是真的没有问题了 真是一波好几折

  • 相关阅读:
    qt调用python脚本中的函数
    常见的浏览器跨域解决方法
    第六章:函数(中)
    前端面试基础题——12
    CRC循环冗余校验计算方法
    解密京东面试:如何应对Redis缓存穿透?
    中英文说明书丨Abbkine细胞迁移分析试剂盒
    标志位的设置与判断
    TensorFlow 用 hashtable 的意义
    java Map集合基本功能
  • 原文地址:https://blog.csdn.net/yumingyang0212/article/details/134296179