1、概述
接口文档对于前后端开发人员都十分重要。尤其是近几年流行前后端分离后,接口文档又变成了重中之重。接口文档固然重要,但是由于项目周期等种种原因,后端开发人员经常出现无法及时更新接口文档,导致前端开发人员抱怨接口文档和实际情况不一致。很多前端开发人员会抱怨别人写的接口文档不规范,不及时更新。但是,当我们自己去写的时候,确实挺烦写接口文档的。如果接口文档可以实时动态生成就不会出现上面问题了,Swagger可以说是完美的解决上面的问题。
优点
- 可以自动生成文档,只需要在接口中使用注解进行标注,就能生成对应的接口文档。
- 自动更新文档,由于是动态生成的,所以如果我们修改了接口方法,文档也会自动对应修改(前提是注解也得到了更新)。这样就不会出现我们修改了接口,却忘记更新接口文档的情况。
- 支持在线调试,Swagger提供了在线调试接口的功能。
缺点
- Swagger不能创建测试用例,所以Swagger暂时不能帮我们处理完所有的事情。它只能提供一个简单的在线调试,如果你想存储你的测试用例,可以使用 Postman 或者 YAPI 这些支持创建测试用例的工具。
- 需要遵循一些规范,它不是任意规范的。比如说,你可能会返回一个json数据,而这个数据可能是一个Map格式的,那么我们此时就不能标注这个Map格式的返回数据的每一个字段的说明,而如果它是一个实体类的话,我们可以通过标注类的属性来给返回字段加说明。再比如说,对于Swagger而言,不推荐在使用GET方式提交数据的时候还使用Body,仅推荐使用query参数、header参数或者路径参数(path),当然这个限制只适用于在线调试。
- 没有接口文档更新管理,虽然一个接口更新完之后,可能不会关心旧版的接口信息,但你“可能"想看看旧版的接口信息,例如有些灰度更新发布的时候,可能还会关心旧版的接口。那么此时只能由后端去看看有没有注释留下了,所以可以考虑接口文档有大的更新的时候注释掉旧版的,然后编写下新版的。
- 代码中存在注解依赖
2、springboot整合Swagger
添加Swagger的依赖
<!-- Swagger -->
<!-- Swagger依赖 -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>
要想使用swagger,我们必须对swagger进行配置,我们需要创建一个swagger的配置类,我们可以命名一个SwaggerConfig的配置类
package edu.xja.config;
import com.github.xiaoymin.swaggerbootstrapui.annotations.EnableSwaggerBootstrapUI;
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.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
/**
* 用于配置SwaggerApi
*/
// 标明当前类是配置类
@Configuration
// 开启Swagger使用(项目注释文档)
@EnableSwagger2
public class SwaggerConfig {
@Bean
public Docket createRestApi() {
return new Docket(DocumentationType.SWAGGER_2)
//用于生成API信息
.apiInfo(apiInfo())
//select()函数返回一个ApiSelectorBuilder实例,用来控制接口被swagger做成文档
.select()
//用于指定扫描哪个包下的接口
.apis(RequestHandlerSelectors.basePackage("edu.xja.controller"))
//选择所有的API,如果你想只为部分API生成文档,可以配置这里
.paths(PathSelectors.any())
.build();
}
/*
*用于定义API主界面的信息,比如可以声明所有的API的总标题、描述、版本
*/
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
//用来自定义API的标题
.title("Swagger接口文档API")
//用来描述整体的API
.description("这个Java后端开发人员很懒,什么信息也没有留下来!")
//创建人信息
.contact(new Contact("lvjt", "http://localhost:8080/swagger-ui.html", "xxxxxxxx@163.com"))
//用于定义服务的域名
//.termsOfServiceUrl("")
.version("1.0") //可以用来定义版本
.build();
}
}
在springboot的配置文件添加swagger的配置(springboot2.5以上都需要添加)
spring:
mvc:
pathmatch:
matching-strategy: ant_path_matcher
启动我们的springboot项目
Swagger UI页面访问地址: 点击查看
默认端口号是8080,根据自己配置文件设置的端口号去访问swagger的UI调试界面
然后你就可以看到一个如下的界面:
由于我们暂时还没有配置接口数据,所以下面显示 No operations defined in spec!
3、定义接口组
使用 @Api 这个注解来标注一个Controller之后,如果下面有接口,那么默认就会生成文档,但是目前还没有我们自定义的说明:
package edu.xja.controller;
import edu.xja.pojo.User;
import edu.xja.service.UserService;
import io.swagger.annotations.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* <p>
* 前端控制器
* </p>
*
* @author lvjt
* @since 2023年04月10日
*/
// tags:你可以当作是这个接口组的名字
@Api(tags = "用户信息")
@RestController
@RequestMapping("/user")
public class UserController {
@Autowired
private UserService userService;
/*
注意,对于swagger而言,不要使用 @RequestMapping
因为@RequestMapping支持任意请求方式,swagger会为这个接口生成7种请求方式的接口文档。
*/
@GetMapping("/list")
public List<User> list() {
List<User> userList = userService.list();
return userList;
}
@GetMapping("/{id}")
public User getById(@PathVariable int id) {
User user = userService.getById(id);
return user;
}
@PostMapping
public boolean save(@RequestBody User user) {
boolean isSave = userService.save(user);
return isSave;
}
@PutMapping
public boolean updateById(@RequestBody User user) {
boolean isUpdate = userService.updateById(user);
return isUpdate;
}
@DeleteMapping("/{id}")
public boolean delete(@PathVariable int id) {
boolean isDel = userService.removeById(id);
return isDel;
}
}
重启项目查看swagger UI视图
swagger UI视图解析
我们可以使用 @ApiOperation 这个注解来描述接口,比如:
4、定义接口请求参数
上面使用我们可以使用 @ApiOperation 这个注解来描述接口,但其实还缺少接口请求参数的说明,下面我们分场景来讲。注意一下,对于GET方式,swagger不推荐使用body方式来传递数据,也就是不希望在使用GET方式时使用json、form-data等类型来传递参数,这时候最好使用路径参数或者url参数(postman等工具是支持的)。所以,如果接口的传递数据是json或者form-data类型的,还是使用POST方式比较好。
4.1、请求参数是实体类
此时,我们需要使用 @ApiModel 来标注实体类,然后在接口中定义入参为实体类即可。
@ApiModel:用来标注实体类
常用配置项:
- value:实体类简称
- description:实体类说明
@ApiModelProperty:用来描述实体类的属性的意义。
常用配置项:
- value:实体类属性的说明。
- example:设置请求示例 (Example Value) 的默认值,如果不配置的话,当属性为string类型的时候,此时请求示例中的默认值为 “”。
- name:用新的属性名来替代旧的属性名。
- allowableValues:限制属性的值的范围,例如:{1,2,3}代表只能取这三个值;[1,5]代表取1到5的值;;(1,5)代表1到5的值,但是不包括1和5;还可以使用infinity或-infinity来取无限值,比如[1,infinity]代表最小值为1,最大值为正无穷大。
- required:标记此属性是否必填,默认是false。
- hidden:用来隐藏属性,默认是false,如果要隐藏属性需要使用true,因为属性默认都是会显示的,就算没有@ApiModelProperty。
定义入参:
4.2、请求参数是非实体类
4.2.1、声明入参是URL参数
再一次强调:对于GET方式,swagger不推荐使用body方式来传递数据。所以,虽然SpringMVC可以自动封装参数,但是对于GET请求还是不要使用form-data,json等方式来传递参数,除非你使用Postman来测试接口,swagger在线测试是不支持这个操作的。
对于非实体类参数,可以使用 @ApilmplicitParams 和 @ApilmplicitParam 来声明请求参数。@ApilmplicitParams用在方法头上,@ApilmplicitParam定义在@ApilmplicitParams里面,@ApilmplicitParam对应一个参数。
@ApilmplicitParam常用配置项:
1.name:用来定义参数的名字,也就是参数的名字,可以与接口的入参名对应。如果不对应也会生成,所以可以用来定义额外参数!
2.value:用来描述参数。
3.required:用来标注参数是否必填。
4.paramType:有path,query,body,form,header等方式,但对于参数是非实体的时候,常用的只有path,query,header;body和form是不常用的,body不适用于多个零散参数的情况,只适用于json对象等情况。【如果你的接口是form-data,x-www-form-urlencoded的时候,可能不能使用swagger页面API调试,但可以在基于Bootstrap Ul的swagger UI增强中调试,基于Bootstrap Ul的swagger支持指定form-data或x-www-form-urlencoded】
4.2.2、声明入参是URL路径参数
4.2.3、声明入参是header参数
4.2.4、声明入参是文件上传参数
5、定义接口响应
定义接口响应,是方便查看接口文档的人能够知道接口返回的数据的意义。
5.1、接口响应是实体类
前面在定义接口请求参数的时候,有提到使用 @ApiModel 来标注类,如果接口返回了这个类,那么这个类上的说明也会作为响应的说明:
5.2、接口响应是非实体类
swagger无法对非实体类的响应进行详细说明,只能标注响应码等信息。是通过 @ApiResponses 和 @ApiResponse 来实现的。
@ApiResponses 和 @ApiResponse 可以与 @ApiModel 一起使用。
6、Swagger UI增强
你可能会觉得现在这个UI不是很好看,现在有一些第三方提供了一些Swagger UI增强,比较流行的是 swagger-bootstrap-ui
<!-- 引入swagger-bootstrap-ui依赖包-->
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>swagger-bootstrap-ui</artifactId>
<version>1.9.6</version>
</dependency>
在Swagger配置类上增加注解 @EnableSwaggerBootstrapUI
@EnableSwaggerBootstrapUI
访问API:http://1ocalhost:8080/doc.html,即可预览到基于bootstarp的Swagger UI界面了。