在上一篇中我们完成使用JSR-303校验,以及利用Swagger2得到相关接口文档,这节,我们在原先的基础之上,完成Swagger中关于对各个元素之间控制前后顺序的具体配置方法。
首先我们需要对Swagger中的接口也就是以Controller 层作为第一级梯度进行组织的,Controller在我们实际开发中,与其他具体接口之间是存在一对多的关系,我们可以将同属一个模块的接口定义在一个Controller 中,默认情况之下,我们的Swagger 是以Controller为单位,对接口进行分组管理,在Swagger 中,这个分组的元素被称为Tag,但是这里的Tag与接口的关系并不是一对多关系,它支持更加丰富的多对多的关系,
首先通过创建一个简单的例子进,来看一下,我们是如何处理Swagger是如如何根据Controller来组织Tag与接口关系的,定义两个Controller,分别负责教师管理与学生管理接口,为了重复利用代码,我们就在上一篇的基础之上进行代码添加了:
为了简单明了,我均将下列代码放在Application类里边
@RestController @RequestMapping(value = "/teacher") static class TeacherController { @GetMapping("/miaow") public String miaow() { return "miaow"; } } @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"; } }
此时通过:localhost:8080/swagger-ui.html 访问得到我们Swagger的组织结构是
在上图中我们了解到我们定义的控制层,得到的swagger生成的默认结构展示出来了。
application.properties文件
swagger.title=spring-boot-starter-swagger swagger.description=Starter for swagger 2.x swagger.version=1.9.0.RELEASE swagger.license=Apache License, Version 2.0 swagger.licenseUrl=https://www.apache.org/licenses/LICENSE-2.0.html swagger.termsOfServiceUrl=https://github.com/dyc87112/spring-boot-starter-swagger swagger.contact.name=miaow swagger.contact.url=https://luoxiaohei520.github.io swagger.contact.email=miaow@qq.com swagger.base-package=com.didispace swagger.base-path=/** swagger.ui-config.tags-sorter=alpha swagger.ui-config.operations-sorter=alpha
在启动类添加相关控制层接口:
@EnableSwagger2Doc @SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } @Api(tags = {"1-教师管理","3-教学管理"}) @RestController @RequestMapping(value = "/teacher") static class TeacherController { @ApiOperation(value = "miaow") @GetMapping("/miaow") public String miaow() { return "miaow"; } } @Api(tags = {"2-学生管理"}) @RestController @RequestMapping(value = "/student") static class StudentController { @ApiOperation(value = "获取学生清单", tags = "3-教学管理") @GetMapping("/list") public String bbb() { return "bbb"; } @ApiOperation("获取教某个学生的老师清单") @GetMapping("/his-teachers") public String ccc() { return "ccc"; } @ApiOperation("创建一个学生") @PostMapping("/aaa") public String aaa() { return "aaa"; } } }
得到结果集
@Api(tags = "教师管理") @RestController @RequestMapping(value = "/teacher") static class TeacherController { // ... } @Api(tags = "学生管理") @RestController @RequestMapping(value = "/student") static class StudentController { // ... }
我们在Api的tags修改成为我们想要的表达文字:
在此,我们使用了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中,但是如果我们希望精确到某个接口的合并,我们应该如何做?
@Api(tags = {"教师管理","教学管理"}) @RestController @RequestMapping(value = "/teacher") static class TeacherController { @ApiOperation(value = "maiow") @GetMapping("/miaow") public String miaow() { return "miaow"; } } @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 提供考虑一个选项,就是按照字字母顺序进行排序。
@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在Swagger之前是这样的:
现在,我们希望可以按照Model中定义的成员变量顺序来展示,那么需要我们通过@ApiModelProperty 注解的position参数来实现位置的设置。
对应的User对象如下:
w未加
@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; public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public User(Long id, String name, Integer age, String email) { this.id = id; this.name = name; this.age = age; this.email = email; } public User() { } }
加了Position之后的swagger展示: