如何构建一份合理高效的接口文档很重要,Swagger的出现可以完美解决了传统接口管理方式存在的痛点。以下介绍Spring Boot整合Swagger2的流程,连带填坑。
SpringBoot整合Swagger2
引入相应的maven包
1
2
3
4
5
6
7
8
9
10
11<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.7.0</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.7.0</version>
</dependency>编写Swagger2的配置类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46package com.swagger.demo.config;
import io.swagger.annotations.Api;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
/**
* @author Mr.zhang
* @description swagger配置类
* @date 9:06 AM 2019/4/17
*/
2
public class Swagger2Config {
"${swagger2.enable}") (
private boolean enable;
public Docket createRestApi() {
return new Docket(DocumentationType.SWAGGER_2)
.groupName("Demo模块")
.select()
.apis(RequestHandlerSelectors.withClassAnnotation(Api.class))
.paths(PathSelectors.regex("/demo.*"))
.build()
.apiInfo(apiInfo())
.enable(enable);
}
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
.title("Demo模块接口文档")
.description("提供Demo模块文档")
.termsOfServiceUrl("https://xingtian.github.io/trace.github.io/")
.version("1.0")
.build();
}
} 注解
@EnableSwagger2
开启swagger2,apiInfo是接口文档的基本说明信息,包括标题、描述、服务网址、联系人、版本等信息。 Docket创建,通过groupName进行分组,paths属性进行过滤,apis属性可以设置扫描包,或者通过注解的方式标识。
enable属性主要用于控制是否生成接口文档,比如:生产环境不生成接口文档。
Controller层类和方法添加相关注解
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99package com.swagger.demo.web;
import com.swagger.demo.entity.ResultModel;
import com.swagger.demo.entity.User;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;
import java.util.List;
/**
* @author Mr.zhang
* @description Demo控制层
* @date 9:57 AM 2019/4/17
*/
"/demo") (
"demo模块") (tags =
public class DemoController {
"/query/{id}") (
"通过ID查询") (
"id", value = "用户ID", required = true, dataType = "int", paramType = "path") (name =
public ResultModel<User> findById(@PathVariable int id) {
return ResultModel.success("id查询成功", new User());
}
"/query/ids") (
"通过ID列表查询") (
public ResultModel<List<User>> findByIdIn(int[] ids) {
return ResultModel.success("in查询成功", new ArrayList<>());
}
"/query/user") (
"通过用户实体查询") (
public ResultModel<List<User>> findByUser(User user) {
return ResultModel.success("通过实体查询成功", new ArrayList<>());
}
"/query/all") (
"查询所有用户") (
public ResultModel<List<User>> findAll() {
return ResultModel.success("全体查找成功", new ArrayList<>());
}
"/query/username") (
"通过用户名称模糊查询") (
"userName", value = "用户名称") (name =
public ResultModel<List<User>> findByUserName(String userName) {
return ResultModel.success(new ArrayList<>());
}
"/insert") (
"新增默认用户") (
public ResultModel<Integer> insert() {
User user = new User();
user.setUserName("zhongshiwen");
user.setNickName("zsw");
user.setRealName("钟仕文");
user.setPassword("zsw123456");
user.setGender("男");
return ResultModel.success("新增用户成功", user.getId());
}
"/update") (
"更新用户信息") (
public ResultModel<Integer> update(User user) {
return ResultModel.success(user.getId());
}
"/update/status") (
"更新单个用户状态") (
({
"id", value = "用户ID", required = true), (name =
"status", value = "状态", required = true) (name =
})
public ResultModel<User> updateStatus(int id, byte status) {
return ResultModel.success(new User());
}
"/delete") (
"删除单个用户") (
"用户ID", required = true) (value =
public ResultModel<Integer> delete(int id) {
return ResultModel.success(id);
}
}返回对象ResultModel
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46package com.swagger.demo.entity;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
* @author Mr.zhang
* @description 返回对象
* @date 10:00 AM 2019/4/17
*/
"返回结果") (description =
public final class ResultModel<T> {
"是否成功: true or false") (
private boolean result;
"描述性原因") (
private String message;
"业务数据") (
private T data;
private ResultModel(boolean result, String message, T data) {
this.result = result;
this.message = message;
this.data = data;
}
public static<T> ResultModel<T> success(T data) {
return new ResultModel<>(true, "SUCCESS", data);
}
public static<T> ResultModel<T> success(String message, T data) {
return new ResultModel<>(true, message, data);
}
public static ResultModel failure() {
return new ResultModel<>(false, "FAILURE", null);
}
public static ResultModel failure(String message) {
return new ResultModel<>(false, message, null);
}
}ApiModel属性对象
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38package com.swagger.demo.entity;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.time.LocalDate;
import java.time.LocalDateTime;
/**
* @author Mr.zhang
* @description 用户表实体
* @date 10:03 AM 2019/4/17
*/
public class User {
"用户ID") private Integer id; (
"账户名") private String userName; (
"用户昵称") private String nickName; (
"真实姓名") private String realName; (
"身份证号码") private String identityCard; (
"性别") private String gender; (
"出生日期") private LocalDate birth; (
"手机号码") private String phone; (
"邮箱") private String email; (
"密码") private String password; (
"用户头像地址") private String logo; (
"账户状态 0:正常; 1:冻结; 2:注销") private Byte status; (
"个性签名") private String summary; (
"用户所在区域码") private String areaCode; (
"注册时间") private LocalDateTime registerTime; (
"最近登录时间") private LocalDateTime lastLoginTime; (
}Swagger2
几个重要注解@Api:用在请求的类上,表示对类的说明
tags “说明该类的作用,可以在UI界面上看到的注解”
value “该参数没什么意义,在UI界面上也看到,所以不需要配置”
@ApiOperation:用在请求的方法上,说明方法的用途、作用
- value=”说明方法的用途、作用”
- notes=”方法的备注说明”
@ApiImplicitParams:用在请求的方法上,表示一组参数说明 @ApiImplicitParam:用在@ApiImplicitParams注解中,指定一个请求参数的各个方面
value:参数的汉字说明、解释
required:参数是否必须传
paramType: 参数放在哪个地方
- 1.header –> 请求参数的获取:@RequestHeader
- 2.query –> 请求参数的获取:@RequestParam
- 3.path(用于restful接口)–> 请求参数的获取:@PathVariable
- 4.body(不常用)
- 5.form(不常用)
dataType:参数类型,默认String,其它值dataType=”Integer”
- defaultValue:参数的默认值
@ApiResponses:用在请求的方法上,表示一组响应 @ApiResponse:用在@ApiResponses中,一般用于表达一个错误的响应信息
- code:数字,例如400
- message:信息,例如”请求参数没填好”
- response:抛出异常的类
@ApiModel:主要有两种用途:
用于响应类上,表示一个返回响应数据的信息
入参实体:使用@RequestBody这样的场景, 请求参数无法使用@ApiImplicitParam注解进行描述的时候
@ApiModelProperty:用在属性上,描述响应类的属性 最终呈现结果
启动应用后,会自动生成页面
地址:
http://{root-path}/swagger-ui.html
(http://localhost:8080/swagger-ui.html)效果如下:
利用该文档可以在线测试接口