大家好,我是晓凡。
写在前面
在上一篇文章,我们详细介绍了SpringBoot3
怎么整合SpringDoc
实现在线接口文档。但是,有不少小伙伴
都觉得接口界面太丑了。有没有什么更美观一点的UI界面呢?
当然是有的了,毕竟这是一个看脸的时代,Knife4j
这不来了么。
一、界面比较
这儿我们将上一篇文章使用swagger UI
和Knife4j UI
做一个比较,哪个好看就不用我多说了吧。
① swagger
UI界面
②Knife4j UI界面
二、Knife4j
是什么?
Knife4j
是一个为 Java
项目生成和管理 API
文档的工具。实际上,它是 Swagger UI
的一个增强工具集,
旨在让 Swagger
生成的 API
在线文档更加优雅、美观、强大。
① 官方地址
http://knife4j.net/
②文档地址
https://doc.xiaominfo.com/docs/quick-start
三、为什么要使用Knife4j
使用Knife4j
主要有以下优点,就问哪个不吸引我们呢?
- **美观的
UI
**:相比于原生 Swagger UI
,Knife4j
提供了更加人性化和美观的界面设计
- 丰富的文档交互功能:支持在线调试、请求参数动态输入、接口排序等
- 个性化配置:可自定义
API
文档的界面风格,实现文档界面的个性化展示
四、Knife4j
版本介绍
目前,我们使用的SpringBoot
版本主要是2和3,不同的boot版本需要适配不同版本的Knife4j
.
通过这一小节,我们将在项目中选择合适的Knife4j
版本
4.1 Knife4j
的前世今生
在更名为Knife4j
之前,原来的名称是叫swagger-bootstrap-ui
,这是两种不一样风格的Ui
,区别如下
名称 |
开发语言&框架 |
状态 |
最后版本 |
风格 |
Knife4j |
Java 、JavaScript 、Vue |
持续更新中… |
无 |
黑色 |
swagger-bootstrap-ui |
Java 、JavaScript 、jQuery |
停更 |
1.9.6 |
蓝色 |
Knife4j
从开源至今,目前主要经历版本的变化,分别如下:
版本 |
说明 |
1.0~1.9.6 |
名称是叫swagger-bootstrap-ui ,蓝色风格Ui |
1.9.6 |
蓝色皮肤风格,开始更名,增加更多后端模块 |
2.0~2.0.5 |
Ui 基于Vue2.0+AntdV 重写,黑色风格,底层依赖的springfox2.9.2 ,仅提供Swagger2 规范的适配 |
2.0.6~2.0.9 |
底层依赖springfox2.10.5 ,仅提供Swagger2 规范的适配 |
3.0~3.0.3 |
底层依赖springfox3.0.3 ,是过度版本,不建议使用 |
4.0~ |
Knife4j 对于支持不同协议,依赖的是第三方组件,需要引入不同依赖
OpenAPI2 (Swagger2 )规范,依赖Springfox 项目,项目处于停更状态,不建议使用
OpenAPI3 (Swagger3 )规范,依赖Springdoc 项目,更新频率快,建议使用该版本 |
4.2 Spring Boot
版本兼容性
Spring Boot 版本 |
Knife4j Swagger2 规范 |
Knife4j OpenAPI3 规范 |
1.5.x~2.0.0 |
<Knife4j 2.0.0 |
>=Knife4j 4.0.0 |
2.0~2.2 |
Knife4j 2.0.0 ~ 2.0.6 |
>=Knife4j 4.0.0 |
2.2.x~2.4.0 |
Knife4j 2.0.6 ~ 2.0.9 |
>=Knife4j 4.0.0 |
2.4.0~2.7.x |
>=Knife4j 4.0.0 |
>=Knife4j 4.0.0 |
>= 3.0 |
>=Knife4j 4.0.0 |
>=Knife4j 4.0.0 |
如果你不考虑使用Knife4j
提供的服务端增强功能,引入Knife4j
的纯Ui
版本没有任何限制。只需要考虑不同的规范即可
五、快速开始
通过上面的介绍,相信你已经对Knife4j
有了整体的认识,接下来我们就使用SpringBoot3
快速整合Knife4j
。
我们这选用的环境如下
jdk17
SpringBoot3.3.1
knife4j 4.4.0
OpenAPI3
协议规范
5.1 新建一个web项目
建一个名为knife4j-spring-boot3-demo
的web项目,项目结构如下
5.2 添加Knife4j
依赖
⚠️温馨提示
我们这里使用的是SpringBoot3
- Spring Boot 3 只支持
OpenAPI3
规范
Knife4j
提供的starter已经引用springdoc-openapi
的jar,需注意避免jar包冲突
JDK
版本必须 >= 17
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-openapi3-jakarta-spring-boot-starter</artifactId>
<version>4.4.0</version>
</dependency>
5.3 新建hello接口
新建controller
包,添加HelloController
类,代码如下
@RestController
public class HelloController {
@GetMapping("/hello")
public String hello(){
return "hello";
}
}
5.4 访问Knife4j
在线文档
浏览器输入:http://localhost:8080/doc.html 访问在线接口文档
六、Knife4j
常用配置
⚠️温馨提示:
增强功能需要通过配置application.yml配置文件开启增强,后面不再赘述,默认开启
knife4j:
enable: true
6.1 项目配置
在application.yml
中可以自定义api-docs
和swagger-ui
的访问路径。当然了,如果没配置,默认就是下面路径
注:这儿还是兼容swagger ui
页面展示
springdoc:
swagger-ui:
path: /swagger-ui.html
tags-sorter: alpha
operations-sorter: alpha
api-docs:
path: /v3/api-docs
group-configs:
- group: 'default'
paths-to-match: '/**'
packages-to-scan: com.xiezhr.knife4jspringboot3demo.controller
浏览器输入:http://localhost:8080/swagger-ui/index.html 可按照原来ui来显示
6.2 配置接口文档基本信息
① 配置接口基本信息
新建一个config
包—>并在包下建立一个Knife4jConfig
配置类
② 配置接口文档基础信息
这儿我们可以配置接口文档标题、接口文档版本信息、接口文档描述信息、接口文档联系人信息,接口文档license许可证信息
我们只需在配置类中添加如下代码即可
@Configuration
public class Knife4jConfig {
@Bean
public OpenAPI openAPI() {
return new OpenAPI()
.info(this.getApiInfo())
;
}
private Info getApiInfo() {
return new Info()
.title("SpringBoot3集成Knife4j")
.description("SpringBoot3集成Knife4j示例文档")
.contact(new Contact().name("程序员晓凡").url("https://www.xiezhrspace.cn").email("1666397814@163.com"))
.license(new License().name("Apache 2.0").url("https://www.xiezhrspace.cn"))
.summary("SpringBoot3集成Knife4j示例文档aaa")
.termsOfService("https://www.xiezhrspace.cn")
.version("2.0");
}
}
浏览器输入:http://localhost:8080/doc.html 访问显示如下
6.3 i18n国际化
Knife4j
提供了i18n
的支持,支持的语言主要包含2种:中文(zh-CN
)、英文(en-US
)。默认是中文
①通过下拉框选择
通过访问doc.html
打开文档界面,可以在文档的右上角看到语言的选择,如下图:
② 通过文档地址也可以选择
- 中文:
http://host:port/doc.html#/home/zh-CN
- 英文:
http://host:port/doc.html#/home/en-US
另外,如果你是使用了knife4j
提供的增强功能,你也可以这样访问
- 中文:
http://host:port/doc.html#/plus/zh-CN
- 英文:
http://host:port/doc.html#/plus/en-US
③ 通过application.yml
配置文件设置
knife4j:
enable: true
setting:
language: zh_cn
6.4 接口添加作者
接口代码如下,我们给hello接口添加作者“张三”
@ApiOperationSupport(author = "张三")
@GetMapping("/hello")
public String hello(){
return "hello";
}
6.5 自定义文档
有时候在OpenAPI
不足以满足接口说明的情况下,我们可以通过.md
格式文件扩充系统文档说明
①添加自定义文档
我们可以在当前项目中添加多个文件夹,文件夹中存放.md
格式的markdown文件,每个.md
文档代表一份自定义文档说明。
这里,我们在默认组default
下面添加接口签名认证文档说明.md
和自定义文档说明.md
两个文档,结构如下
每个.md
文件中,Knife4j
允许一级(h1)、二级(h2)、三级(h3)标题作为最终的文档标题
比如,上面添加的自定义文档说明.md
内容如下
# 自定义文档说明
## 效果说明
`knife4j`为了满足文档的个性化配置,添加了自定义文档功能
开发者可自定义`md`文件扩展补充整个系统的文档说明
开发者可以在当前项目中添加一个文件夹,文件夹中存放`.md`格式的markdown文件,每个`.md`文档代表一份自定义文档说明
**注意**:自定义文档说明必须以`.md`结尾的文件,其他格式文件会被忽略
② 配置自定义文档显示
文档添加好之后,我们在application.yml
添加如下配置信息
knife4j:
documents:
- group: default
name: 其他文档
# 某一个文件夹下所有的.md文件
locations: classpath:markdown/*
配置说明:
group
: 分组的名称,这儿我们还没有配置分组,所以默认的是default
name
: 界面呈现时菜单显示
locations
: markdown文档路径
③ 前端界面呈现效果
上述信息配置好之后,在浏览器访问doc.html 如下
6.6 访问权限控制
为了保证生产环境下接口服务安全,我们可以提供一个登陆界面的功能,只有输入用户名和密码才能访问
① 在application.yml
中添加如下配置
knife4j:
enable: true
basic:
enable: true
username: xiezhr
password: 123456
②需要输入正确的用户名和密码才能访问
6.7 接口排序
使用Knife4j
提供的增强注解@ApiOperationSupport
中的order字段可进行接口排序
HelloController
中有hello
和 getToken
两个接口,我们要实现getToken
接口显示在前面,代码如下
① 修改application.yml
springdoc:
swagger-ui:
operations-sorter: order
② 调整@ApiOperationSupport
中的order
@RestController
public class HelloController {
@ApiOperationSupport(author = "张三",order = 2)
@GetMapping("/hello")
public String hello(){
return "hello";
}
@ApiOperationSupport(author = "李四" ,order = 1)
@GetMapping("/access-appid")
public String getToken(){
return "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c";
}
}
③ 接口显示顺序如下
6.8 接口分组
为了演示API分组,我们在controller
包下面再建立admin
包和common
包,包下分别添加AdminController
和CommonController
接口类,结构及代码如下
① AdminController
类
@RequestMapping("admin")
@RestController
public class AdminController {
@GetMapping("/access-appid")
public String getToken(){
return "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c";
}
}
② CommonController
类
@RequestMapping("common")
@RestController
public class CommonController {
@GetMapping("/hello")
public String hello(){
return "hello";
}
@GetMapping("/hi")
public String Hi(){
return "Hi 程序员晓凡";
}
}
在默认情况(没有分组)的情况下,所有包下接口都显示在一一个默认组下面,如/common/* 和/admin/* 访问路径下的接口都显示在一起,如下图所示
这时,如果/common/* 下的接口比较多,/admin/* 下的接口也比较多,界面上显示就很混乱
解决办法就是添加分组信息,这里有两种配置方法
① 通过application.yml
配置 admin分组和common 两个分组
springdoc:
group-configs:
- group: 'admin'
paths-to-match: '/admin/**'
packages-to-scan: com.xiezhr.knife4jspringboot3demo.controller
- group: 'common'
paths-to-match: '/common/**'
packages-to-scan: com.xiezhr.knife4jspringboot3demo.controller
② 通过配置类Knife4jConfig
添加两个分组
@Configuration
public class SpringDocConfig {
@Bean("common")
public GroupedOpenApi webGroupApi() {
return GroupedOpenApi.builder().group("common")
.pathsToMatch("/common/**")
.build();
}
@Bean("admin")
public GroupedOpenApi adminGroupApi() {
return GroupedOpenApi.builder().group("admin")
.pathsToMatch("/admin/**")
.build();
}
}
以上两种配置时等效的,再访问:http://localhost:8080/doc.html 显示如下
6.9 动态请求参数
在某些特定的情况下如果后端定义的是一种Map结构,或者是参数并没有定义声明,而希望也能达到一种动态添加参数进行调试的结果,这种体验有点类似于postman
① 开启动态参数配置
knife4j:
enable: true
setting:
# 开启动态请求参数,true-开启,false-关闭
enable-dynamic-parameter: true
配置完后,开启动态请求这个会勾上
② 添加动态参数调试
6.10 过滤请求参数
通常我们在开发接口时,比如一个新增接口和一个修改接口,修改接口需要传递主键id、而新增接口则不需要传递此属性,但大部分情况,我们只写一个Model类,此时在新增接口时显示主键id会显得很多余.
使用自定义增强注解ApiOperationSupport
中的ignoreParameters
属性,可以强制忽略要显示的参数.
忽略的规则如下:
- 例如新增接口时,某实体类不需要显示Id,即可使用该属性对参数进行忽略.
ignoreParameters={"id"}
- 如果存在多个层次的参数过滤,则使用名称.属性的方式,例如
ignoreParameters={"uptModel.id","uptModel.uptPo.id"}
,其中uptModel是实体对象参数名称,id为其属性,uptPo为实体类,作为uptModel类的属性名称
- 如果参数层级只是一级的情况下,并且参数是实体类的情况下,不需要设置参数名称,直接给定属性值名称即可
- 如果实体类属性中是通过List这种数组的方式,那么过滤规则会有所不同,在属性后面需要追加一个下标
[0]
,ignoreParameters={"uptModel.uptPo[0].id"}
在接口过滤时,主要有两种情况
6.10.1 表单参数
我们在使用实体类直接作为参数时,在我们的ui界面中是不会显示参数名称的,此时可以直接使用实体的属性名称进行参数忽略,例如如下代码:
表单类型的请求是不需要添加参数名的
@ApiOperation(value = "新增Model接口1")
@ApiOperationSupport(ignoreParameters = {"id","orderDate.id"})
@PostMapping("/insertMode1l")
public Rest<UptModel> insertModel1(UptModel uptModel){
Rest<UptModel> r =new Rest<>();
r.setData(uptModel);
return r;
}
实体类UptModel.java
文件代码
public class UptModel {
@ApiModelProperty(value = "主键id")
private String id;
@ApiModelProperty(value = "姓名")
private String name;
@ApiModelProperty(value = "邮箱")
private String email;
@ApiModelProperty(value = "订单信息")
private OrderDate orderDate;
}
此时,最终过过滤掉UptModel
的属性id和属性orderDate
类中的id属性,不在界面显示.
6.10.2 JSON参数
如果请求参数是使用JSON的方式
代码如下:
@ApiOperation(value = "新增Model接口")
@ApiOperationSupport(ignoreParameters = {"uptModel.id","uptModel.name","uptModel.orderDate.id"})
@PostMapping("/insertModel")
public Rest<UptModel> insertModel(@RequestBody UptModel uptModel){
Rest<UptModel> r =new Rest<>();
r.setData(uptModel);
return r;
}
此时如果要过滤id的话,需要指定带上参数名称uptModel
最终忽略的值为ignoreParameters = {"uptModel.id","uptModel.name","uptModel.orderDate.id"}
6.11 包含请求参数
时候需要忽略的参数太多时,我们需要写很多的忽略参数属性,此时,一个与忽略参数对立取反的特性就显得很有帮助了
使用自定义增强注解ApiOperationSupport
中的includeParameters
属性,可以强制包含要显示的参数.去除多余的参数
6.12 自定义Host
不同的网络环境,可以通过配置该属性,方便的进行调试
通过配置application.yml
knife4j:
enable: true
setting:
# 是否启用Host
enable-host: true
# 启用Host后地址,例如:http://192.168.0.111:8080
enable-host-text: "http://192.168.0.111:8080"
6.13 全局参数
Knife4j
提供全局参数设置功能,例如:我们可以设置全局token参数
全局参数功能主要提供两种参数类型:
设置方法如下
6.14 自定义主页内容
可以提供一个Markdown文件来自定义显示Home主页的显示内容,通过配置yml来进行开启,配置文件如下
knife4j:
enable: true
setting:
enable-home-custom: true
home-custom-path: classpath:markdown/home.md
enable-home-custom
:该属性为Boolean值,默认false
,如果开发者要自定义主页内容,该选项设置为true
home-custom-path
:提供一个主页的Markdown文件位置
我们markdown目录下添加home.md
文档,并添加内容之后,最终界面显示如下
Knife4j
支持自定义界面底部Footer
内容,可以更改为公司或者产品介绍等信息
未自定义前
通过设置application.yml
后
knife4j:
enable: true
setting:
enable-footer: true
enable-footer-custom: true
footer-custom-content: Apache License 2.0 | Copyright 2019-[程序员晓凡](https://www.xiezhrspace.cn)
七、其他功能
7.1 导出离线文档
使用swagger
的时候,导出一份精细的文档,需要很繁琐的步骤,集成了knife4j
之后,导出文档变得很简单
而且还可以导出不同格式的文档
7.2 导出postman
我们还可以将接口信息复制然后导出到postman工具进行调试
具体操作如下
7.3 生成前端调用代码
八、小结
SpringBoot3
整合knife4j
其实非常简单,界面相对于swagger UI
确实美观了不少。文章只列举了常用功能,如果小伙伴有特殊的需求,可以浏览官方文档,官方文档还是非常详细的。
作者也给出了各种场景的实战demo: https://gitee.com/xiaoym/swagger-bootstrap-ui-demo
SpringBoot
各种版本的整合都有案例
本期内容到这儿就结束了 ★,°:.☆( ̄▽ ̄)/$:.°★ 。 希望对您有所帮助
我们下期再见 (●’◡’●) ヾ(•ω•`)o