前言

springboot集成swagger2技术比较成熟,基本不挑版本。网上技术文章一找一大堆,不在此赘述。但是sprngboot 2.6.x以上版本在集成swagger 3的时候,会报Failed to start bean 'documentationPluginsBootstrapper'; 错误

网上关于此问题的解决,有各种各样的方案,但实际实践起来非常麻烦。比如这种方案在网上说的比较多,但实际上,应用效果并不佳。

解决此问题,降版本的方案我就不说了,如果确实需要使用sprngboot 2.6.x以上版本在集成swagger 3 的兄弟,请往下看。

错误原因

报错内容

Failed to start bean 'documentationPluginsBootstrapper'; nested exception is java.lang.NullPointerException

报错原因

Springfox使用的路径匹配是基于AntPathMatcher的,而Spring Boot 2.6.X使用的是PathPatternMatcher

解决方案

依赖配置

在pom.xml中引入以下核心配置

    <dependencies>
        <!-- web -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--swagger3-->
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-boot-starter</artifactId>
            <version>3.0.0</version>
        </dependency>
    </dependencies>

    <!--版本管理-->
    <dependencyManagement>
        <dependencies>
            <!--SpringBoot-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>2.7.0</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

webmvc配置

在config目录下,新建MyWebMvcConfigurer,修改资源映射路径,完成mvc与swagger对接。
注意,这一步是最核心的,由于springboot使用的是PathPatternMatcher,所以无法识别swagger的静态资源路径。网上很多的方法指导是将springboot2.6.x版本的路径匹配规则修改回AntPathMatcher,因此要改一堆配置。而直接添加addResourceHandlers的方式,能够避免复杂的配置工作。

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;

@Configuration
public class MyWebMvcConfigurer extends WebMvcConfigurationSupport {

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        // swagger配置
        registry.
                addResourceHandler("/swagger-ui/**")
                .addResourceLocations("classpath:/META-INF/resources/webjars/springfox-swagger-ui/")
                .resourceChain(false);
    }
}

swagger配置

在config目录下,新建Swagger3Config,配置swagger所需参数

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.builders.RequestParameterBuilder;
import springfox.documentation.oas.annotations.EnableOpenApi;
import springfox.documentation.schema.ScalarType;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.ParameterType;
import springfox.documentation.service.RequestParameter;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;

import java.util.ArrayList;
import java.util.List;

@Configuration
@EnableOpenApi // swagger3开启注解,与swagger2不同
public class Swagger3Config {

    /**
     * 文档基本信息
     */
    private ApiInfo apiInfo() {
        return new ApiInfoBuilder()
                .title("swagger口文档")
                .description("swagger接口文档")
                .version("2.0")
                .build();
    }

    /**
     * 全局通用属性(摘要)配置
     */
    @Bean
    public Docket api() {
        return new Docket(DocumentationType.OAS_30)
                .apiInfo(apiInfo()) //应用文档基本信息
                .select()
                .apis(RequestHandlerSelectors.basePackage("com.albert.backend.api")) // swagger扫描路径
                .paths(PathSelectors.any()) // 应用于包下所有路径
                .build()
                .ignoredParameterTypes(User.class, AdminUser.class) // 忽略此类型输入参数(viewResovler全局添加的)
                .globalRequestParameters(getGlobalRequestParameters()); // 设置全局通用参数
    }

    /**
     * 项目通用参数,添加全局参数——登录认证token(若无可省略)
     */
    private List<RequestParameter> getGlobalRequestParameters() {
        List<RequestParameter> parameters = new ArrayList<>();
        parameters.add(new RequestParameterBuilder()
                .name("token") // 参数名
                .query(q -> q.model(m -> m.scalarModel(ScalarType.STRING))) //参数类型
                .description("登录认证token") // 描述
                .required(false) // 非必传
                .in(ParameterType.HEADER) //请求头中的参数,其它类型可以点进ParameterType类中查看
                .build());
        return parameters;
    }
}

结果

完成以上配置,swagger可正常运行,无报错

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐