一、Swagger 简介
-
前后端分离:
- 前端:前端控制层、视图层;
- 后端:后端控制层、服务层、数据访问层;
- 前后端,通过 API 进行交互;
- 前后端相对独立,且松耦合;
-
产生的问题:
- 前后端集成,需要 API 对接进行交互,就需要一个 API 规范文档,但文档不能根据代码的变化,实时动态的改变,当后端修改了接口,前端不能及时获取,导致调用出错,需要手动维护 API 文档,加大了开发的工作量和困难;
-
解决方案:
- Swagger 解决了这一系列的问题,通过定义 schema [ 计划的提纲 ],实时跟踪最新的 API,降低集成风险;
-
Swagger:
- Restful Api 文档在线自动生成器:API 文档 与 API 定义同步更新;
- 直接运行,在线测试 API;
- 支持多种语言(如:Java、PHP 等);
二、Spring Boot 集成 Swagger
2.1 环境搭建
- 新建 Spring Boot web 项目:
- 导入相关依赖:
<!--SpringBoot整合swagger3方式-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-boot-starter</artifactId>
<version>3.0.0</version>
</dependency>
-
编写 Controller 测试,确保运行成功;
-
创建配置文件:
application.yaml
# Springfox使用的路径匹配是基于AntPathMatcher的,SpringBoot2.6.X使用的是PathPatternMatcher
spring:
mvc:
pathmatch:
matching-strategy: ANT_PATH_MATCHER
-
配置 Swagger:需要编写自定义配置类;
-
新建配置目录:config;
-
创建 SwaggerConfig;
-
// 配置类
@Configuration
// 开启Swagger2的自动配置
// @EnableSwagger2
// 开启Swagger3的自动配置
@EnableOpenApi
public class SwaggerConfig {
}
-
运行测试:访问地址
http://localhost:8080/swagger-ui/index.html与 2.x 访问地址http://localhost:8080/swagger-ui.html不同;
2.2 配置 Swagger
- Swagger 实例 Bean 是 Docket,需要通过配置 Docket 实例,来配置Swaggger:
// 配置docket,以配置Swagger具体参数
@Bean
public Docket docket() {
// 使用 OpenAPI 3.0 (OpenAPI Specification 的简称 OAS)
return new Docket(DocumentationType.OAS_30);
}
- 通过
ApiInfo属性,配置文档信息:
// 配置ApiInfo文档信息
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
// 文档标题
.title("Swagger3.0的接口文档测试")
// 文档描述
.description("api信息列表")
// 联系人信息
.contact(new Contact("作者", "作者URL", "作者Email"))
// 文档版本
.version("V1.0")
// 组织链接
.termsOfServiceUrl("http://www.test.com")
.build();
}
- 在 Docket 实例关联上
apiInfo():
// 配置docket,以配置Swagger具体参数
@Bean
public Docket docket() {
// 使用 OpenAPI 3.0 (OpenAPI Specification 的简称 OAS)
return new Docket(DocumentationType.OAS_30)
// 将api的元信息,设置为包含在json ResourceListing响应中
.apiInfo(apiInfo());
}
-
运行测试:
2.3 配置扫描接口
- 构建 Docket 时,通过
select()方法,配置扫描接口:
// 配置docket,以配置Swagger具体参数
@Bean
public Docket docket() {
// 使用 OpenAPI 3.0 (OpenAPI Specification 的简称 OAS)
return new Docket(DocumentationType.OAS_30)
// 将api的元信息,设置为包含在json ResourceListing响应中
.apiInfo(apiInfo())
// .select():配置扫描接口
.select()
// apis:添加swagger接口提取范围 RequestHandlerSelectors:扫描接口方式
// .basePackage:指定要扫描的包
.apis(RequestHandlerSelectors.basePackage("com.study.controller"))
.build();
}
- 其他扫描接口的方式:
// 扫描所有,项目中的所有接口都会被扫描到
any()
// 不扫描接口
none()
// 通过方法上的注解扫描,如withMethodAnnotation(GetMapping.class)只扫描get请求
withMethodAnnotation(final Class<? extends Annotation> annotation)
// 通过类上的注解扫描,如.withClassAnnotation(Controller.class)只扫描有controller注解的类中的接口
withClassAnnotation(final Class<? extends Annotation> annotation)
// 根据包路径扫描接口
basePackage(final String basePackage)
- 通过
.paths()配置接口扫描过滤:
// 配置docket,以配置Swagger具体参数
@Bean
public Docket docket() {
// 使用 OpenAPI 3.0 (OpenAPI Specification 的简称 OAS)
return new Docket(DocumentationType.OAS_30)
// 将api的元信息,设置为包含在json ResourceListing响应中
.apiInfo(apiInfo())
// .select():配置扫描接口
.select()
// apis:添加swagger接口提取范围 RequestHandlerSelectors:扫描接口方式
// .basePackage:指定要扫描的包
.apis(RequestHandlerSelectors.basePackage("com.study.controller"))
// .paths():过滤路径
// 只扫描请求以/test开头的接口
.paths(PathSelectors.ant("/test"))
.build();
}
- 配置过滤的可选值:
// 任何请求都扫描
any()
// 任何请求都不扫描
none()
// 通过正则表达式控制
regex(final String pathRegex)
// 通过ant()控制
ant(final String antPattern)
2.4 配置开关 Swagger
- 通过
enable()方法,配置是否启用 Swagger,如果是 false,Swagger将不能在浏览器中访问:
// 配置docket,以配置Swagger具体参数
@Bean
public Docket docket() {
// 使用 OpenAPI 3.0 (OpenAPI Specification 的简称 OAS)
return new Docket(DocumentationType.OAS_30)
// 将api的元信息,设置为包含在json ResourceListing响应中
.apiInfo(apiInfo())
// 配置是否启用Swagger,如果是false,在浏览器将无法访问
.enable(false)
// .select():配置扫描接口
.select()
// apis:添加swagger接口提取范围 RequestHandlerSelectors:扫描接口方式
// .basePackage:指定要扫描的包
.apis(RequestHandlerSelectors.basePackage("com.study.controller"))
// .paths():过滤路径
// 只扫描请求以/test开头的接口
.paths(PathSelectors.ant("/test"))
.build();
}
-
关闭 Swagger,运行测试:
-
动态配置项目:test、dev 环境时,显示Swagger,prod 时不显示:
// 配置docket,以配置Swagger具体参数
@Bean
// Environment:获取环境设置
public Docket docket(Environment environment) {
// 设置要显示Swagger的环境
Profiles of = Profiles.of("dev", "test");
// 判断当前是否处于该环境
// 通过 enable() 接收此参数,判断是否要显示
boolean flag = environment.acceptsProfiles(of);
// 使用 OpenAPI 3.0 (OpenAPI Specification 的简称 OAS)
return new Docket(DocumentationType.OAS_30)
// 将api的元信息,设置为包含在json ResourceListing响应中
.apiInfo(apiInfo())
// 配置是否启用Swagger,如果是false,在浏览器将无法访问
.enable(flag)
// .select():配置扫描接口
.select()
// apis:添加swagger接口提取范围 RequestHandlerSelectors:扫描接口方式
// .basePackage:指定要扫描的包
.apis(RequestHandlerSelectors.basePackage("com.study.controller"))
// .paths():过滤路径
// 只扫描请求以/test开头的接口
.paths(PathSelectors.ant("/test"))
.build();
}
- 设置运行环境:
application.properties
# 设置运行环境
spring.profiles.active=dev
- 在项目中,增加一个 dev 的配置文件,测试效果;
2.5 配置 API 分组
- 如果没有配置分组,默认是 default,通过
groupName()方法,配置分组:
// 配置docket,以配置Swagger具体参数
@Bean
public Docket docket() {
// 使用 OpenAPI 3.0 (OpenAPI Specification 的简称 OAS)
return new Docket(DocumentationType.OAS_30)
// 将api的元信息,设置为包含在json ResourceListing响应中
.apiInfo(apiInfo())
// 配置分组
.groupName("测试组A")
// 省略其它配置...
}
- 配置多个分组,只需要配置多个 docket 即可:
// 配置多个分组
@Bean
public Docket docket2() {
return new Docket(DocumentationType.OAS_30).groupName("测试组B");
}
@Bean
public Docket docket3() {
return new Docket(DocumentationType.OAS_30).groupName("测试组C");
}
@Bean
public Docket docket4() {
return new Docket(DocumentationType.OAS_30).groupName("测试组D");
}
-
运行测试:
2.6 实体类配置
- 新建实体类:
// @Schema 注解用在类上不生效,使用@ApiModel替代
// @ApiModel:实体类注释
@ApiModel("User 用户实体")
public class User {
// @Schema:描述对象属性,在实体类属性上使用,等同于@ApiModelProperty
@Schema(name = "用户名", description = "用户名")
public String userName;
@Schema(description = "密码")
public String passWord;
// get、set方法
}
- 创建实例类请求接口:
- 只要接口的返回值中,存在实体类(即使是泛型),都会被扫描到 Swagger 中;
@RestController
// @Tag:接口类描述,在Controller类上使用,等同于@Api
@Tag(name = "Hello控制类")
public class Hello {
@GetMapping("/hello")
public String hello() {
return "hello swagger";
}
// 只要接口的返回值中,存在实体类,就会被扫描到Swagger中
@PostMapping("/user")
public User getUser() {
return new User();
}
@GetMapping("/hello2")
// @Operation:接口方法描述,在Controller方法上使用,等同于@ApiOperation
@Operation(summary = "hello2 接口方法")
// @Parameter:参数描述,在Controller 方法的参数上使用,等同于@ApiParam
public String hello2(@Parameter(description = "用户名") String username) {
return "Hello " + username;
}
@PostMapping("/h1")
// @Operation:接口方法描述,在Controller方法上使用,等同于@ApiOperation
@Operation(summary = "h1 接口方法")
// @Parameter:参数描述,在Controller 方法的参数上使用,等同于@ApiParam
public User h1(@Parameter(description = "用户") User user) {
return user;
}
}
-
运行测试:主页面
-
查看 GET 请求:
-
查看 POST 请求:
-
实体类描述:
-
注:并不是因为
@ApiModel等注解,让实体显示在这里,而是,只要出现在接口方法的返回值上的实体,都会显示在这里,这些注解,只是实现了注释功能;
2.7 常用注解
- Swagger2 常用注解说明:
@Api:用在 controller 类,描述 API 接口;@ApiOperation:描述接口方法@ApiModel:描述对象@ApiModelProperty:描述对象属性@ApiImplicitParams:描述接口参数@ApiResponses:描述接口响应@ApiIgnore:忽略接口方法
- Swagger3 与 Swagger2 注解对比使用:
- Swagger2
io.swagger.annotations包下; - Swagger3 定义在
io.swagger.v3.oas.annotations包下; - Springdoc 官网
- Swagger2
| swagger2 | OpenAPI 3 | 注解位置 |
|---|---|---|
@Api | @Tag(name = “接口类描述”) | Controller 类上 |
@ApiOperation | @Operation(summary =“接口方法描述”) | Controller 方法上 |
@ApiImplicitParams | @Parameters | Controller 方法上 |
@ApiImplicitParam | @Parameter(description=“参数描述”) | Controller 方法上 @Parameters 里 |
@ApiParam | @Parameter(description=“参数描述”) | Controller 方法的参数上 |
@ApiIgnore | @Parameter(hidden = true) 或 @Operation(hidden = true) 或 @Hidden | 排除或隐藏 api |
@ApiModel | @Schema | DTO 类上 |
@ApiModelProperty | @Schema | DTO 属性上 |
总结:
- 可以通过 Swagger 给一些比较难理解的属性和接口,增加注释信息;
- 接口文档实时更新;
- 可以在线测试;
- 注意:在正式发布时,需要关闭 Swagger,出于安全考虑,可以节省内存;