Swagger
Swagger
随着前后端分离架构和微服务架构的流行,我们使用
- 由于接口众多,并且细节复杂(需要考虑不同的
HTTP 请求类型、HTTP 头部信息、HTTP 请求内容等) ,高质量地创建这份文档本身就是件非常吃力的事,下游的抱怨声不绝于耳。 - 随着时间推移,不断修改接口实现的时候都必须同步修改接口文档,而文档与代码又处于两个不同的媒介,除非有严格的管理机制,不然很容易导致不一致现象。
为了解决上面这样的问题,本文将介绍
首先添加
<dependency>
<groupId>com.spring4all</groupId>
<artifactId>swagger-spring-boot-starter</artifactId>
<version>1.9.0.RELEASE</version>
</dependency>
应用主类中添加
@EnableSwagger2Doc
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
swagger.title=spring-boot-starter-swagger
swagger.description=Starter for swagger 2.x
swagger.version=1.4.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=didi
swagger.contact.url=http://blog.didispace.com
swagger.contact.email=dyc87112@qq.com
swagger.base-package=com.didispace
swagger.base-path=/**
各参数配置含义如下:
swagger.title
:标题swagger.description
:描述swagger.version
:版本swagger.license
:许可证swagger.licenseUrl
:许可证URL swagger.termsOfServiceUrl
:服务条款URL swagger.contact.name
:维护人swagger.contact.url
:维护人URL swagger.contact.email
:维护人email swagger.base-package
:swagger 扫描的基础包,默认:全扫描swagger.base-path
:需要处理的基础URL 规则,默认:/**
添加文档内容
在整合完
@Api(tags = "用户管理")
@RestController
@RequestMapping(value = "/users") // 通过这里配置使下面的映射都在/users下
public class UserController {
// 创建线程安全的Map,模拟users信息的存储
static Map<Long, User> users = Collections.synchronizedMap(new HashMap<>());
@GetMapping("/")
@ApiOperation(value = "获取用户列表")
public List<User> getUserList() {
List<User> r = new ArrayList<>(users.values());
return r;
}
@PostMapping("/")
@ApiOperation(value = "创建用户", notes = "根据User对象创建用户")
public String postUser(@RequestBody User user) {
users.put(user.getId(), user);
return "success";
}
@GetMapping("/{id}")
@ApiOperation(value = "获取用户详细信息", notes = "根据url的id来获取用户详细信息")
public User getUser(@PathVariable Long id) {
return users.get(id);
}
@PutMapping("/{id}")
@ApiImplicitParam(paramType = "path", dataType = "Long", name = "id", value = "用户编号", required = true, example = "1")
@ApiOperation(value = "更新用户详细信息", notes = "根据url的id来指定更新对象,并根据传过来的user信息来更新用户详细信息")
public String putUser(@PathVariable Long id, @RequestBody User user) {
User u = users.get(id);
u.setName(user.getName());
u.setAge(user.getAge());
users.put(id, u);
return "success";
}
@DeleteMapping("/{id}")
@ApiOperation(value = "删除用户", notes = "根据url的id来指定删除对象")
public String deleteUser(@PathVariable Long id) {
users.remove(id);
return "success";
}
}
@Data
@ApiModel(description="用户实体")
public class User {
@ApiModelProperty("用户编号")
private Long id;
@ApiModelProperty("用户姓名")
private String name;
@ApiModelProperty("用户年龄")
private Integer age;
}
接口分组
我们在
默认分组
首先,我们通过一个简单的例子,来看一下默认情况,
@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";
}
}
启动应用之后,我们可以看到

图中标出了
自定义默认分组的名称
接着,我们可以再试一下,通过
@Api(tags = "教师管理")
@RestController
@RequestMapping(value = "/teacher")
static class TeacherController {
// ...
}
@Api(tags = "学生管理")
@RestController
@RequestMapping(value = "/student")
static class StudentController {
// ...
}
再次启动应用之后,我们就看到了如下的分组内容,代码中

合并Controller 分组
到这里,我们还都只是使用了
@Api(tags = {"教师管理", "教学管理"})
@RestController
@RequestMapping(value = "/teacher")
static class TeacherController {
// ...
}
@Api(tags = {"学生管理", "教学管理"})
@RestController
@RequestMapping(value = "/student")
static class StudentController {
// ...
}
最终效果如下:

更细粒度的接口分组
通过
@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";
}
}
效果如下图所示:

内容的顺序
在完成了接口分组之后,对于接口内容的展现顺序又是众多用户特别关注的点,其中主要涉及三个方面:分组的排序、接口的排序以及参数的排序,下面我们就来逐个说说如何配置与使用。
分组的排序
关于分组排序,也就是
@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.ui-config.operations-sorter=alpha
参数的排序
完成了接口的排序之后,更细粒度的就是请求参数的排序了。默认情况下,
@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;
}