Knife4J + Springdoc + SpringBoot2美化Swagger文档

news2024/12/22 18:27:35

前言

我们知道利用Swagger-UI结合Swagger提供的注解,在SpringBoot项目上可以将接口以HTML形式(swagger-ui.html)呈现出来,并且可以在线调试。但是老外的审美和使用习惯可能不太符合中国开发者的喜好。于是Knife4J(https://doc.xiaominfo.com)便诞生了,默认提供的界面通过左侧分组+右侧接口展现的形式十分符合中国开发者的习惯,然后版本太多,官网也是花了大量的篇幅阐述不同版本之间的差异,本文就着重介绍下使用使用SpringBoot2+SpringDoc(https://doc.xiaominfo.com/docs/quick-start#openapi3)的方式来实现OpenAPI3规范的Swagger文档。

添加依赖

<dependency>
    <groupId>com.github.xiaoymin</groupId>
    <artifactId>knife4j-openapi3-spring-boot-starter</artifactId>
    <version>4.5.0</version>
</dependency>

示例接口

org.example.controller.pack1.Demo1.java

package org.example.controller.pack1;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.Data;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.validation.constraints.NotBlank;
import java.util.Collections;
import java.util.List;

@Tag(name = "DEMO1")
@RestController
@RequestMapping("demo1")
public class Demo1 {

    @Operation(summary = "Find Demo1 List")
    @GetMapping("findList")
    public List<Demo1Resp> findList(Demo1Req req) {
        return Collections.EMPTY_LIST;
    }

    @Operation(summary = "Delete Demo1 By ID")
    @DeleteMapping("deleteById")
    public Boolean deleteById(@Parameter(description = "Demo1 ID") Long id) {
        return false;
    }

    @Data
    @Schema(description = "Demo1 Request")
    public static class Demo1Req {

        @NotBlank
        @Schema(description = "Demo1 Code")
        private String code;

        @Schema(description = "Demo1 Name")
        private String name;
    }

    @Data
    @Schema(description = "Demo2 Response")
    public static class Demo1Resp {
        @Schema(description = "Demo1 ID")
        private Long id;

        @Schema(description = "Demo1 Code")
        private String code;

        @Schema(description = "Demo1 Name")
        private String name;
    }
}

org.example.controller.pack2.Demo2.java

package org.example.controller.pack2;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.Data;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.validation.constraints.NotNull;
import java.util.Collections;
import java.util.List;

@Tag(name = "DEMO2")
@RestController
@RequestMapping("demo2")
public class Demo2 {

    @Operation(summary = "Find Demo2 List")
    @GetMapping("/findList")
    public List<Demo2Resp> findList(Demo2Req req) {
        return Collections.EMPTY_LIST;
    }

    @Operation(summary = "Delete Demo2 By ID")
    @DeleteMapping("deleteById")
    public Boolean deleteById(@Parameter(description = "Demo2 ID") Long id) {
        return false;
    }

    @Data
    @Schema(description = "Demo2 Request")
    public static class Demo2Req {

        @NotNull
        @Schema(description = "Demo2 Code")
        private String code;

        @Schema(description = "Demo2 Name")
        private String name;
    }

    @Data
    @Schema(description = "Demo2 Response")
    public static class Demo2Resp {
        @Schema(description = "Demo2 ID")
        private Long id;

        @Schema(description = "Demo2 Code")
        private String code;

        @Schema(description = "Demo2 Name")
        private String name;
    }
}

默认效果

以上的接口代码,在没有做任何配置(包括application.yml和@Configuration配置)的情况
下,打开浏览器访问http://localhost:8080/doc.html将显示以下画面

  • 主页
    在这里插入图片描述
  • Find Demo1 List接口
    在这里插入图片描述
  • Find Demo2 List接口
    在这里插入图片描述
  • Swagger Models
    在这里插入图片描述
    同时,如果访问http://localhost:8080/swagger-ui/index.html,那么默认的Swagger-UI页面也是可以呈现的:
    在这里插入图片描述

Springdoc配置

由于使用该版本的Knife4J是基于Springdoc(https://springdoc.org)的,所以可以使用Springdoc的配置来自定义一部分效果

常用配置

参数名称默认值参数描述
springdoc.api-docs.enabledtrue开始ApiDocs的接口访问,默认地址:/v3/api-docs,关闭后接口文档将无法访问
springdoc.swagger-ui.enabledtrue是否开启Swagger-UI视图,默认地址:/swagger-ui.html, 关闭后接口文档将无法访问
springdoc.packages-to-scan*扫描的包路径,多个用逗号隔开
springdoc.packages-to-exclude包扫描排除的路径,多个用逗号隔开
springdoc.paths-to-match/*扫描的接口URL路径,多个用逗号隔开,支持AntPath形式
springdoc.paths-to-exclude排除的接口URL路径,多个用逗号隔开,支持AntPath形式
springdoc.auto-tag-classestrue是否开启自动Tag(没有@Tag注解类,会将类名以横杠隔开的形式自动生成一个Tag)
springdoc.api-docs.groups.enabledtrue是否允许分组
springdoc.group-configs[0].group分组名称
springdoc.group-configs[0].display-name分组显示名称
springdoc.group-configs[0].packages-to-scan*扫描的包路径,多个用逗号隔开
springdoc.group-configs[0].packages-to-exclude包扫描排除的路径,多个用逗号隔开
springdoc.group-configs[0].paths-to-match/*扫描的接口URL路径,多个用逗号隔开,支持AntPath形式
springdoc.group-configs[0].paths-to-exclude排除的接口URL路径,多个用逗号隔开,支持AntPath形式
springdoc.pre-loading-enabledfalse是否开启预加载,开启后在启动时就会生成OpenApi文档
springdoc.writer-with-order-by-keysfalse接口是否按照字母顺序排序
springdoc.disable-i18nfalse是否禁用国际化
springdoc.default-flat-param-objectfalse扁平显示属性值(开启后直接显示实体内的参数,而不显示实体名称)
springdoc.show-actuatorfalse是否显示Actuator接口路径
springdoc.show-spring-cloud-functionstrue是否显示SpringCloud接口路径

其他配置

其他配置参考官网(https://springdoc.org/#springdoc-openapi-core-properties)

Knife4j增强配置

针对Knife4j的Swagger文档,提供一些个性化的配置:

参数名称默认值参数描述
knife4j.enablefalse是否开启Knife4j增强模式
knife4j.corsfalse是否开启一个默认的跨域配置,该功能配合自定义Host使用
knife4j.productionfalse是否开启生产环境保护
knife4j.basic.enablefalse启用文档BasicHttp校验功能,保护文档
knife4j.basic.usernamebasic用户名
knife4j.basic.passwordbasic密码
knife4j.documents自定义文档集合,该属性是数组
knife4j.documents.group所属分组
knife4j.documents.name类似于接口中的tag,对于自定义文档的分组
knife4j.documents.locationsmarkdown文件路径,可以是一个文件夹(classpath:markdowns/*),也可以是单个文件(classpath:md/sign.md)
knife4j.setting.enable-after-scripttrue调试Tab是否显示AfterScript功能,默认开启
knife4j.setting.languagezh-CNUi默认显示语言,目前主要有两种:中文(zh-CN)、英文(en-US)
knife4j.setting.enable-swagger-modelstrue是否显示界面中SwaggerModel功能
knife4j.setting.swagger-model-nameSwagger Models重命名SwaggerModel名称,默认
knife4j.setting.enable-document-managetrue是否显示界面中"文档管理"功能
knife4j.setting.enable-reload-cache-parameterfalse是否在每个Debug调试栏后显示刷新变量按钮,默认不显示
knife4j.setting.enable-versionfalse是否开启界面中对某接口的版本控制,如果开启,后端变化后Ui界面会存在小蓝点
knife4j.setting.enable-request-cachetrue是否开启请求参数缓存
knife4j.setting.enable-filter-multipart-apisfalse针对RequestMapping的接口请求类型,在不指定参数类型的情况下,如果不过滤,默认会显示7个类型的接口地址参数,如果开启此配置,默认展示一个Post类型的接口地址
knife4j.setting.enable-filter-multipart-api-method-typePOST具体接口的过滤类型
knife4j.setting.enable-hostfalse是否启用自定义Host
knife4j.setting.enable-host-textfalse自定义HOST地址
knife4j.setting.enable-home-customfalse是否开启自定义主页内容
knife4j.setting.home-custom-path主页内容Markdown文件路径
knife4j.setting.enable-searchtrue是否启用UI界面中的搜索框
knife4j.setting.enable-footertrue是否显示Footer
knife4j.setting.enable-footer-customfalse是否开启自定义Footer
knife4j.setting.footer-custom-contentfalse自定义Footer内容
knife4j.setting.enable-dynamic-parameterfalse是否开启动态参数调试功能
knife4j.setting.enable-debugtrue启用调试
knife4j.setting.enable-open-apitrue显示OpenAPI规范
knife4j.setting.enable-grouptrue显示服务分组

推荐配置

application.properties

# 开启预加载
springdoc.pre-loading-enabled = true
# 接口按照字母顺序排序
springdoc.writer-with-order-by-keys = true 

# 接口分组1
springdoc.group-configs[0].group = 分组1
# 分组1包扫描路径
springdoc.group-configs[0].packages-to-scan = org.example.controller.pack1

# 接口分组2
springdoc.group-configs[1].group = 分组2
# 分组2URL匹配路径(支持Ant)
springdoc.group-configs[1].paths-to-match = /demo2/*

# 开启Knife4j增强配置
knife4j.enable = true
#隐藏SwaggerModel功能
knife4j.setting.enable-swagger-models = false
#隐藏OpenApi描述
knife4j.setting.enable-open-api = false
# 显示刷新变量按钮
knife4j.setting.enable-reload-cache-parameter = true 
# 显示接口变化标识
knife4j.setting.enable-version = true
# 生产环境建议开启文档保护
knife4j.basic.enable = true 
# 接口文档访问用户名
knife4j.basic.username = admin 
# 接口文档访问密码
knife4j.basic.password = 123456

application.yaml

springdoc:
  pre-loading-enabled: true #开启预加载
  writer-with-order-by-keys: true #接口按照字母顺序排序
  group-configs:
    - group: 分组1
      packages-to-scan:
        - org.example.controller.pack1 # 分组1包扫描路径
    - group: 分组2
      paths-to-match:
        - /demo2/* # 分组2URL匹配路径(支持Ant)

knife4j:
  enable: true # 开启Knife4j增强配置
  setting:
    enable-swagger-models: false #隐藏SwaggerModel功能
    enable-open-api: false #隐藏OpenApi描述
    enable-reload-cache-parameter: true # 显示刷新变量按钮
    enable-version: true # 显示接口变化标识
  basic:
    enable: true  # 生产环境建议开启文档保护
    username: admin  # 接口文档访问用户名
    password: 123456 # 接口文档访问密码

效果如下
在这里插入图片描述

  • 接口按照包路径或者URL路径分了组
  • 隐藏了Swagger Models
  • 接口按照字母顺序排序
  • OpenApi不显示了
  • 接口调试了多了“刷新变量”按钮

已知问题

在用实体对象接收GET请求的参数时,参数默认会以JSON形式去传递:
在这里插入图片描述
Knife4J对此提供了两种解决方法, 此类接口数量少的情况下推荐第一种(接口参数中增加@ParameterObject注解):

 import org.springdoc.api.annotations.ParameterObject;
 
 @Operation(summary = "Find Demo1 List")
 @GetMapping("findList")
 public List<Demo1Resp> findList(@ParameterObject Demo1Req req) {
     return Collections.EMPTY_LIST;
 }

关于第二种方法,使用将参数拉平的配置:

springdoc.default-flat-param-object = true

GET请求的接口是没问题了,但是POST请求时,默认application/json形式的接口(标记了@RequstBody)也被拉平了。
这个是Springdoc的bug(https://github.com/springdoc/springdoc-openapi/pull/2291), 并且官网也对此进行了修复(https://github.com/springdoc/springdoc-openapi/releases/tag/v1.8.0)。目前Knife4J最新版(4.5.0)使用的版本仍是1.7.0,所以只能是先手动强制更新:
pom.xml

<dependency>
    <groupId>com.github.xiaoymin</groupId>
    <artifactId>knife4j-openapi3-spring-boot-starter</artifactId>
    <version>4.5.0</version>
    <exclusions>
        <exclusion>
            <groupId>org.springdoc</groupId>
            <artifactId>springdoc-openapi-ui</artifactId>
        </exclusion>
    </exclusions>
</dependency>
<dependency>
    <groupId>org.springdoc</groupId>
    <artifactId>springdoc-openapi-ui</artifactId>
    <version>1.8.0</version>
</dependency>

但是呢发现更新后,在解析的时候报以下错误:

java.lang.NoSuchMethodError: org.springdoc.core.SpringDocConfigProperties.getGroupConfigs()Ljava/util/List;
at com.github.xiaoymin.knife4j.spring.extension.Knife4jOpenApiCustomizer.addOrderExtension(Knife4jOpenApiCustomizer.java:80) ~[knife4j-openapi3-spring-boot-starter-4.5.0.jar:na]
at com.github.xiaoymin.knife4j.spring.extension.Knife4jOpenApiCustomizer.customise(Knife4jOpenApiCustomizer.java:70) ~[knife4j-openapi3-spring-boot-starter-4.5.0.jar:na]
at org.springdoc.api.AbstractOpenApiResource.lambda$null$7(AbstractOpenApiResource.java:380) ~[springdoc-openapi-common-1.8.0.jar:1.8.0]

大致看了下源码,springdoc-openapi-common 1.8.0中org.springdoc.core.SpringDocConfigProperties类中的groupConfigs属性类型从原来的List类型换成了Set,所以外面用到的时候出错了。
这时候只能是禁用Knife4J的增强功能了:

knife4j.enable = false

这样两种请求就都可以使用了:
GET(application/x-www-form-urlencoded)
在这里插入图片描述
POST(application/json)
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2106827.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

搜维尔科技:特斯拉人形机器人采用Manus VR数据手套来捕捉手指动作的特点和优势

1.高保真手指追踪&#xff1a;能够提供精确的手指动作捕捉&#xff0c;包括手指的弯曲、伸展、旋转等动作&#xff0c;并且不受遮挡限制。这种高保真的手指追踪能力对于机器人准确模拟人类手部动作至关重要。 2.触觉反馈系统&#xff1a;部分型号的数据手套可能具备触觉反馈功能…

【Python】超详细基础语法总结

Python大礼包&#xff1a;【2024年最新Python全套学习资料包】免费领取&#xff01; 1.字面量 字面量&#xff1a;在代码中&#xff0c;被写下来的固定的值 1.1Python常用的6种值&#xff08;数据&#xff09;的类型 1.2代码练习&#xff08;输出字面量&#xff09; > p…

蓝牙技术|超高精度蓝牙位置服务将成为蓝牙定位产品发展方向

随着市场需求的变化&#xff0c;精确的距离测量成为提升安全性和用户体验的重要因素。预计未来五年蓝牙位置服务设备的年均增长率为22%&#xff0c;到2028年出货量将达到5.63亿台。 为了满足这一需求&#xff0c;SIG即将在2024年下半年推出一项新功能——蓝牙信道探测(Blueto…

C语言6大常用标准库 -- 1.<stdio.h>

目录 引言 1.<stdio.h>&#xff08;标准输入输出库&#xff09; 1.1 简介 1.2 库变量 1.3 库宏 1.4 库函数 &#x1f308;你好呀&#xff01;我是 程序猿 &#x1f30c; 2024感谢你的陪伴与支持 ~ &#x1f680; 欢迎一起踏上探险之旅&#xff0c;挖掘无限可能&am…

电影票API接口对接全攻略,让你轻松对接API

电影票API接口对接是指将第三方电影票销售平台的服务集成到自己的应用程序或网站中&#xff0c;使用户能够直接购买电影票。这种集成通常通过API&#xff08;应用程序编程接口&#xff09;实现。以下是电影票API接口对接的一般步骤和注意事项&#xff1a; 一般步骤&#xff1a…

Trm理论 2(Word2Vec)

神经网络模型&#xff08;NNLM&#xff09;和Word2Vec NNLM模型是上次说过的模型&#xff0c;其目的是为了预测下一个词。 softmax(w2tanh(w1x b1)b2) 会得到一个副产品词向量 而Word2Vue就是专门求词向量的模型 softmax(w2*(w1*x b1)b2) Word2Vec softmax(w2*(w1*x b1)b…

期权虚值和实值的投资风险有什么不同?

今天带你了解期权虚值和实值的投资风险有什么不同&#xff1f;首先虚值期权与实值期权在本质上有一定的区别&#xff0c;两者并不是一个概念。 期权虚值合约 虚值期权又称价外期权&#xff0c;是指不具有内在价值的期权&#xff0c;即行权价高于标的现价的认购期权或行权价低…

stm32之外部flash下载算法

文章目录 下载算法下载到芯片的核心思想算法程序中擦除操作执行流程擦除操作大致流程&#xff1a;算法程序中编程操作执行流程算法程序中校验操作执行流程 创建MDK下载算法通用流程第1步&#xff0c;使用MDK提供好的程序模板第2步&#xff0c;修改工程名第3步&#xff0c;修改使…

【unity小技巧】使用Unity的Animation Layer和Avatar Mask把多个不同动画组合使用,实现人物不同部位播放不同的动画

文章目录 前言如何使用Unity的Animation Layer和Avatar Mask把多个动画组合使用游戏角色的疲劳感是如何制作的&#xff1f;利用Animation Layers中的additive模式把多个动画混合在一起如何制作角色的受伤状态&#xff1f;Unity动画层级&#xff08;Animation Layer&#xff09;…

在stable diffussion中控制生成图片的光线

在摄影中&#xff0c;光线起着至关重要的作用&#xff0c;它对图像的整体质量和氛围有着显著的影响。您可以使用光线来增强主题&#xff0c;创造深度和维度&#xff0c;传达情感&#xff0c;以及突出重要细节。 在这篇文章中&#xff0c;我会告诉你如何在stable diffussion中控…

【C++11】深入理解与应用右值引用

&#x1f525; 个人主页&#xff1a;大耳朵土土垚 &#x1f525; 所属专栏&#xff1a;C从入门至进阶 这里将会不定期更新有关C/C的内容&#xff0c;欢迎大家点赞&#xff0c;收藏&#xff0c;评论&#x1f973;&#x1f973;&#x1f389;&#x1f389;&#x1f389; 文章目录…

webCppCluster

1.通讯协议、接口协议、数据传输格式之间的区别&#xff1f; 通讯协议 在TCP/IP四层模型中&#xff0c;四层分别是&#xff1a;应用层、传输层、网络层、网络接口层。 应用层通讯协议的代表&#xff1a;HTTP HTTPS 主要规定传输消息的具体内容、什么格式传输、是请求还是相应…

ueditorplus百度编辑器集成秀米及135编辑器

备用地址&#xff1a;ueditorplus百度编辑器集成秀米及135编辑器 下载拉取&#xff1a;ueditorplus: UEditorPlus 是基于 UEditor 二次开发的富文本编辑器&#xff0c;让 UEditor 焕然一新,已集成秀米、135编辑器&#xff0c;会不定时更新&#xff01;&#xff01;&#xff01…

MobaXterm 终端工具使用

文章目录 MobaXterm 相关介绍下载安装 MobaXterm添加 SSH 连接 MobaXterm 相关介绍 MobaXterm 是一款功能强大的终端仿真器和远程计算工具&#xff0c;专为 Windows 用户设计&#xff0c;提供了一站式解决方案&#xff0c;以便在本地和远程计算环境中工作。它结合了终端仿真、S…

C++设计模式——Chain of Responsibility职责链模式

一&#xff0c;职责链模式的定义 职责链模式&#xff0c;又被称为责任链模式&#xff0c;是一种行为型设计模式&#xff0c;它让多个对象依次处理收到的请求&#xff0c;直到处理完成为止。 职责链模式需要使用多个对象&#xff0c;其中的每个对象要么处理请求&#xff0c;要…

『功能项目』坐骑UI搭建及脚本控制显/隐【19】

本章项目成果展示 我们打开上一篇18怪物消亡掉落宝箱的项目&#xff0c; 本章要做的事情是搭建一个坐骑UI界面&#xff0c;并通过键盘B键/右侧坐骑按钮控制坐骑UI界面的显示与隐藏 在背包Bag上创建一个父物体&#xff0c; 命名为Middle 修改Bag的尺寸 将下面资源图片放进Art文…

开源|FormCreate低代码表单在弹窗中渲染表单时表单的值没有正常清空解决方法

如何在弹窗中通过低代码表单 FormCreate 渲染表单&#xff0c;包括表单的配置、表单验证、以及表单提交的处理。 源码地址: Github | Gitee <template><div><!-- 触发弹窗的按钮 --><el-button type"primary" click"showDialog true&quo…

国家商用密码算法——SM1、SM2、SM3

1、SM1 SM1 是中国国家密码管理局&#xff08;SCA&#xff09;发布的国密算法之一&#xff0c;属于对称加密算法&#xff0c;其分组长度、秘钥长度都是128bit。 【注】对称加密算法是一种使用相同密钥进行数据加密和解密的加密方式。在这种算法中&#xff0c;发送方和接收方共…

将本地的 IntelliJ IDEA 项目导入到 GitLab 上——超详细图文教程

要将本地的 IntelliJ IDEA 项目导入到 GitLab 上&#xff0c;可以按照以下详细步骤进行操作&#xff1a; 1. 在 GitLab 上创建一个新的仓库 打开 GitLab 或公司内部的 GitLab 服务器。 登录你的 GitLab 账号。 点击右上角的 号按钮&#xff0c;然后选择 “New Project”。 …

清华MEM作业-利用管理运筹学的分析工具slover求解最优解的实现 及 通过使用文件或者套节字来识别进程的fuser命令

一、清华MEM作业-利用管理运筹学的分析工具slover求解最优解的实现 最近又接触了一些线性求解的问题&#xff0c;以前主要都是在高中数学里接触到&#xff0c;都是使用笔算&#xff0c;最后通过一些函数式得出最小或者最大值&#xff0c;最近的研究生学业上接触到了一个Excel s…