嘘~ 小破站正在拼命加载中 . . .

SpringBoot3整合Knife4j


大家好,我是晓凡。

写在前面

在上一篇文章,我们详细介绍了SpringBoot3 怎么整合SpringDoc实现在线接口文档。但是,有不少小伙伴

都觉得接口界面太丑了。有没有什么更美观一点的UI界面呢?

当然是有的了,毕竟这是一个看脸的时代,Knife4j 这不来了么。

一、界面比较

这儿我们将上一篇文章使用swagger UIKnife4j UI做一个比较,哪个好看就不用我多说了吧。

swaggerUI界面

swaggerUI界面

Knife4j 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 UIKnife4j 提供了更加人性化和美观的界面设计
  • 丰富的文档交互功能:支持在线调试、请求参数动态输入、接口排序等
  • 个性化配置:可自定义 API 文档的界面风格,实现文档界面的个性化展示

四、Knife4j版本介绍

目前,我们使用的SpringBoot 版本主要是2和3,不同的boot版本需要适配不同版本的Knife4j.

通过这一小节,我们将在项目中选择合适的Knife4j版本

4.1 Knife4j的前世今生

在更名为Knife4j之前,原来的名称是叫swagger-bootstrap-ui,这是两种不一样风格的Ui,区别如下

名称 开发语言&框架 状态 最后版本 风格
Knife4j JavaJavaScriptVue 持续更新中… 黑色
swagger-bootstrap-ui JavaJavaScriptjQuery 停更 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 &#123;
    @GetMapping("/hello")
    public String hello()&#123;
        return "hello";
    &#125;
&#125;

5.4 访问Knife4j在线文档

浏览器输入:http://localhost:8080/doc.html 访问在线接口文档

在线接口文档

六、Knife4j 常用配置

⚠️温馨提示:

增强功能需要通过配置application.yml配置文件开启增强,后面不再赘述,默认开启

knife4j:
  enable: true

6.1 项目配置

application.yml中可以自定义api-docsswagger-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来显示

swagger-ui

6.2 配置接口文档基本信息

① 配置接口基本信息

新建一个config包—>并在包下建立一个Knife4jConfig配置类

Knife4jConfig配置类

② 配置接口文档基础信息

这儿我们可以配置接口文档标题、接口文档版本信息、接口文档描述信息、接口文档联系人信息,接口文档license许可证信息

我们只需在配置类中添加如下代码即可

@Configuration
public class Knife4jConfig &#123;

    @Bean
    public OpenAPI openAPI() &#123;
        return new OpenAPI()
                // 配置接口文档基本信息
                .info(this.getApiInfo())
                ;
    &#125;

    private Info getApiInfo() &#123;
        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");
    &#125;
&#125;

浏览器输入: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()&#123;
    return "hello";
&#125;

接口作者

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 中有hellogetToken 两个接口,我们要实现getToken接口显示在前面,代码如下

① 修改application.yml

springdoc:
  swagger-ui:
    operations-sorter: order

② 调整@ApiOperationSupport中的order

@RestController
public class HelloController &#123;
    @ApiOperationSupport(author = "张三",order = 2)
    @GetMapping("/hello")
    public String hello()&#123;
        return "hello";
    &#125;

    @ApiOperationSupport(author = "李四" ,order = 1)
    @GetMapping("/access-appid")
    public String getToken()&#123;

        return "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c";
    &#125;
&#125;

③ 接口显示顺序如下

接口排序

6.8 接口分组

为了演示API分组,我们在controller包下面再建立admin包和common包,包下分别添加AdminControllerCommonController接口类,结构及代码如下

image-20240630152601955

AdminController

@RequestMapping("admin")
@RestController
public class AdminController &#123;

    @GetMapping("/access-appid")
    public String getToken()&#123;

        return "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c";
    &#125;
&#125;

CommonController

@RequestMapping("common")
@RestController
public class CommonController &#123;

    @GetMapping("/hello")
    public String hello()&#123;
        return "hello";
    &#125;

    @GetMapping("/hi")
    public String Hi()&#123;
        return "Hi 程序员晓凡";
    &#125;
&#125;

在默认情况(没有分组)的情况下,所有包下接口都显示在一一个默认组下面,如/common/* 和/admin/* 访问路径下的接口都显示在一起,如下图所示

default分组

这时,如果/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 &#123;
  // 此处省去其他配置信息......
    
    @Bean("common")
    public GroupedOpenApi webGroupApi() &#123;
        return GroupedOpenApi.builder().group("common")
                .pathsToMatch("/common/**")
                .build();
    &#125;

    @Bean("admin")
    public GroupedOpenApi adminGroupApi() &#123;
        return GroupedOpenApi.builder().group("admin")
                .pathsToMatch("/admin/**")
                .build();
    &#125;

&#125;

以上两种配置时等效的,再访问: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 = &#123;"id","orderDate.id"&#125;)
@PostMapping("/insertMode1l")
public Rest<UptModel> insertModel1(UptModel uptModel)&#123;
    Rest<UptModel> r =new Rest<>();
    r.setData(uptModel);
    return r;
&#125;

实体类UptModel.java文件代码

public class UptModel &#123;

    @ApiModelProperty(value = "主键id")
    private String id;

    @ApiModelProperty(value = "姓名")
    private String name;

    @ApiModelProperty(value = "邮箱")
    private String email;

    @ApiModelProperty(value = "订单信息")
    private OrderDate orderDate;
&#125;

此时,最终过过滤掉UptModel的属性id和属性orderDate类中的id属性,不在界面显示.

img

6.10.2 JSON参数

如果请求参数是使用JSON的方式

代码如下:

@ApiOperation(value = "新增Model接口")
@ApiOperationSupport(ignoreParameters = &#123;"uptModel.id","uptModel.name","uptModel.orderDate.id"&#125;)
@PostMapping("/insertModel")
public Rest<UptModel> insertModel(@RequestBody UptModel uptModel)&#123;
    Rest<UptModel> r =new Rest<>();
    r.setData(uptModel);
    return r;
&#125;

此时如果要过滤id的话,需要指定带上参数名称uptModel

最终忽略的值为ignoreParameters = {"uptModel.id","uptModel.name","uptModel.orderDate.id"}

img

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参数

全局参数功能主要提供两种参数类型:

  • query(表单)
  • header(请求头)

设置方法如下

全局参数设置

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 文档,并添加内容之后,最终界面显示如下

home.md

最终显示效果

6.15 自定义Footer

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)

image-20240630174827521

七、其他功能

7.1 导出离线文档

使用swagger的时候,导出一份精细的文档,需要很繁琐的步骤,集成了knife4j之后,导出文档变得很简单

而且还可以导出不同格式的文档

离线文档

7.2 导出postman

我们还可以将接口信息复制然后导出到postman工具进行调试

具体操作如下

导出postman

7.3 生成前端调用代码

生成前端调用代码

八、小结

SpringBoot3 整合knife4j其实非常简单,界面相对于swagger UI 确实美观了不少。文章只列举了常用功能,如果小伙伴有特殊的需求,可以浏览官方文档,官方文档还是非常详细的。

作者也给出了各种场景的实战demo: https://gitee.com/xiaoym/swagger-bootstrap-ui-demo

SpringBoot各种版本的整合都有案例

各种场景整合

本期内容到这儿就结束了 ★,°:.☆( ̄▽ ̄)/$:.°★ 。 希望对您有所帮助

我们下期再见 (●’◡’●) ヾ(•ω•`)o


文章作者: xiezhr
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 xiezhr !
评论
  目录