文档
- 快速开始
- Knife4j 4.0 迭代计划
- 如何贡献代码
- 序章
- 社区
- 增强特性
- 3.1 增强模式
- 3.2 i18n 国际化
- 3.3 接口添加作者
- 3.4 自定义文档
- 3.5 访问权限控制
- 3.6 接口排序
- 3.7 分组排序
- 3.8 请求参数缓存
- 3.9 动态请求参数
- 3.10 导出离线文档
- 3.11 过滤请求参数
- 3.12 包含请求参数
- 3.13 搜索API接口
- 3.14 清除缓存
- 3.15 动态请求参数添加文档注释
- 3.16 动态响应参数添加文档注释
- 3.17 自定义Host
- 3.18 afterScript
- 3.19 OAuth2
- 3.20 导出 Postman
- 3.21 全局参数
- 3.22 自定义 Swagger Models 名称
- 3.23 自定义主页内容
- 3.24 自定义 Footer
- 3.25 JSR303
- 3.26 禁用调试
- 3.27 禁用搜索框
- 3.28 禁用 OpenApi 结构显示
- 3.29 版本控制
- 生态中间件
- 升级
中间件
- 中间件介绍
- Aggregation 微服务聚合中间件
- Desktop 独立渲染组件
OAS 简介
- OAS 简介
- OpenAPI 规范
- Java 注解
实战指南
- 示例代码
- Spring 单体架构
- Spring 微服务架构
- OAuth 2.0
- 微服务聚合实战
- ASP.NET Core
- Springfox 源码系列
- Springfox 源码系列
- springfox 源码分析(一) 程序入口
- springfox 源码分析(二) 初探 mapstruct
- springfox 源码分析(三) 初探 Spring Plugin 插件系统
- springfox 源码分析(四) 配置类初始化
- springfox 源码分析(五) Web 配置类 Plugin 插件的使用
- springfox 源码分析(六) Web 配置类扫描包作用探索
- springfox 源码分析(七) 文档初始化
- springfox 源码分析(八) 遍历接口获取 Model 对象
- springfox 源码分析(九) 文档初始化分组
- springfox 源码分析(十) 遍历接口获取 Model 对象
- springfox 源码分析(十一) 自定义添加 Swagger Models 功能实现
- springfox 源码分析(十二) 遍历接口获取 ApiDescription 集合
- springfox 源码分析(十三) 自定义扩展实现接口的排序
- springfox 源码分析(十四) 归档得到 ApiListing 接口集合
- springfox 源码分析(十五) 归档得到 Documentation 文档对象
- springfox 源码分析(十六) 分组接口 swagger-resouces
- springfox 源码分析(十七) Swagger2 接口文档示例接口 api-docs
- springfox 源码分析(十八) 自定义扩展实现分组的排序
- springfox 源码分析(十九) guava 库学习
- springfox 源码分析(二十一) 忽略参数 Class 类型
文章来源于网络收集而来,版权归原创者所有,如有侵权请及时联系!
springfox 源码分析(十二) 遍历接口获取 ApiDescription 集合
ApiDescription是springfox提供的接口描述信息类,在springfox 源码分析(十) 遍历接口获取Model对象中我们拿到了接口的类型Model集合信息,但除了Model信息,接口还有更多的信息
基础信息
主要包括:接口路径、consumes、produces、参数、请求类型、描述、说明、响应状态码、是否过时、扩展信息、分组
因为我们的接口可以运行多个请求类型的存在,所以以上信息在springfox是通过 Operation
来声明的
先来看 ApiDescription
的源码
public class ApiDescription {
//分组名称
private final String groupName;
//路径
private final String path;
//描述
private final String description;
//操作信息集合
//一个接口有可能存在多个请求方法类型,即:GET、POST、PUT、DELETE等,所以这里也是1:N的映射关系
private final List<Operation> operations;
//是否隐藏
private final Boolean hidden;
//getter and setters....
}
在代码注释中,我也做了说明
因为一个接口有可能存在多个请求方法类型,即:GET、POST、PUT、DELETE等,所以这里也是1:N的映射关系,即存在多个Operation集合
Operation的属性
public class Operation {
//请求接口
private final HttpMethod method;
//接口名称
private final String summary;
//接口描述信息
private final String notes;
private final ModelReference responseModel;
//唯一id
private final String uniqueId;
private final int position;
//tags
private final Set<String> tags;
private final Set<String> produces;
private final Set<String> consumes;
private final Set<String> protocol;
//是否隐藏
private final boolean isHidden;
private final Map<String, List<AuthorizationScope>> securityReferences;
//参数
private final List<Parameter> parameters;
//状态码
private final Set<ResponseMessage> responseMessages;
//是否过时
private final String deprecated;
//扩展信息
private final List<VendorExtension> vendorExtensions;
//setter and getter..
}
在Operation中声明的属性中就是我们上面介绍的接口相关信息.
初始化
我们知道了接口的介绍信息,此时,来看springfox如何处理,将接口的上下文信息最终初始化转换为ApiDescription
ApiDescriptionReader.read
方法
/***
* 获取ApiDescription接口集合信息
* @param outerContext
* @return
*/
public List<ApiDescription> read(RequestMappingContext outerContext) {
PatternsRequestCondition patternsCondition = outerContext.getPatternsCondition();
ApiSelector selector = outerContext.getDocumentationContext().getApiSelector();
List<ApiDescription> apiDescriptionList = newArrayList();
for (String path : matchingPaths(selector, patternsCondition)) {
String methodName = outerContext.getName();
try {
RequestMappingContext operationContext = outerContext.copyPatternUsing(path);
//根据接口上下文获取Operation集合
List<Operation> operations = operationReader.read(operationContext);
if (operations.size() > 0) {
operationContext.apiDescriptionBuilder()
.groupName(outerContext.getGroupName())
.operations(operations)
.pathDecorator(pluginsManager.decorator(new PathContext(outerContext, from(operations).first())))
.path(path)
.description(methodName)
.hidden(false);
ApiDescription apiDescription = operationContext.apiDescriptionBuilder().build();
lookup.add(outerContext.key(), apiDescription);
apiDescriptionList.add(apiDescription);
}
} catch (Error e) {
String contentMsg = "Skipping process path[" + path + "], method[" + methodName + "] as it has an error.";
log.error(contentMsg, e);
}
}
return apiDescriptionList;
}
核心操作是通过operationReader.read操作,获取Operation集合
public List<Operation> read(RequestMappingContext outerContext) {
List<Operation> operations = newArrayList();
Set<RequestMethod> requestMethods = outerContext.getMethodsCondition();
Set<RequestMethod> supportedMethods = supportedMethods(requestMethods);
//Setup response message list
Integer currentCount = 0;
//遍历获取当前支持的接口类型
for (RequestMethod httpRequestMethod : supportedMethods) {
OperationContext operationContext = new OperationContext(new OperationBuilder(nameGenerator),
httpRequestMethod,
outerContext,
currentCount);
//调用OperationPlugin插件,构造Operation对象
Operation operation = pluginsManager.operation(operationContext);
//添加
if (!operation.isHidden()) {
operations.add(operation);
currentCount++;
}
}
Collections.sort(operations, outerContext.operationOrdering());
return operations;
}
主要的逻辑如下:
- 获取当前支持的接口类型,包括GET|POST、PUT、DELETE等
- 通过调用OperationPlugin的插件对Operation中的每个属性进行赋值操作,包括参数类型、描述、响应状态码等等信息
OperationPlugin插件包含了多个实现类型,这个可以参考前面介绍的springfox 源码分析(五) web配置类Plugin插件的使用
既然Operation提供了扩展参数,那么我们后面是可以进行添加自定义扩展的
下一篇会介绍如何添加springfox的接口扩展字段.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论