大家好,我是晓凡。
写在前面
在上一篇文章,我们详细介绍了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.htmltags-sorter: alphaoperations-sorter: alphaapi-docs:path: /v3/api-docsgroup-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 {@Beanpublic 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许可证信息.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: truesetting: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: defaultname: 其他文档# 某一个文件夹下所有的.md文件locations: classpath:markdown/*
配置说明:
group
: 分组的名称,这儿我们还没有配置分组,所以默认的是default
name
: 界面呈现时菜单显示locations
: markdown文档路径
③ 前端界面呈现效果
上述信息配置好之后,在浏览器访问doc.html 如下
6.6 访问权限控制
为了保证生产环境下接口服务安全,我们可以提供一个登陆界面的功能,只有输入用户名和密码才能访问
① 在application.yml
中添加如下配置
knife4j:enable: truebasic:enable: trueusername: xiezhrpassword: 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: truesetting:# 开启动态请求参数,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: truesetting:# 是否启用Hostenable-host: true# 启用Host后地址,例如:http://192.168.0.111:8080enable-host-text: "http://192.168.0.111:8080"
6.13 全局参数
Knife4j
提供全局参数设置功能,例如:我们可以设置全局token参数
全局参数功能主要提供两种参数类型:
- query(表单)
- header(请求头)
设置方法如下
6.14 自定义主页内容
可以提供一个Markdown文件来自定义显示Home主页的显示内容,通过配置yml来进行开启,配置文件如下
knife4j:enable: truesetting:enable-home-custom: truehome-custom-path: classpath:markdown/home.md
enable-home-custom
:该属性为Boolean值,默认false
,如果开发者要自定义主页内容,该选项设置为true
home-custom-path
:提供一个主页的Markdown文件位置
我们markdown目录下添加home.md
文档,并添加内容之后,最终界面显示如下
6.15 自定义Footer
Knife4j
支持自定义界面底部Footer
内容,可以更改为公司或者产品介绍等信息
未自定义前
通过设置application.yml
后
knife4j:enable: truesetting:enable-footer: trueenable-footer-custom: truefooter-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