文档
- 快速开始
- 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 源码分析(十八) 自定义扩展实现分组的排序
既然我们对springfox提供的接口已经有了一个初步的了解,那么针对我们在分组接口文章中提的需求,如果自定义扩展实现分组的排序如何做呢?
在swagger-bootstrap-ui以前的版本中,已经存在了增强功能,增强功能主要的方式是重写了springfox的接口,然后在我们自定义的ui中渲染即可.
因为 SwaggerResource.java
中没有提供排序的字段属性,所以我们可以扩展该类,提供一个排序字段
/***
*
* @since:swagger-bootstrap-ui 1.9.4
* @author <a href="mailto:xiaoymin@foxmail.com">xiaoymin@foxmail.com</a>
* 2019/06/02 16:24
*/
public class SwaggerResourceExt extends SwaggerResource {
private Integer order;
public Integer getOrder() {
return order;
}
public void setOrder(Integer order) {
this.order = order;
}
}
很简单,提供一个order属性,该类继承自springfox的 SwaggerResource
扩展了基础属性类,那么我们提供的方式也需要进行扩展
@Component
@Qualifier("swaggerResourcesExtProvider")
public class SwaggerResourcesExtProvider {
private final String swagger1Url;
private final String swagger2Url;
@VisibleForTesting
boolean swagger1Available;
@VisibleForTesting
boolean swagger2Available;
private final DocumentationCache documentationCache;
@Autowired
public SwaggerResourcesExtProvider(Environment environment, DocumentationCache documentationCache) {
swagger1Url = environment.getProperty("springfox.documentation.swagger.v1.path", "/api-docs-ext");
swagger2Url = environment.getProperty("springfox.documentation.swagger.v2.path", "/v2/api-docs-ext");
swagger1Available = classByName("springfox.documentation.swagger1.web.Swagger1Controller").isPresent();
swagger2Available = classByName("springfox.documentation.swagger2.web.Swagger2Controller").isPresent();
this.documentationCache = documentationCache;
}
public List<SwaggerResourceExt> get() {
List<SwaggerResourceExt> resources = new ArrayList<SwaggerResourceExt>();
for (Map.Entry<String, Documentation> entry : documentationCache.all().entrySet()) {
String swaggerGroup = entry.getKey();
Documentation documentation=entry.getValue();
List<VendorExtension> vendorExtensions=documentation.getVendorExtensions();
if (swagger1Available) {
SwaggerResourceExt swaggerResource = resource(swaggerGroup, swagger1Url,vendorExtensions);
swaggerResource.setSwaggerVersion("1.2");
}
if (swagger2Available) {
SwaggerResourceExt swaggerResource = resource(swaggerGroup, swagger2Url,vendorExtensions);
swaggerResource.setSwaggerVersion("2.0");
resources.add(swaggerResource);
}
}
//根据自定义扩展属性order进行排序
Collections.sort(resources, new Comparator<SwaggerResourceExt>() {
@Override
public int compare(SwaggerResourceExt o1, SwaggerResourceExt o2) {
return o1.getOrder().compareTo(o2.getOrder());
}
});
return resources;
}
private SwaggerResourceExt resource(String swaggerGroup, String baseUrl,List<VendorExtension> vendorExtensions) {
SwaggerResourceExt swaggerResource = new SwaggerResourceExt();
swaggerResource.setName(swaggerGroup);
swaggerResource.setUrl(swaggerLocation(baseUrl, swaggerGroup));
swaggerResource.setOrder(0);
//判断是否不为空
if (vendorExtensions!=null&&!vendorExtensions.isEmpty()){
Optional<VendorExtension> ov= FluentIterable.from(vendorExtensions).filter(new Predicate<VendorExtension>() {
@Override
public boolean apply(VendorExtension input) {
return input.getClass().isAssignableFrom(OrderExtensions.class);
}
}).first();
if (ov.isPresent()){
OrderExtensions orderExtensions=(OrderExtensions) ov.get();
swaggerResource.setOrder(orderExtensions.getValue());
}
}
return swaggerResource;
}
private String swaggerLocation(String swaggerUrl, String swaggerGroup) {
String base = Optional.of(swaggerUrl).get();
if (Docket.DEFAULT_GROUP_NAME.equals(swaggerGroup)) {
return base;
}
return base + "?group=" + swaggerGroup;
}
}
针对原springfox的方式进行扩展,主要逻辑
- 首先获取Documentation的Map集合对象,进行遍历
- 我们的接口参数是需要从外部由开发者自定义的传入的,那么此时我们可以利用Docket对象提供的扩展属性集合来操作,
swagger-bootstrap-ui
提供了OrderExtensions
扩展,开发者创建Docket对象时进行参数传入即可 - 筛选Documentation的扩展属性集合,找到符合规范的扩展,如果未找到则默认排序值为0
重写了获取 SwaggerResource
集合的工具类,接下来重写接口层
@ApiIgnore
@Controller
@RequestMapping("/swagger-resources-ext")
public class SwaggerBootstrapUiResourceExtController {
private final SwaggerResourcesExtProvider swaggerResourcesExtProvider;
@Autowired
public SwaggerBootstrapUiResourceExtController(@Qualifier("swaggerResourcesExtProvider") SwaggerResourcesExtProvider swaggerResources) {
this.swaggerResourcesExtProvider = swaggerResources;
}
@RequestMapping
@ResponseBody
public ResponseEntity<List<SwaggerResourceExt>> swaggerResources() {
return new ResponseEntity<List<SwaggerResourceExt>>(swaggerResourcesExtProvider.get(), HttpStatus.OK);
}
}
此时,提供一个类似springfox的分组接口,通过工具类提供,获取拿到分组信息
有了以上的扩展实现,我们SwaggerConfiguration配置文件创建Docket对象时需要稍微做一个改动
@Bean(value = "defaultApi")
public Docket defaultApi() {
ParameterBuilder parameterBuilder=new ParameterBuilder();
List<Parameter> parameters= Lists.newArrayList();
parameterBuilder.name("token").description("token令牌").modelRef(new ModelRef("String"))
.parameterType("header")
.required(true).build();
parameters.add(parameterBuilder.build());
Docket docket=new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.groupName("默认接口")
.select()
.apis(RequestHandlerSelectors.basePackage("com.swagger.bootstrap.ui.demo.controller"))
//.apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))
.paths(PathSelectors.any())
.build()
//添加扩展
.extensions(Lists.newArrayList(new OrderExtensions(1)))
.globalOperationParameters(parameters)
.securityContexts(Lists.newArrayList(securityContext())).securitySchemes(Lists.<SecurityScheme>newArrayList(apiKey()));
return docket;
}
此时,我们使用extensions方法添加扩展,赋值OrderExtensions的排序order值
此时我们访问接口 /swagger-resoueces-ext
返回:
[
{
"order": 1,
"name": "默认接口",
"url": "/v2/api-docs-ext?group=默认接口",
"swaggerVersion": "2.0",
"location": "/v2/api-docs-ext?group=默认接口"
},
{
"order": 2,
"name": "分组接口",
"url": "/v2/api-docs-ext?group=分组接口",
"swaggerVersion": "2.0",
"location": "/v2/api-docs-ext?group=分组接口"
}
]
此时,我们在Ui端就可以自定义接口分组的排序了
以上功能在 swagger-bootstrap-ui
1.9.4版本已经实现,开发者如果有排序的需求,可以使用此方法.
注意:在使用此功能时,需要在Swagger的配置文件类上加上 @EnableSwaggerBootstrapUI
注解
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论