升级SpringBoot 2.6 Swagger documentationPluginsBootstrapper null

  • Post author:
  • Post category:其他


1.版本

spring boot 2.5.8 升级到spring boot 2.6.6

swagger-spring-boot-starter: 1.9.1

swagger:2.9.2

2.问题描述

3.解决方案

查看此错误,官方github中的issue中有相关的描述,增加如下配置解决

**
 * spring boot升级到2.6.6后,启动时{@link DocumentationPluginsBootstrapper}报空指针
 *
 * https://github.com/springfox/springfox/issues/3462
 *
 * https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-2.6-Release-Notes#pathpattern-based-path-matching-strategy-for-spring-mvc
 *
 */
@Configuration
@ConditionalOnProperty(prefix = "swagger", name = "enabled", havingValue = "true")
public class SwaggerConfiguration {

    @Bean
    public BeanPostProcessor removeSpringfoxHandlerProvider() {
        return new BeanPostProcessor() {

            @Override
            public Object postProcessAfterInitialization(Object bean, String beanName)  {
                if (bean instanceof DocumentationPluginsBootstrapper) {
                    try {
                        return removeSpringfoxHandlerProvider((DocumentationPluginsBootstrapper)bean);
                    } catch (NoSuchFieldException e) {
                        throw new RuntimeException(e);
                    }
                }
                return bean;
            }
        };
    }

    private DocumentationPluginsBootstrapper removeSpringfoxHandlerProvider(DocumentationPluginsBootstrapper bootstrapper)
        throws NoSuchFieldException {
        Field handlerProvidersField = bootstrapper.getClass().getDeclaredField("handlerProviders");
        handlerProvidersField.setAccessible(true);

        Object object = ReflectionUtils.getField(handlerProvidersField, bootstrapper);
        if (object == null) {
            return bootstrapper;
        }

        List<RequestHandlerProvider> requestHandlerProviders = (List<RequestHandlerProvider>) object;
        if (CollectionUtils.isEmpty(requestHandlerProviders)) {
            return bootstrapper;
        }

        List<RequestHandlerProvider> newRequestHandlerProviders = new LinkedList<>();
        for (RequestHandlerProvider requestHandlerProvider : requestHandlerProviders) {
            if (requestHandlerProvider.getClass().isAssignableFrom(WebMvcRequestHandlerProvider.class)) {
                continue;
            }
            newRequestHandlerProviders.add(requestHandlerProvider);
        }

        ReflectionUtils.setField(handlerProvidersField, bootstrapper, newRequestHandlerProviders);

        return bootstrapper;
    }

    @Bean
    public RequestHandlerProvider customRequestHandlerProvider(HandlerMethodResolver methodResolver,
                                                               List<RequestMappingInfoHandlerMapping> handlerMappings) {
        // 基本参照WebMvcRequestHandlerProvider类实现
        return new RequestHandlerProvider() {

            @Override
            public List<RequestHandler> requestHandlers() {
                return byPatternsCondition().sortedCopy(from(nullToEmptyList(handlerMappings))
                    .transformAndConcat(toMappingEntries())
                    .transform(toRequestHandler()));
            }

            private Function<? super RequestMappingInfoHandlerMapping,
                Iterable<Map.Entry<RequestMappingInfo, HandlerMethod>>> toMappingEntries() {
                return new Function<RequestMappingInfoHandlerMapping, Iterable<Map.Entry<RequestMappingInfo, HandlerMethod>>>() {
                    @Override
                    public Iterable<Map.Entry<RequestMappingInfo, HandlerMethod>> apply(RequestMappingInfoHandlerMapping input) {
                        return input.getHandlerMethods().entrySet();
                    }
                };
            }

            private Function<Map.Entry<RequestMappingInfo, HandlerMethod>, RequestHandler> toRequestHandler() {
                return new Function<Map.Entry<RequestMappingInfo, HandlerMethod>, RequestHandler>() {
                    @Override
                    public WebMvcRequestHandler apply(Map.Entry<RequestMappingInfo, HandlerMethod> input) {
                        return new WebMvcRequestHandler(
                            methodResolver,
                            tweakInfo(input.getKey()),
                            input.getValue());
                    }
                };
            }

            /**
             * 唯一更改的地方
             * @param info 请求映射信息
             * @return 新的请求映射信息
             */
            private RequestMappingInfo tweakInfo(RequestMappingInfo info) {
                if (info.getPathPatternsCondition() == null) {
                    return info;
                }
                String[] patterns = info.getPathPatternsCondition().getPatternValues().toArray(new String[]{});
                return info.mutate().options(new RequestMappingInfo.BuilderConfiguration()).paths(patterns).build();
            }
        };
    }
}



版权声明:本文为sjdl9396原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。