Spring Boot 2.x基础教程:Swagger接口分类与各元素排序问题详解
之前通过Spring Boot 2.x基础教程:使用Swagger2构建强大的API文档一文,我们学习了如何使用Swagger为Spring Boot项目自动生成API文档,有不少用户留言问了关于文档内容的组织以及排序问题。所以,就特别开一篇详细说说Swagger中文档内容如何来组织以及其中各个元素如何控制前后顺序的具体配置方法。
接口的分组
我们在Spring Boot中定义各个接口是以Controller
作为第一级维度来进行组织的,Controller
与具体接口之间的关系是一对多的关系。我们可以将同属一个模块的接口定义在一个Controller
里。默认情况下,Swagger是以Controller
为单位,对接口进行分组管理的。这个分组的元素在Swagger中称为Tag
,但是这里的Tag
与接口的关系并不是一对多的,它支持更丰富的多对多关系。
默认分组
首先,我们通过一个简单的例子,来看一下默认情况,Swagger是如何根据Controller来组织Tag与接口关系的。定义两个Controller
,分别负责教师管理与学生管理接口,比如下面这样:
@RestController @RequestMapping(value = "/teacher") static class TeacherController { @GetMapping("/xxx") public String xxx() { return "xxx"; } } @RestController @RequestMapping(value = "/student") static class StudentController { @ApiOperation("获取学生清单") @GetMapping("/list") public String bbb() { return "bbb"; } @ApiOperation("获取教某个学生的老师清单") @GetMapping("/his-teachers") public String ccc() { return "ccc"; } @ApiOperation("创建一个学生") @PostMapping("/aaa") public String aaa() { return "aaa"; } }
启动应用之后,我们可以看到Swagger中这两个Controller是这样组织的:
图中标出了Swagger默认生成的Tag
与Spring Boot中Controller
展示的内容与位置。
自定义默认分组的名称
接着,我们可以再试一下,通过@Api
注解来自定义Tag
,比如这样:
@Api(tags = "教师管理") @RestController @RequestMapping(value = "/teacher") static class TeacherController { // ... } @Api(tags = "学生管理") @RestController @RequestMapping(value = "/student") static class StudentController { // ... }
再次启动应用之后,我们就看到了如下的分组内容,代码中@Api
定义的tags
内容替代了默认产生的teacher-controller
和student-controller
。
合并Controller分组
到这里,我们还都只是使用了Tag
与Controller
一一对应的情况,Swagger中还支持更灵活的分组!从@Api
注解的属性中,相信聪明的读者一定已经发现tags
属性其实是个数组类型:
我们可以通过定义同名的Tag
来汇总Controller
中的接口,比如我们可以定义一个Tag
为“教学管理”,让这个分组同时包含教师管理和学生管理的所有接口,可以这样来实现:
@Api(tags = {"教师管理", "教学管理"}) @RestController @RequestMapping(value = "/teacher") static class TeacherController { // ... } @Api(tags = {"学生管理", "教学管理"}) @RestController @RequestMapping(value = "/student") static class StudentController { // ... }
最终效果如下:
更细粒度的接口分组
通过@Api
可以实现将Controller
中的接口合并到一个Tag
中,但是如果我们希望精确到某个接口的合并呢?比如这样的需求:“教学管理”包含“教师管理”中所有接口以及“学生管理”管理中的“获取学生清单”接口(不是全部接口)。
那么上面的实现方式就无法满足了。这时候发,我们可以通过使用@ApiOperation
注解中的tags
属性做更细粒度的接口分类定义,比如上面的需求就可以这样子写:
@Api(tags = {"教师管理","教学管理"}) @RestController @RequestMapping(value = "/teacher") static class TeacherController { @ApiOperation(value = "xxx") @GetMapping("/xxx") public String xxx() { return "xxx"; } } @Api(tags = {"学生管理"}) @RestController @RequestMapping(value = "/student") static class StudentController { @ApiOperation(value = "获取学生清单", tags = "教学管理") @GetMapping("/list") public String bbb() { return "bbb"; } @ApiOperation("获取教某个学生的老师清单") @GetMapping("/his-teachers") public String ccc() { return "ccc"; } @ApiOperation("创建一个学生") @PostMapping("/aaa") public String aaa() { return "aaa"; } }
效果如下图所示:
内容的顺序
在完成了接口分组之后,对于接口内容的展现顺序又是众多用户特别关注的点,其中主要涉及三个方面:分组的排序、接口的排序以及参数的排序,下面我们就来逐个说说如何配置与使用。
分组的排序
关于分组排序,也就是Tag的排序。目前版本的Swagger支持并不太好,通过文档我们可以找到关于Tag排序的配置方法。
第一种:原生Swagger用户,可以通过如下方式:
第二种:Swagger Starter用户,可以通过修改配置的方式:
swagger.ui-config.tags-sorter=alpha
似乎找到了希望,但是其实这块并没有什么可选项,一看源码便知:
public enum TagsSorter { ALPHA("alpha"); private final String value; TagsSorter(String value) { this.value = value; } @JsonValue public String getValue() { return value; } public static TagsSorter of(String name) { for (TagsSorter tagsSorter : TagsSorter.values()) { if (tagsSorter.value.equals(name)) { return tagsSorter; } } return null; } }
是的,Swagger只提供了一个选项,就是按字母顺序排列。那么我们要如何实现排序呢?这里笔者给一个不需要扩展源码,仅依靠使用方式的定义来实现排序的建议:为Tag的命名做编号。比如:
@Api(tags = {"1-教师管理","3-教学管理"}) @RestController @RequestMapping(value = "/teacher") static class TeacherController { // ... } @Api(tags = {"2-学生管理"}) @RestController @RequestMapping(value = "/student") static class StudentController { @ApiOperation(value = "获取学生清单", tags = "3-教学管理") @GetMapping("/list") public String bbb() { return "bbb"; } // ... }
由于原本存在按字母排序的机制在,通过命名中增加数字来帮助排序,可以简单而粗暴的解决分组问题,最后效果如下:
接口的排序
在完成了分组排序问题(虽然不太优雅...)之后,在来看看同一分组内各个接口该如何实现排序。同样的,凡事先查文档,可以看到Swagger也提供了相应的配置,下面也分两种配置方式介绍:
第一种:原生Swagger用户,可以通过如下方式:
第二种:Swagger Starter用户,可以通过修改配置的方式:
swagger.ui-config.operations-sorter=alpha
很庆幸,这个配置不像Tag的排序配置没有可选项。它提供了两个配置项:alpha
和method
,分别代表了按字母表排序以及按方法定义顺序排序。当我们不配置的时候,改配置默认为alpha
。两种配置的效果对比如下图所示:
参数的排序
完成了接口的排序之后,更细粒度的就是请求参数的排序了。默认情况下,Swagger对Model参数内容的展现也是按字母顺序排列的。所以之前教程中的User对象在文章中展现如下:
如果我们希望可以按照Model中定义的成员变量顺序来展现,那么需要我们通过@ApiModelProperty
注解的position
参数来实现位置的设置,比如:
@Data @ApiModel(description = "用户实体") public class User { @ApiModelProperty(value = "用户编号", position = 1) private Long id; @NotNull @Size(min = 2, max = 5) @ApiModelProperty(value = "用户姓名", position = 2) private String name; @NotNull @Max(100) @Min(10) @ApiModelProperty(value = "用户年龄", position = 3) private Integer age; @NotNull @Email @ApiModelProperty(value = "用户邮箱", position = 4) private String email; }
最终效果如下:
小结
本文详细的介绍了Swagger中对接口内容的组织控制。有些问题并没有通过配置来解决,也可能是对文档或源码内容的了解不够深入。如果读者有更好的实现方案,欢迎提出与交流。
代码示例
本文的完整工程可以查看下面仓库中的chapter2-4
目录:
- Github:https://github.com/dyc87112/SpringBoot-Learning/tree/2.x
- Gitee:https://gitee.com/didispace/SpringBoot-Learning/tree/2.x
如果您觉得本文不错,欢迎Star支持,您的关注是我坚持的动力!
相关资料
- https://swagger.io/docs/
- http://blog.didispace.com/spring-boot-learning-21-2-2/
- https://github.com/SpringForAll/spring-boot-starter-swagger
> 欢迎关注我的公众号:程序猿DD,获得独家整理的学习资源和日常干货推送。 > 如果您对我的专题内容感兴趣,也可以关注我的博客:didispace.com

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
死磕 java线程系列之自己动手写一个线程池
(手机横屏看源码更方便) 问题 (1)自己动手写一个线程池需要考虑哪些因素? (2)自己动手写的线程池如何测试? 简介 线程池是Java并发编程中经常使用到的技术,那么自己如何动手写一个线程池呢?本文彤哥将手把手带你写一个可用的线程池。 属性分析 线程池,顾名思义它首先是一个“池”,这个池里面放的是线程,线程是用来执行任务的。 首先,线程池中的线程应该是有类别的,有的是核心线程,有的是非核心线程,所以我们需要两个变量标识核心线程数量coreSize和最大线程数量maxSize。 为什么要区分是否为核心线程呢?这是为了控制系统中线程的数量。 当线程池中线程数未达到核心线程数coreSize时,来一个任务加一个线程是可以的,也可以提高任务执行的效率。 当线程池中线程数达到核心线程数后,得控制一下线程的数量,来任务了先进队列,如果任务执行足够快,这些核心线程很快就能把队列中的任务执行完毕,完全没有新增线程的必要。 当队列中任务也满了,这时候光靠核心线程就无法及时处理任务了,所以这时候就需要增加新的线程了,但是线程也不能无限制地增加,所以需要控制其最大线程数量maxSize。 其次,我们需要一...
- 下一篇
数据模型之版本管理
转载本文需注明出处:微信公众号EAWorld,违者必究。 引言: 主数据是描述企业核心数据、业务对象,当记录到数据库中时,需要对其进行维护,确保其时效性、准确性。数据模型管理是重要的环节,在实施主数据模型版本管理项目中用树节点挂载的方式,建立不同的数据类型树,在树节点下挂载数据类型、模型、版本,在每个版本下配置字段、展现方式等信息,并且可增加编码配置关系,在应用数据的时候可以灵活使用和展现数据。有效地解决了地产等行业的需求,提高数据处理效率和使用价值。 目录: 1. 数据模型版本管理使用方案介绍 2. 模型版本管理数据关系结构 3. 模型版本管理下的主数据 1.数据模型管理使用方案介绍 对于数据开发项目,我们常常会面临众多的数据对接,部分场景不仅数据量大,且数据种类多,数据解析开发工作量巨大。对于主数据模型版本管理,一般是使用是树节点挂载的方式,建立不同的数据类型树,在相应的树节点下挂载相应的数据类型、模型、版本和数据,在每个版本下需要配置相应的字段、展现方式等信息,并且可以增加一些编码配置关系,在应用数据的时候可 以灵活的使用和展现数据。 数据模型版本管理分为四部分: 第一部分是数据...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- SpringBoot2全家桶,快速入门学习开发网站教程
- CentOS8编译安装MySQL8.0.19
- CentOS8,CentOS7,CentOS6编译安装Redis5.0.7
- SpringBoot2整合Thymeleaf,官方推荐html解决方案
- CentOS8安装Docker,最新的服务器搭配容器使用
- CentOS7安装Docker,走上虚拟化容器引擎之路
- CentOS7,CentOS8安装Elasticsearch6.8.6
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- CentOS8安装MyCat,轻松搞定数据库的读写分离、垂直分库、水平分库
- Windows10,CentOS7,CentOS8安装MongoDB4.0.16