一、简介
官网:API Documentation & Design Tools for Teams | Swagger
Swagger 是一个规范且完整的框架,用于生成、描述、调用和可视化 RESTful 风格的 Web 服务。
Swagger 的目标是对 REST API 定义一个标准且和语言无关的接口,可以让人和计算机拥有无须访问源码、文档或网络流量监测就可以发现和理解服务的能力。当通过 Swagger 进行正确定义,用户可以理解远程服务并使用最少实现逻辑与远程服务进行交互。与为底层编程所实现的接口类似,Swagger 消除了调用服务时可能会有的猜测。
Swagger 的优势
-
支持 API 自动生成同步的在线文档:使用 Swagger 后可以直接通过代码生成文档,不再需要自己手动编写接口文档了,对程序员来说非常方便,可以节约写文档的时间去学习新技术。
-
提供 Web 页面在线测试 API:光有文档还不够,Swagger 生成的文档还支持在线测试。参数和格式都定好了,直接在界面上输入参数对应的值即可在线测试接口。
二、基本使用
1、导入相关依赖
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.1.RELEASE</version>
<relativePath/>
</parent>
<dependencies>
<!--swagger-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.7.0</version>
<!--provide仅在编译和测试阶段生效,provide不会被打包,也不具有传递性。-->
<scope>provided</scope>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.7.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
2、编写配置文件
@Configuration
@EnableSwagger2 // 开启 swagger2 的自动配置
public class SwaggerConfig {
}
这个时候 Swagger 已经算是整合到项目之中了,可以启动下服务,输入http://localhost:8080/swagger-ui.html#
可以看到 Swagger 文档中大概有这四类信息
-
组
-
基本信息
-
接口信息
-
实体类信息
2.1 配置基本信息
Swagger 有自己的实例 Docket,如果我们想要自定义基本信息,可以使用 docket 来配置 swagger 的基本信息,基本信息的设置在这个ApiInfo对象中。
ApiInfo 中默认的基本设置
-
title:Api Documentation
-
description:Api Documentation
-
version:1.0
-
termsOfServiceUrl:urn:tos
-
contact:无
-
license:Apache 2.0
-
licenseUrl:http://www.apache.org/licenses/LICENSE-2.0
配置文件添加以下内容:
@Configuration
@EnableSwagger2
public class SwaggerConfig {
@Bean
public Docket docket() {
return new Docket(DocumentationType.SWAGGER_2)
// 配置基本信息
.apiInfo(apiInfo());
}
/**
* 基本信息设置
* @return
*/
private ApiInfo apiInfo() {
Contact contact = new Contact(
"小明", // 作者姓名
"https://www.csdn.net/nav/web", // 作者网址
"111111@qq.com"); // 作者邮箱
// 底层使用链式编程对属性赋值
return new ApiInfoBuilder()
.title("SpringBoot整合Swagger接口文档") // 标题
.description("你好,Swagger") // 描述
.termsOfServiceUrl("https://www.bilibili.com") // 跳转连接
.version("2.0") // 版本
.license("Swagger-的使用(详细教程)")
.licenseUrl("https://weibo.com")
.contact(contact) //作者信息
.build();
}
}
重启服务,打开 Swagger 文档,基本信息改变如下所示:
2.2 配置接口信息
默认情况下,Swagger 是会展示所有的接口信息的,包括最基础的basic-error相关的接口
有时候我们希望不要展示 basic-error-controller 相关的接口,或者是说这想要显示某些接口,比如说:user-controller下的接口,由该怎么去实现呢?这个时候就需要设置扫描接口
@Bean
public Docket docket() {
return new Docket(DocumentationType.SWAGGER_2){
// 配置接口信息
.select() // 设置扫描接口
// 配置如何扫描接口
// 可设置多个,底层:Predicates.and(this.requestHandlerSelector, selector);
.apis(RequestHandlerSelectors
//.any() // 扫描全部的接口,默认
//.none() // 全部不扫描
.basePackage("com.cyf.controller") // 扫描指定包下的接口
//.withClassAnnotation(RestController.class) // 扫描带有指定注解的类下所有接口
//.withMethodAnnotation(PostMapping.class) // 扫描带有指定注解的方法接口
)
.apis(RequestHandlerSelectors.withMethodAnnotation(PostMapping.class))
// 路径匹配
// 可设置多个,底层:Predicates.and(this.pathSelector, selector);
.paths(PathSelectors
.any() // 满足条件的路径,该断言总为true
//.none() // 不满足条件的路径,该断言总为false(可用于生成环境屏蔽 swagger)
//.ant("/user/**") // 满足字符串表达式路径
//.regex("") // 符合正则的路径
)
.build();
}
@RestController
@ApiModel("用户服务")
public class UserController {
@GetMapping("/get")
public String get() {
return "get页面";
}
@PostMapping("/post")
public String post() {
return "post页面";
}
@DeleteMapping("/delete")
public String delete() {
return "delete页面";
}
@PutMapping("/put")
public String put() {
return "put页面";
}
}
可根据自己的需求去设置对应的配置
可以看到之前 basic-error-controller 相关的接口已经没有了
2.3配置分组信息
Swagger 默认只有一个 default 分组选项,如果没有设置,所有的接口都会显示在 default 分组下,如果功能模块和接口数量一多,就会显得比较凌乱,不方便查找和使用。
swagger 文档中组名默认是 default,可通过 .groupName(String)
如果需要配置多个组的话,就需要配置多个docket
@Bean
public Docket docket1() {
return new Docket(DocumentationType.SWAGGER_2)
.groupName("test1");
}
@Bean
public Docket docket2() {
return new Docket(DocumentationType.SWAGGER_2)
.groupName("test2");
}
3、控制 Swagger 的开启
在开发或者测试环境下,我们开启 swagger 会方便前端和后端的交互,但是如果在生产环境下也开启 swagger 的话,是会将接口暴露出去的,有极大风险,如何让 swagger 根据不同的环境来决定是否开启?
配置文件如下:
spring:
profiles:
active: pro
---
spring:
profiles: dev
server:
port: 8887
---
spring:
profiles: pro
server:
port: 8886
---
spring:
profiles: test
server:
port: 8885
@Bean
public Docket docket(Environment environment) {
// 设置环境范围
Profiles profiles = Profiles.of("dev", "test");
// 如果在该环境返回内则返回:true,反之返回 false
boolean flag = environment.acceptsProfiles(profiles);
// 创建一个 swagger 的 bean 实例
return new Docket(DocumentationType.SWAGGER_2)
//是否开启 swagger:true -> 开启,false -> 关闭
.enable(flag)
}
当我指向生产环境时,就不能打开 swagger 了。
4、常用注解使用
@ApiModel
该注解是作用于返回对象类上面的,是用来描述类的一些基本信息的。
相关属性:
-
value:提供类的一个备用名,如果不设置,默认情况下将使用 class 类的名称
-
description:对于类,提供一个详细的描述信息
-
parent:这个属性用于描述的是类的一些父类信息
-
discriminator:这个属性解释起来比较麻烦,因为这个类主要体现在断言当中
-
subTypes:可以通过这个属性,指定我们想要使用的子类
@ApiModel(value = "用户类", description = "拥有两个字段")
public class User {
}
@ApiModelProperty
用于方法,字段; 表示对model属性的说明或者数据操作更改
-
value:字段说明
-
name:重写属性名字
-
dataType:重写属性类型
-
required:是否必填
-
example:举例说明
-
hidden:隐藏
@ApiModel(value = "用户类", description = "拥有两个字段")
public class User {
@ApiModelProperty("用户id")
private Long id;
@ApiModelProperty("姓名")
private String name;
}
@ApiOperation
该注解用来对某个方法/接口进行描述
@GetMapping("/get")
@ApiOperation(value = "根据用户名称返回User对象")
public R<User> get(String name) {
return new R(200, new User(1L, name), "请求成功");
}
@ApiParam
该注解使用在方法上或者参数上,字段说明,表示对参数的添加元数据(说明或者是否必填等)
相关属性:
-
name:参数名
-
value:参数说明
-
required:是否必填
@ApiOperation("根据用户名称返回User对象")
public R<User> get(
@ApiParam(value = "用户姓名", required = false) @RequestParam String name) {
return new R(200, new User(1L, name), "请求成功");
}