Unable to scan documentation context default solution appears when Swagger2 starts

One, the problem

The local project has done the configuration of Swagger2, and the following error is reported during startup:

DocumentationPluginsBootstrapper : Unable to scan documentation context default

Controller file tested:

package com.quantsmart.controller;

import com.quantsmart.model.R;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.Authorization;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author: kaiyi
 * @Date 2021/5/21 13:57
 */
@RestController
@Api(tags = "CoinCommon里面的测试接口")
public class TestController {

    @GetMapping("/common/test")
    @ApiOperation(value = "测试方法", authorizations = {@Authorization("Authorization")})
    @ApiImplicitParams({
            @ApiImplicitParam(name = "param", value = "参数1", dataType = "String", paramType = "query", example = "paramValue"),
            @ApiImplicitParam(name = "param1", value = "参数2", dataType = "String", paramType = "query", example = "paramValue")
    })
    public R<String> testMethod(String param, String param2){
        return R.ok("ok,哈哈哈,测试哇");
    }

}

Swagger2 configuration

/config/swagger/SwaggerProperties.java


package com.quantsmart.config.swagger;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;

/**
 * @author: kaiyi
 * @Date 2021/5/20 16:50
 */
@Data
@ConfigurationProperties(prefix = "swagger2")
public class SwaggerProperties {

    /**
     * 是否开启swagger
     */
    private Boolean enabled;

    /**
     * 包扫描的路径
     */
    private String basePackage;

    /**
     * 联系人的名称
     */
    private String name ;

    /**
     * 联系人的主页
     */
    private String url ;

    /**
     * 联系人的邮箱
     */
    private String email ;

    /**
     * API的标题
     */
    private String  title  ;

    /**
     * API的描述
     */
    private String description ;

    /**
     * API的版本号
     */
    private String version ;

    /**
     * API的服务团队
     */
    private String termsOfServiceUrl ;

}

/config/swagger/SwaggerAutoConfiguration.java

package com.quantsmart.config.swagger;

import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
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.service.*;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spi.service.contexts.SecurityContext;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

import java.util.Arrays;
import java.util.List;


/**
 * @author: kaiyi
 * @Date 2021/5/20 16:50
 */

@Configuration
@EnableSwagger2  // 开启swagger2自动生成api文档的功能
@EnableConfigurationProperties(SwaggerProperties.class)
public class SwaggerAutoConfiguration {

    private SwaggerProperties swaggerProperties;

    public SwaggerAutoConfiguration(SwaggerProperties swaggerProperties) {
        this.swaggerProperties = swaggerProperties;
    }

    @Bean
    public Docket docket() {
        Docket docket = new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(apiInfo())
                .select()
                .apis(RequestHandlerSelectors.basePackage(swaggerProperties.getBasePackage()))
                .paths(PathSelectors.any())
                .build();
        // 安全的配置
        docket.securitySchemes(securitySchemes()) // 安全规则
                .securityContexts(securityContexts()); // 安全配置的上下问
        return docket;
    }

    /**
     * api 信息的简介
     *
     * @return
     */
    private ApiInfo apiInfo() {
        return new ApiInfoBuilder().contact(
                new Contact(swaggerProperties.getName(), swaggerProperties.getUrl(), swaggerProperties.getEmail())
        )
                .title(swaggerProperties.getTitle())
                .description(swaggerProperties.getDescription())
                .version(swaggerProperties.getVersion())
                .termsOfServiceUrl(swaggerProperties.getTermsOfServiceUrl())
                .build();

    }

    /**
     * 安全的规则配置
     *
     * @return
     */
    private List<SecurityScheme> securitySchemes() {
        return Arrays.asList(new ApiKey("Authorization", "Authorization", "Authorization"));
    }

    /**
     * 安全的上下文
     *
     * @return
     */
    private List<SecurityContext> securityContexts() {
        return Arrays.asList(new SecurityContext(
                Arrays.asList(new SecurityReference("Authorization", new AuthorizationScope[]{new AuthorizationScope("global", "accessResource")})),
                PathSelectors.any()
        ));
    }




}

Note that the apis(RequestHandlerSelectors.basePackage(swaggerProperties.getBasePackage())) scan here is the controller package, and is the cause of the following error:

ERROR 4928 --- [           main] d.s.w.p.DocumentationPluginsBootstrapper : Unable to scan documentation context default
java.lang.NullPointerException: null
    at java.lang.String.startsWith(String.java:1405) ~[na:1.8.0_131]
    at java.lang.String.startsWith(String.java:1434) ~[na:1.8.0_131]
    at springfox.documentation.builders.RequestHandlerSelectors$4.apply(RequestHandlerSelectors.java:98) ~[springfox-core-2.9.2.jar:null]
    at springfox.documentation.builders.RequestHandlerSelectors$4.apply(RequestHandlerSelectors.java:95) ~[springfox-core-2.9.2.jar:null]
    at com.google.common.base.Present.transform(Present.java:75) ~[guava-20.0.jar:na]
    at springfox.documentation.builders.RequestHandlerSelectors$5.apply(RequestHandlerSelectors.java:114) ~[springfox-core-2.9.2.jar:null]
    at springfox.documentation.builders.RequestHandlerSelectors$5.apply(RequestHandlerSelectors.java:111) ~[springfox-core-2.9.2.jar:null]
    at com.google.common.base.Predicates$AndPredicate.apply(Predicates.java:384) ~[guava-20.0.jar:na]
    at com.google.common.base.Predicates$AndPredicate.apply(Predicates.java:384) ~[guava-20.0.jar:na]
    at com.google.common.collect.Iterators$6.computeNext(Iterators.java:617) ~[guava-20.0.jar:na]
    at com.google.common.collect.AbstractIterator.tryToComputeNext(AbstractIterator.java:145) ~[guava-20.0.jar:na]
    at com.google.common.collect.AbstractIterator.hasNext(AbstractIterator.java:140) ~[guava-20.0.jar:na]
    at springfox.documentation.spring.web.scanners.ApiListingReferenceScanner.scan(ApiListingReferenceScanner.java:48) ~[springfox-spring-web-2.9.2.jar:null]
    at springfox.documentation.spring.web.scanners.ApiDocumentationScanner.scan(ApiDocumentationScanner.java:67) ~[springfox-spring-web-2.9.2.jar:null]
    at springfox.documentation.spring.web.plugins.DocumentationPluginsBootstrapper.scanDocumentation(DocumentationPluginsBootstrapper.java:101) [springfox-spring-web-2.9.2.jar:null]
    at springfox.documentation.spring.web.plugins.DocumentationPluginsBootstrapper.start(DocumentationPluginsBootstrapper.java:167) [springfox-spring-web-2.9.2.jar:null]
    at org.springframework.context.support.DefaultLifecycleProcessor.doStart(DefaultLifecycleProcessor.java:182) [spring-context-5.2.6.RELEASE.jar:5.2.6.RELEASE]
    at org.springframework.context.support.DefaultLifecycleProcessor.access$200(DefaultLifecycleProcessor.java:53) [spring-context-5.2.6.RELEASE.jar:5.2.6.RELEASE]
    at org.springframework.context.support.DefaultLifecycleProcessor$LifecycleGroup.start(DefaultLifecycleProcessor.java:360) [spring-context-5.2.6.RELEASE.jar:5.2.6.RELEASE]
    at org.springframework.context.support.DefaultLifecycleProcessor.startBeans(DefaultLifecycleProcessor.java:158) [spring-context-5.2.6.RELEASE.jar:5.2.6.RELEASE]
    at org.springframework.context.support.DefaultLifecycleProcessor.onRefresh(DefaultLifecycleProcessor.java:122) [spring-context-5.2.6.RELEASE.jar:5.2.6.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.finishRefresh(AbstractApplicationContext.java:894) [spring-context-5.2.6.RELEASE.jar:5.2.6.RELEASE]
    at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.finishRefresh(ServletWebServerApplicationContext.java:162) [spring-boot-2.2.7.RELEASE.jar:2.2.7.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:553) [spring-context-5.2.6.RELEASE.jar:5.2.6.RELEASE]
    at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:141) [spring-boot-2.2.7.RELEASE.jar:2.2.7.RELEASE]
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:747) [spring-boot-2.2.7.RELEASE.jar:2.2.7.RELEASE]
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:397) [spring-boot-2.2.7.RELEASE.jar:2.2.7.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:315) [spring-boot-2.2.7.RELEASE.jar:2.2.7.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1226) [spring-boot-2.2.7.RELEASE.jar:2.2.7.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1215) [spring-boot-2.2.7.RELEASE.jar:2.2.7.RELEASE]
    at com.coin.TestCommonApplication.main(TestCommonApplication.java:12) [classes/:na]

Two, the solution

The problem has been found above, if I change apis(RequestHandlerSelectors.basePackage(swaggerProperties.getBasePackage())) to the specific package I want to scan at this time

apis(RequestHandlerSelectors.basePackage(“com.quantsmart.controller”))

Restart at this time, you can find that the above error does not appear in the printed log, and a controller interface is printed and scanned in the DocumentationPluginsBootstrapper.

image.png

The above modification method is directly hard-coded, so we can configure swaggerProperties.getBasePackage() in the configuration file, the controller package path (that is, the basePackage attribute in the SwaggerProperties class), for example, add the controller package path application.yml


# Swagger2属性配置
swagger2:
  base-package: com.quantsmart.controller  # 需要指定扫描的包的路径

Then visit the http://localhost:8989/swagger-ui.html page, you can see that you can successfully see the interface document page:

image.png


Corwien
为者常成,行者常至!

为者常成,行者常至。

6.3k 声望
1.6k 粉丝
0 条评论
推荐阅读
CDH6 离线安装
Cloudera Manager是一个拥有集群自动化安装、中心化管理、集群监控、报警功能的一个工具,使得安装集群从几天的时间缩短在几个小时内,运维人员从数十人降低到几人以内,极大的提高集群管理的效率。

Corwien2阅读 1.9k

与RabbitMQ有关的一些知识
工作中用过一段时间的Kafka,不过主要还是RabbitMQ用的多一些。今天主要来讲讲与RabbitMQ相关的一些知识。一些基本概念,以及实际使用场景及一些注意事项。

lpe2348阅读 1.8k

封面图
万字详解,吃透 MongoDB!
MongoDB 是一个基于 分布式文件存储 的开源 NoSQL 数据库系统,由 C++ 编写的。MongoDB 提供了 面向文档 的存储方式,操作起来比较简单和容易,支持“无模式”的数据建模,可以存储比较复杂的数据类型,是一款非常...

JavaGuide4阅读 377

封面图
Git操作不规范,战友提刀来相见!
年终奖都没了,还要扣我绩效,门都没有,哈哈。这波骚Git操作我也是第一次用,担心闪了腰,所以不仅做了备份,也做了笔记,分享给大家。问题描述小A和我在同时开发一个功能模块,他在优化之前的代码逻辑,我在开...

王中阳Go5阅读 2.1k评论 2

封面图
Redis 发布订阅模式:原理拆解并实现一个消息队列
“65 哥,如果你交了个漂亮小姐姐做女朋友,你会通过什么方式将这个消息广而告之给你的微信好友?““那不得拍点女朋友的美照 + 亲密照弄一个九宫格图文消息在朋友圈发布大肆宣传,暴击单身狗。”像这种 65 哥通过朋...

码哥字节6阅读 1.3k

封面图
PHP转Go实践:xjson解析神器「开源工具集」
我和劲仔都是PHP转Go,身边越来越多做PHP的朋友也逐渐在用Go进行重构,重构过程中,会发现php的json解析操作(系列化与反序列化)是真的香,弱类型语言的各种隐式类型转换,很大程度的减低了程序的复杂度。

王中阳Go6阅读 1.4k评论 2

封面图
NB的Github项目,看到最后一个我惊呆了!
最近看到不少好玩的、实用的 Github 项目,就来给大家推荐一把。中国制霸生成器最近在朋友圈非常火的一个小网站,可以在线标记 居住、短居、游玩、出差、路过 标记后可生成图片进行社区分享,标记过的信息会记录...

艾小仙5阅读 1.6k评论 1

为者常成,行者常至。

6.3k 声望
1.6k 粉丝
宣传栏