上节我们初步了解Docket,接下来我们继续了解Docket内的配置方法。
select(),selector()方法
这两个方法实现了扫描项目中接口的功能。其中select()
方法是行为,selector()
是行为的发起者,行为被委托给ApiSelectorBuilder
对象去具体实现,当行为完成后,ApiSelectorBuilder
将行为的结果返回给行为的发起者selector()
。
注释翻译为:
*启动用于api选择的生成器。
*@return api选择生成器。要完成构建api选择器,请使用api选择器的构建方法需要调用,这将在调用build方法时自动返回到构建摘要。
*/
ApiSelectorBuilder
(接口选择器构建者)
apis()
方法
该对象是扫描接口的执行者,调用apis()
方法 完成行为,调用build()
方法将行为结果返回给行为的发起者selector()
,selector()
返回Docket实例,使得结果最后归于Docket。
apis()
方法的参数决定如何扫描我们的接口,apis()
方法提供了5种扫描方式,分别如下:
- 1、RequestHandlerSelectors.none() 不匹配任何controller的接口
- 2、RequestHandlerSelectors.any() 匹配任何controller的接口
- 3、RequestHandlerSelectors.withClassAnnotation() 扫描含有类注解的 参数为
注解名
+.class
- 4、RequestHandlerSelectors.withMethodAnnotation() 扫描含有方法注解的 参数为
注解名
+.class
- 5、RequestHandlerSelectors.basePackage() 扫描指定包路径 参数为 包路径的字符串
以第一种为例,代码如下:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
import java.util.ArrayList;
/**
* TODO
*
* @author ben
* @version 1.0
* @date 2022/9/13 11:23
*/
@Configuration
@EnableSwagger2
public class SwaggerConfig {
@Bean
public Docket docket() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.select()
.apis(RequestHandlerSelectors.none())
.build();
}
//配置文档信息
private ApiInfo apiInfo() {
Contact contact = new Contact("ben", "https://xxxxxx.com", "Swagger2Config@SpringBoot.com");
return new ApiInfo(
"Ben的学习总结", // 标题
"Swagger2Config", // 描述
"v1.0", // 版本
"https://xxxxxx.com", // 组织链接
contact, // 联系人信息
"Apach 2.0 许可", // 许可
"https://xxxxxx.com", // 许可连接
new ArrayList<>()// 扩展
);
}
}
启动看一看:
之前:
我在controller
层新建了两个接口:
扫描包路径:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
import java.util.ArrayList;
/**
* TODO
*
* @author ben
* @version 1.0
* @date 2022/9/13 11:23
*/
@Configuration
@EnableSwagger2
public class SwaggerConfig {
@Bean
public Docket docket() {
return new Docket(DocumentationType.SWAGGER_2)
//配置文档信息
.apiInfo(apiInfo())
//扫描行为
.select()
//接口扫描 不匹配任何controller的接口
// .apis(RequestHandlerSelectors.none())
//扫描指定包路径 参数为 包路径的字符串
.apis(RequestHandlerSelectors.basePackage("cn.ben.swagger2config.controller"))
.build();
}
//配置文档信息
private ApiInfo apiInfo() {
Contact contact = new Contact("ben", "https://xxxxxx.com", "Swagger2Config@SpringBoot.com");
return new ApiInfo(
"Ben的学习总结", // 标题
"Swagger2Config", // 描述
"v1.0", // 版本
"https://xxxxxx.com", // 组织链接
contact, // 联系人信息
"Apach 2.0 许可", // 许可
"https://xxxxxx.com", // 许可连接
new ArrayList<>()// 扩展
);
}
}
启动后:
apis()
的运用
@Bean
public Docket createRestApi() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.select()
.apis(RequestHandlerSelectors.basePackage("com.fan.controller"))
.apis(RequestHandlerSelectors.withClassAnnotation(Api.class))
.build().globalOperationParameters(defaultHeader());
}
如上代码,在apis()
方法中可以进行配置扫描条件,可以通过apis()
进行多次设置,apis方法参数为Predicate<RequestHandler> selector
。
// apis方法源码
public ApiSelectorBuilder apis(Predicate<RequestHandler> selector) {
this.requestHandlerSelector = Predicates.and(this.requestHandlerSelector, selector);
return this;
}
查看apis()
方法的源码可以发现,条件参数selector被Predicates以and()方法操作,并返回一个Predicate<RequestHandler>
类,Predicates.and()
实际上完成"条件1 and 条件2"的操作,类似于sql语句where条件的内容,根据这个特点,可以通过Predicates.and()
和Predicates.or()
的方法完成"(条件1 and 条件2) or 条件3"的操作,就可以扫描任何指定包下的API,并实现多路径扫描、交集、并集等配置。swagger示例如下:
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import io.swagger.annotations.ApiOperation;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import springfox.documentation.RequestHandler;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.ParameterBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.schema.ModelRef;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.service.Parameter;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
import java.util.ArrayList;
import java.util.List;
@EnableSwagger2
@Configuration
public class SwaggerConfig {
@Bean
public Docket createRestApi() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.select()
.apis(getBasePackages())
.build();
}
// 设置多路径
private Predicate<RequestHandler> getBasePackages() {
Predicate<RequestHandler> predicate = Predicates.and(RequestHandlerSelectors.basePackage("cn.ben.for_learn_projects.swagger2config.controller")); // 扫描cn.ben.for_learn_projects.swagger2config.controller包
predicate = Predicates.and(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class), predicate) // 扫描cn.ben.for_learn_projects.swagger2config.controller包下有@ApiOperation,和上面是交集
predicate = Predicates.or(RequestHandlerSelectors.basePackage("cn.ben.for_learn_projects.swagger2config.controller2"), predicate)// 扫描cn.ben.for_learn_projects.swagger2config.controller2包,和上面是并集
return predicate;
}
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
.title("后台API接口文档")
.description("后台API接口文档")
.termsOfServiceUrl("")
.contact(new Contact("", "", "1663501@qq.com"))
.version("V 1.0.0")
.build();
}
}
paths()
方法
在 ApiSelectorBuilder
对象中,通过apis()
方法扫描接口,通过paths()
方法过滤接口。
path()
方法接收一个 PathSelectors
对象
该对象有四个方法,对应四种过滤方式:
-
any() // 任何请求都扫描
-
none() // 任何请求都不扫描
-
regex(final String pathRegex) // 通过正则表达式控制
@Bean public Docket docket(){ return new Docket(DocumentationType.SWAGGER_2) .apiInfo(apiInfo()) .select() .paths(PathSelectors.regex("^[+-@=](.*?)"))//该正则表示匹配所有 .build(); }
-
ant(final String antPattern) // 通过ant()控制
@Bean public Docket docket(){ return new Docket(DocumentationType.SWAGGER_2) .apiInfo(apiInfo()) .select() .paths(PathSelectors.ant("/test-swagger2/**"))//匹配/test-swagger2/开头的所有controller .build(); }
当apis()
与paths()
一起使用时,代码如下:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
import java.util.ArrayList;
/**
* TODO
*
* @author ben
* @version 1.0
* @date 2022/9/13 11:23
*/
@Configuration
@EnableSwagger2
public class SwaggerConfig {
@Bean
public Docket docket() {
return new Docket(DocumentationType.SWAGGER_2)
//配置文档信息
.apiInfo(apiInfo())
//扫描行为
.select()
//接口扫描 不匹配任何controller的接口
// .apis(RequestHandlerSelectors.none())
//扫描指定包路径 参数为 包路径的字符串
.apis(RequestHandlerSelectors.basePackage("cn.ben.for_learn_projects.swagger2config.controller"))
/// 任何请求都扫描
.paths(PathSelectors.any())
.build();
}
//配置文档信息
private ApiInfo apiInfo() {
Contact contact = new Contact("ben", "https://xxxxxx.com", "Swagger2Config@SpringBoot.com");
return new ApiInfo(
"Ben的学习总结", // 标题
"Swagger2Config", // 描述
"v1.0", // 版本
"https://xxxxxx.com", // 组织链接
contact, // 联系人信息
"Apach 2.0 许可", // 许可
"https://xxxxxx.com", // 许可连接
new ArrayList<>()// 扩展
);
}
}
小结
Docket内有select()
方法将扫描行为委托给ApiSelectorBuilder
对象,ApiSelectorBuilder
通过apis()
方法扫描接口,通过 paths()
方法过滤接口,最后通过build()
方法将扫描行为的结果返回selecteor()
,将行为的结果带回Docket。