Swagger2限定接口范圍


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

不過默認情況下,Swagger2會把項目中的所有接口都展示在列表里,特別是你用了Springboot/SpringCloud之后,各種內部health check的接口,但其實這些都沒必要展示出來。

這時候,你就需要限定接口的范圍了。

實現方法

增加一個配置類,簡要代碼如下:

@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…

不過,這時候,有個新問題,如果要增加展示 com.springXXX 的接口,怎么辦呢?

優化方案

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

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

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

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

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

  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());
	}

}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM