Swagger2限定接口範圍

前面在使用Swagger2時遇到的坑中簡單介紹了Swagger的使用。html

不過默認狀況下,Swagger2會把項目中的全部接口都展現在列表裏,特別是你用了Springboot/SpringCloud以後,各類內部health check的接口,但其實這些都不必展現出來。java

這時候,你就須要限定接口的範圍了。spring

實現方法

增長一個配置類,簡要代碼以下:api

@Configuration
@EnableSwagger2
public class Swagger2Config {

    @Bean
    public Docket buildDocket() {
        return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo()).select()
              .apis(RequestHandlerSelectors.basePackage("com.yejg")).paths(PathSelectors.any()).build();
    }
    private ApiInfo apiInfo() {
        return new ApiInfoBuilder().title("接口文檔").description("描述文字...").termsOfServiceUrl("https://yejg.top").version("V1.0").build();
    }
}

有了這個【RequestHandlerSelectors.basePackage("com.yejg")】限定以後,就只會展現【com.yejg】包下的接口了。so easy…app

不過,這時候,有個新問題,若是要增長展現 com.springXXX 的接口,怎麼辦呢?ide

優化方案

直接上代碼以前,先看下優化方案怎麼來的。優化

從代碼看,跟目錄範圍相關的就是apis方法了,源碼以下:ui

// 此Predicate是com.google.common.base.Predicate,不是jdk8的那個,不過原理相似 都是判斷的謂詞
public ApiSelectorBuilder apis(Predicate<RequestHandler> selector) {
    requestHandlerSelector = and(requestHandlerSelector, selector);
    return this;
}

想要支持配置多個目錄,就得從這個Predicate下手了。this

先看下RequestHandlerSelectors.basePackage是怎麼返回Predicate的:google

public static Predicate<RequestHandler> basePackage(final String basePackage) {
    return new Predicate<RequestHandler>() {
      @Override
      public boolean apply(RequestHandler input) {
        return declaringClass(input).transform(handlerPackage(basePackage)).or(true);
      }
    };
  }
  
    private static Function<Class<?>, Boolean> handlerPackage(final String basePackage) {
    return new Function<Class<?>, Boolean>() {
      @Override
      public Boolean apply(Class<?> input) {
        return input.getPackage().getName().startsWith(basePackage);
      }
    };
  }

重點關注上面的handlerPackage方法,它的邏輯就是:判斷項目的包路徑是否以設定的basePackage開頭。

若是改變這裏的判斷邏輯,判斷項目的包路徑是否以設定的basePackage1 或者 basePackage2 開頭,那就達到同時指定多個目錄的效果了。

實現代碼以下:

@Configuration
@EnableSwagger2
public class Swagger2Config {

    // 定義分隔符
    private static final String SEPARATOR = ",";

    @Bean
    public Docket buildDocket() {
        return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo()).select()
                .apis(basePackage("com.yejg" + SEPARATOR + "com.springXXX"))
                .paths(PathSelectors.any()).build();
    }

    private ApiInfo apiInfo() {
        return new ApiInfoBuilder().title("接口文檔").description("描述文字...")
                .termsOfServiceUrl("https://yejg.top").version("V1.0").build();
    }


    /**
     * @param basePackage
     * @return
     * @see RequestHandlerSelectors#basePackage(String)
     */
    public static Predicate<RequestHandler> basePackage(final String basePackage) {
        return new Predicate<RequestHandler>() {
            @Override
            public boolean apply(RequestHandler input) {
                return declaringClass(input).transform(handlerPackage(basePackage)).or(true);
            }
        };
    }

    private static Function<Class<?>, Boolean> handlerPackage(final String basePackage) {
        return input -> {
            // 循環判斷匹配
            for (String strPackage : basePackage.split(SEPARATOR)) {
                boolean isMatch = input.getPackage().getName().startsWith(strPackage);
                if (isMatch) {
                    return true;
                }
            }
            return false;
        };
    }

    private static Optional<? extends Class<?>> declaringClass(RequestHandler input) {
        return Optional.fromNullable(input.declaringClass());
    }

}
相關文章
相關標籤/搜索