文档
- 快速开始
- 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 源码分析(十一) 自定义添加 Swagger Models 功能实现
在springfox 源码分析(十) 遍历接口获取Model对象这一篇中,我们其实已经大致了解了Springfox针对接口中涉及到的Model类进行解析初始化的过程
在默认 OperationModelsProviderPlugin
插件中, collectGlobalModels
收集全局Models的方法会将我们外部传入的Model添加到Springfox的集合中去,并且最终我们会在Swagger的标准属性定义definitions中发现她
那么我们既然知道了springfox的原理,我们知道springfox默认只会把接口中涉及的参数类、返回类、注解中定义的类这三类model添加到框架中
有时,如果我们在程序框架中定义了一些公共的属性Models,但是并没有在接口中使用,此时springfox默认是不会加入的,那么我们应该通过何种方式,才能再swagger的ui界面中看到后端自定义的Model呢
我们通过源码环节知道 OperationModelsProviderPlugin
最终获取全局参数Models是通过 DocumentationContext
对象来获取的,而在springfox 源码分析(七) 文档初始化-DocumentationContext这一节时,我们已经介绍了 DocumentationContext
的初始化过程
我们只需要使用springfox为我们提供的Docket对象的方法就可以实现我们的自定义Models
目前Docket对象提供了添加Model的方法,源码如下:
/**
* Method to add additional models that are not part of any annotation or are perhaps implicit
*
* @param first - at least one is required
* @param remaining - possible collection of more
* @return on-going docket
* @since 2.4.0
*/
public Docket additionalModels(ResolvedType first, ResolvedType... remaining) {
additionalModels.add(first);
additionalModels.addAll(newHashSet(remaining));
return this;
}
这是唯一的方法入口, ResolvedType
是springfox默认使用的jackson提供的类,他是一个静态类
那么,我们如何将Type类型转化为 ResolvedType
类型
jackson也提供了一个类来进行转换,那就是 com.fasterxml.classmate.TypeResolver
并且该类springfox已经帮助我们注入到了Spring的容器中,具体代码如下:
@Configuration
@ComponentScan(basePackages = {
"springfox.documentation.schema"
})
@EnablePluginRegistries({
ModelBuilderPlugin.class,
ModelPropertyBuilderPlugin.class,
TypeNameProviderPlugin.class,
SyntheticModelProviderPlugin.class
})
public class ModelsConfiguration {
@Bean
public TypeResolver typeResolver() {
return new TypeResolver();
}
}
所以,在我们的SwaggerConfiguration配置文件中,只需要将TypeResolver通过注解注入即可使用了
第一种方式
在SwaggerConfiguration中引入TypeResolver
@EnableSwagger2
@EnableSwaggerBootstrapUI
@Import(BeanValidatorPluginsConfiguration.class)
public class SwaggerConfiguration {
private final TypeResolver typeResolver;
@Autowired
public SwaggerConfiguration(TypeResolver typeResolver) {
this.typeResolver = typeResolver;
}
在创建Docket对象时,调用additionalModels的方法,代码如下:
@Bean(value = "groupRestApi")
@Order(value = 1)
public Docket groupRestApi() {
List<ResolvedType> list=Lists.newArrayList();
SpringAddtionalModel springAddtionalModel= springAddtionalModelService.scan("com.swagger.bootstrap.ui.demo.extend");
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(groupApiInfo())
.groupName("分组接口")
.select()
.apis(RequestHandlerSelectors.basePackage("com.swagger.bootstrap.ui.demo.group"))
.paths(PathSelectors.any())
.build()
//添加自定义Model类型
.additionalModels(typeResolver.resolve(DeveloperApiInfo.class))
.ignoredParameterTypes(HttpSession.class).extensions(Lists.newArrayList(new OrderExtensions(2))).securityContexts(Lists.newArrayList(securityContext(),securityContext1())).securitySchemes(Lists.<SecurityScheme>newArrayList(apiKey(),apiKey1()));
}
这样我们在界面上就可以看见我们默认添加的Model了,效果:
如果我们只是需要添加一个类的情况下,使用这种方式是最简洁的,假如我们有很多类的情况下,我们希望能够提供根据路径包扫描的方式来获取 ResolvedType
,那该如何做呢?
此时,你可以使用第二种方式
第二种方式
在swagger-bootstrap-ui的1.9.4版本中,为Java开发者提供了公共api方法
在SwaggerConfiguration配置文件中,可以引入swagger-bootstrap-ui提供的工具类
@Configuration
@EnableSwagger2
@EnableSwaggerBootstrapUI
@Import(BeanValidatorPluginsConfiguration.class)
public class SwaggerConfiguration {
@Autowired
SpringAddtionalModelService springAddtionalModelService;
}
注意: @EnableSwaggerBootstrapUI
注解必须在配置类上引入,否则可能引起错误.
然后使用 springAddtionalModelService
提供的scan方法进行包路径扫描,包路径可以是多个,以逗号分隔
@Bean(value = "groupRestApi")
@Order(value = 1)
public Docket groupRestApi() {
List<ResolvedType> list=Lists.newArrayList();
//扫描
SpringAddtionalModel springAddtionalModel= springAddtionalModelService.scan("com.swagger.bootstrap.ui.demo.extend");
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(groupApiInfo())
.groupName("分组接口")
.select()
.apis(RequestHandlerSelectors.basePackage("com.swagger.bootstrap.ui.demo.group"))
.paths(PathSelectors.any())
.build()
.additionalModels(springAddtionalModel.getFirst(),springAddtionalModel.getRemaining())
.ignoredParameterTypes(HttpSession.class).extensions(Lists.newArrayList(new OrderExtensions(2))).securityContexts(Lists.newArrayList(securityContext(),securityContext1())).securitySchemes(Lists.<SecurityScheme>newArrayList(apiKey(),apiKey1()));
}
springAddtionalModelService最终扫描包路径生成 SpringAddtionalModel
对象,该对象源码:
public class SpringAddtionalModel {
/***
* 第一个Type
*/
private ResolvedType first;
/***
* 剩余
*/
private List<ResolvedType> remaining=new ArrayList<>();
public ResolvedType[] getRemaining() {
if (!remaining.isEmpty()){
return remaining.toArray(new ResolvedType[]{});
}
return new ResolvedType[]{};
}
public ResolvedType getFirst() {
return first;
}
public void setFirst(ResolvedType first) {
this.first = first;
}
public void add(ResolvedType type){
remaining.add(type);
}
}
注意有两个属性,first和remaining的集合
这也是配合Docket对象提供的additionalModels方法进行的简单封装,开发者扫描包路径后,会得到first以及remaining的集合
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论