5-22 Swagger Api在线文档与Knife4j
简介
Swagger
是一个用于 生成、描述、调用 RESTful 接口的Web服务,
可以将项目中对外暴露的接口展现在Web页面上,并且可以进行接口的调用和调试,代替Postman
作用和好处:
- 跟随项目代码,编译时动态实时生成新的接口文档
- 可以将指定的接口,展现在web文档页面
- 可以直接进行接口调试,降低开发阶段成本
tips:
- 所有使用方法均为注解,且均已
Apixxx
开头 - 所有注解只会存在于
Controller
层和Model
层
配置
建议:不要使用最新版3.0.0+,会有兼容问题
一、依赖
- 遵循 OpenApi 规范的core库
<!--Swagger core库, 遵循 OpenApi 规范-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>
- Swagger UI库
<!--Swagger UI-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>
- 版本兼容
swagger 2.9.2版本自带的models库,版本未1.5.20,该版本会有一个警告一直抛出在控制台,于是我们需要排除错误版本,引入 1.5.22版本来解决这个问题
java.lang.NumberFormatException: For input string: ""
最后展示一下最终依赖:
<!--Swagger core库, 遵循 OpenApi 规范-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
<!--排除2.9.2版本自带的 models1.5.20版本-->
<exclusions>
<exclusion>
<groupId>io.swagger</groupId>
<artifactId>swagger-models</artifactId>
</exclusion>
</exclusions>
</dependency>
<!--引入models 1.5.22版本, 解决控制台警告: java.lang.NumberFormatException: For input string: ""-->
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-models</artifactId>
<version>1.5.22</version>
</dependency>
<!--Swagger UI-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>
二、启动项配置
package com.a2j.swagger;
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;
/**
* Author: bzb
* Data: 2022/1/20 17:56
* Desc: Swagger Api 启动配置项
* Docs: http://localhost:1234/swagger-ui.html
*/
@Configuration
@EnableSwagger2 // 开启Swagger web服务
public class SwaggerApiConfig {
@Bean
public Docket swagger() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo()) // Api配置
.groupName("a2j模块") // 分组名称
.select() // 构建选择器builder配置
.apis(RequestHandlerSelectors.basePackage("com.a2j.controller")) // 扫描接口的包路径
.paths(PathSelectors.any()) // 扫描路径
.build();
}
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
.title("A2J-Api接口文档")
.description("接口描述、参数描述、字段描述、在线调试")
.version("1.0.0")
.contact(new Contact("bzb", "", ""))
.build();
}
}
此时使用 http://localhost:1234/swagger-ui.html 访问就能看到文档了!
使用
一、类注解
@Api
作用于`Controller`层的接口类,描述接口信息
常用参数: `tags`
属性名 | 类型 | 描述 |
---|---|---|
tags | String[] | 类的说明 |
value | String | url路径 |
hidden | Boolean | 在文档中隐藏显示 |
@ApiModel
作用于`Model`层的实体类VO对象,描述对象信息
配合 `@ApiImplicitParams` 和 `@RequestBody`使用
常用参数:`description`
属性名 | 类型 | 描述 |
---|---|---|
description | String | 类的说明 |
value | String | 对象名 |
parent | Class<?> | 继承父级类的.class |
二、方法注解
@ApiOperation
作用于`Controller`层的接口方法上,描述接口信息
常用参数:`value`、`notes`
value
该接口作用说明,直接UI呈现notes
备注,适合接口的详细描述response
返回值类型的.class
@ApiImplicitParam
@ApiImplicitParams
作用于`Controller`层的接口方法上,描述入参数据信息
`@ApiImplicitParam` 用于参数类型为`基础数据`的时候
`@ApiImplicitParams` 用于参数类型为`实体类对象`类型的时候
常用参数:`value`、`notes`
-
name
参数名 -
value
参数说明 -
required
是否为必传参数,默认false -
paramType
入参方式,header/query/path/body -
dataType
参数类型,默认String,int/String -
defaultValue
参数默认值
@ApiResponse
@ApiResponses
作用于`Controller`层的接口方法上,描述出参数据信息。此功能最后有全局处理的方式优化。
`@ApiResponse` 用于描述单个响应码
`@ApiResponses` 用于描述多个响应码
常用参数:`code`、`message`
-
code
响应码 -
message
响应码的对应说明 -
response
可能抛出异常的数据类型的.class
三、属性字段注解
@ApiModelProperty
作用于`Model`层的属性上,描述字段信息
常用参数:`value`
-
value
属性说明 -
required
是否必传,默认true -
example
默认值 -
hidden
隐藏显示,默认false
使用案例:
package com.a2j.controller.car;
import io.swagger.annotations.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
...
/**
* Author: bzb
* Data: 2022/1/19 15:38
* Desc: 车型controller
*/
@RestController
@RequestMapping("/carType")
@Api(tags = "车型接口")
public class CarTypeController {
@Autowired
CarTypeService service;
/**
* 新增车型
* @param record 车型信息
*/
@PostMapping("/addCarType")
@ApiOperation(value = "新增车型")
@ApiImplicitParams({})
@ApiResponse(code = 200, message = "请求成功")
public BaseBean<String> addCarType(@RequestBody CarTypeVO record) {
service.addCarType(record);
return BaseBean.success(ResponseCode.SUCCESS);
}
/**
* 删除车型
* @param id 车型id
*/
@PutMapping("/delCarType/{id}")
@ApiOperation(value = "删除车型")
@ApiImplicitParam(name = "id", value = "车型id", required = true, dataType = "int", paramType = "path", defaultValue = "100")
@ApiResponses({
@ApiResponse(code = 200, message = "请求成功"),
@ApiResponse(code = 404, message = "接口不存在")
})
public BaseBean<String> delCarType(@PathVariable Integer id) {
service.delCarType(id);
return BaseBean.success(ResponseCode.SUCCESS);
}
}
package com.a2j.beans.car.type;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* Author: bzb
* Data: 2022/1/18 22:39
* Desc: 车型出入参对象
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@ApiModel(description = "车型出入参对象")
public class CarTypeVO {
@ApiModelProperty(value = "品牌id", hidden = true)
private Integer brandId;
@ApiModelProperty(value = "车系名称", required = true, example = "迈凯伦")
private String typeName;
...
}
ApiResponse优化
上面我们介绍了 @ApiResponse 的使用方法
对于接口返回描述,每个接口都去加上同样的内容过于繁琐,于是我们使用全局的响应码配置处理。
@Bean
public Docket swagger() {
// 全局响应码统一处理
List<ResponseMessage> responseMessages = new ArrayList<>();
for (ResponseCode value : ResponseCode.values()) {
// 大于1000的不对外显示
if (value.getCode() > 1000) continue;
responseMessages.add(
new ResponseMessageBuilder()
.code(value.getCode())
.message(value.getMessage())
.build()
);
}
return new Docket(DocumentationType.SWAGGER_2)
.useDefaultResponseMessages(false) // 不使用默认的响应码描述
.globalResponseMessage(RequestMethod.GET, responseMessages)
.globalResponseMessage(RequestMethod.POST, responseMessages)
.globalResponseMessage(RequestMethod.PUT, responseMessages)
.globalResponseMessage(RequestMethod.DELETE, responseMessages);
}
Knife4j优化Swagger
Knife4j
是Swagger
的UI增强版,
Swagger
现有的体验有如下缺陷,所以我们需要升级增强版 Knife4j
1. 文档界面粗糙,不易操作
入参对象属性过多时阅读性差,在线调试不够友好
2. 正式环境无法关闭文档
Swagger有解决方案,但不是自有配置
一、在pom.xml中改造依赖如下:
第一层级
<!--knife4j, 3.0版本问题参考: http://github.com/springfox/springfox/issues/3520-->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-dependencies</artifactId>
<version>2.0.8</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
第二层级
<dependencies>
<!--Spring Boot项目单体架构 -->
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-spring-boot-starter</artifactId>
</dependency>
<!--Swagger UI, core库遵循 OpenApi 规范-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
</dependency>
</dependencies>
二、对启动配置项修改
@EnableSwagger2
修改为:@EnableSwagger2WebMvc
原来的:
import springfox.documentation.swagger2.annotations.EnableSwagger2;
// http://localhost:1234/swagger-ui.html
@Configuration
@EnableSwagger2 // 开启Swagger web服务
public class SwaggerApiConfig {
}
现在的:
import springfox.documentation.swagger2.annotations.EnableSwagger2WebMvc;
// http://localhost:1234/doc.html
@Configuration
@EnableSwagger2WebMvc // 开启Swagger web服务
public class SwaggerApiConfig {
}
application-dev.yml
增加配置
# knife4j
knife4j:
enable: true # 开启增强模式,下面高级设置才生效
production: false # 是否为生产环境
basic:
enable: true # 开启knife4j
username: bzb
password: 123
application-prod.yml
增加配置
# knife4j
knife4j:
enable: true # 开启增强模式,下面高级设置才生效
production: true # 是否为生产环境
basic:
enable: true # 开启knife4j
username: bzb
password: 123
至此,配置就结束了,此时文档的访问地址为 http://localhost:1234/doc.html ,快去看看惊艳到你了没吧!