Spingboot升级2.6.5全过程(含swagger3.0升级)

3月29日spring爆出cve-2022-22950漏洞,为修复漏洞,公司3个版本的框架需要升级至2.6.5,记录填坑程,全是干货。

原版本是2.0.5 和 2.1.18。

1、spring.profiles.active配置失效

springboot2.4之前的yml配置写法

spring: 
  profiles:
    active: test

springboot2.4之后的yml配置写法

spring: 
  config:
    activate:
      on-profile:
      - test

2、内置tomcat不在支持tomcat8.5版本的

升级至 <tomcat.version>9.0.60</tomcat.version>

3、由于SpringBoot禁止了循环引用,会报出循环依赖的错误,要解决这个问题其实很简单,你可以修改application.yml直接允许循环引用,不过这个方法有点粗暴,在没有其他方法的时候可以使用;其实循环引用主要是因为会导致Spring不知道该先创建哪个Bean才会被禁用的,我们可以使用@Lazy注解指定某个Bean进行懒加载就可以优雅解决该问题。

spring:
  main: 
    allow-circular-references: true

4、swagger2导致plugin-core包冲突,解决方案升级swagger3

<dependency>
  <groupId>io.springfox</groupId>
  <artifactId>springfox-boot-starter</artifactId>
  <version>3.0.0</version>
</dependency>

  附上swagger3的一些配置

@Configuration
@EnableOpenApi
public class Swagger3Config {

    @Bean
    public Docket createRestApi() {
        // 添加全局header参数
        List<RequestParameter> parameters = new ArrayList<>();
        parameters.add(new RequestParameterBuilder().name("authorization").description("token").required(false)
                .in(ParameterType.HEADER).query(q -> q.model(m -> m.scalarModel(ScalarType.STRING))).required(false)
                .build());
        return new Docket(DocumentationType.OAS_30).pathProvider(new CustRelativePathProvider())
                .directModelSubstitute(LocalDateTime.class, Date.class)
                .directModelSubstitute(LocalDate.class, String.class)
                .directModelSubstitute(LocalTime.class, String.class)
                .directModelSubstitute(ZonedDateTime.class, String.class).globalRequestParameters(parameters)
                .apiInfo(apiInfo()).select().apis(RequestHandlerSelectors.basePackage("com.hrbwmxx"))
                .paths(PathSelectors.any()).build();
    }

    private ApiInfo apiInfo() {
        return new ApiInfoBuilder().title("管理平台接口").description("管理平台接口文档").version("v 1.0").build();
    }

    /**
     * 增加全局请求后缀.do
     * 
     * @description
     * @author gqf
     * @date 2022-4-6
     * @version v1.0
     */
    public class CustRelativePathProvider extends DefaultPathProvider {

        public static final String ROOT = "/";

        @Override
        public String getOperationPath(String operationPath) {
            UriComponentsBuilder uriComponentsBuilder = UriComponentsBuilder.fromPath("/");
            String uri = Paths
                    .removeAdjacentForwardSlashes(uriComponentsBuilder.path(operationPath).build().toString());
            return uri + ".do";
        }

        @Override
        protected String getDocumentationPath() {
            return ROOT;
        }
    }
}

5、使用了bean覆盖,需要增加配置


spring:
  main: 
    allow-bean-definition-overriding: true

6、升级导致请求后缀(.do)mapping映射失效,找不到映射,重写WebMvcConfigurer,重新配置dispatcherServlet,并配置静态资源处理及后缀.do处理,同时配置swagger相关资源。这个问题研究了1天,配置文件如何修改都不好使,必须要重新注册dispatcherServlet。

@EnableWebMvc
@ComponentScan(basePackages = { "com.hrbwmxx" })
@Configuration
public class WebMvcSuffixConfig implements WebMvcConfigurer {

    @Override
    public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
        // 指定请求后缀
        configurer.mediaType(".do", MediaType.APPLICATION_JSON);
    }

    @Override
    public void configurePathMatch(PathMatchConfigurer configurer) {
        // 设置是否是后缀模式匹配,如“/user”是否匹配/user.*,默认真即匹配;不用再RequestMapping中写.do
        configurer.setUseSuffixPatternMatch(true);
        configurer.setUseRegisteredSuffixPatternMatch(true);
    }
}

如果使用java8的LocalDateTime,会导致日期转换器失效, 需要在addFormatters中注册日期转获器才能生效。

@Configuration
public class WebMvcConfg implements WebMvcConfigurer {

    private static Logger logger = LoggerFactory.getLogger(WebMvcConfg.class);

    @Resource
    private DispatcherServlet dispatcherServlet;

    /**
     * 静态资源管理
     */
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/**").addResourceLocations("/");
        registry.addResourceHandler("/**.html").addResourceLocations("/");
        registry.addResourceHandler("/swagger-ui/**")
        .addResourceLocations("classpath:/META-INF/resources/webjars/springfox-swagger-ui/");
        registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
    }

    /**
     * 开启springmvc 对应 mvc:annotation-driven 项
     * @param registry
     */
    @Override
    public void addFormatters(FormatterRegistry registry) {
        registry.addFormatter(new CurrencyStyleFormatter());
        
        //重新注册日期转换器
        registry.addConverter(new Converter<String, LocalDate>() {

            @Override
            public LocalDate convert(String source) {
                if (StringUtilx.isEmpty(source)) {
                    return null;
                } else {
                    return LocalDate.parse(source.toString(),
                            DateTimeFormatter.ofPattern(DateConfig.DEFAULT_DATE_FORMAT));
                }
            }
        });
        registry.addConverter(new Converter<String, LocalDateTime>() {

            @Override
            public LocalDateTime convert(String source) {
                if (StringUtilx.isEmpty(source)) {
                    return null;
                } else {
                    return LocalDateTime.parse(source.toString(),
                            DateTimeFormatter.ofPattern(DateConfig.DEFAULT_DATE_TIME_FORMAT));
                }
            }
        });
        registry.addConverter(new Converter<String, LocalTime>() {

            @Override
            public LocalTime convert(String source) {
                if (StringUtilx.isEmpty(source)) {
                    return null;
                } else {
                    return LocalTime.parse(source.toString(),
                            DateTimeFormatter.ofPattern(DateConfig.DEFAULT_TIME_FORMAT));
                }
            }
        });
        registry.addConverter(new Converter<String, Date>() {

            @Override
            public Date convert(String source) {
                SimpleDateFormat format = new SimpleDateFormat(DateConfig.DEFAULT_DATE_TIME_FORMAT);
                try {
                    return format.parse(source.toString());
                } catch (ParseException e) {
                    return null;
                }
            }
        });
    }

    @Override
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
        // 注册Spring data jpa pageable的参数分解器
        argumentResolvers.add(new PageableHandlerMethodArgumentResolver());
    }

    /**
     * 重新定义dispatcherServlet拦截方案,所有.do访问进行拦截 (前后端分离专用,仅拦截后端接口)
     *
     * @return
     */
    @Bean
    public ServletRegistrationBean<DispatcherServlet> dispatcherServletBean() {
    	// 注解扫描上下文
        AnnotationConfigWebApplicationContext applicationContext = new AnnotationConfigWebApplicationContext();
        applicationContext.register(WebMvcSuffixConfig.class);
        // 通过构造函数指定dispatcherServlet的上下文
        DispatcherServlet suffixDispatcherServlet = new DispatcherServlet(applicationContext);
        suffixDispatcherServlet.setApplicationContext(applicationContext);
        // 用ServletRegistrationBean包装servlet
        ServletRegistrationBean<DispatcherServlet> bean = new ServletRegistrationBean<DispatcherServlet>(
                suffixDispatcherServlet);
        // 注入上传配置到自己注册的ServletRegistrationBean
        bean.addUrlMappings("*.do");
        bean.addUrlMappings("*.html");
        bean.addUrlMappings("*.css");
        bean.addUrlMappings("*.js");
        bean.addUrlMappings("*.jpg");
        bean.addUrlMappings("*.png");
        bean.addUrlMappings("*.gif");
        bean.addUrlMappings("*.jpeg");
        bean.addUrlMappings("*.ico");
        bean.addUrlMappings("*.woff");
        bean.addUrlMappings("*.woff2");
        bean.addUrlMappings("*.ttf");
        bean.addUrlMappings("/swagger-resources/configuration/ui");
        bean.addUrlMappings("/swagger-resources/configuration/security");
        bean.addUrlMappings("/swagger-resources");
        bean.addUrlMappings("/v3/api-docs/*");
        bean.setLoadOnStartup(0);
        // 把默认的给覆盖掉
        bean.setName("dispatcherServlet");
        return bean;
    }

}

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

行走的冬瓜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值