SpringBoot集成Swagger2的增强版Knife4j

news2024/10/5 16:29:32

1. 背景

作为SpringBoot集成中间件其中的一篇文章吧,既然打算出这么一个系列了,争取做到虽小却全,又精又美的一个系列吧。

Swagger应该都有接触吧,knife4j是Swagger2的增强版,更加友好的操作页面,更多强大的功能,基于Swagger2和 OpenAPI,提供了一个更好的接口文档界面,本文主要演示了如何使用SpringBoot集成Knife4j。

本文拆分自笑小枫-SpringBoot系列 , 更为精简的介绍了SpringBoot如何集成中间件。如果想系统的使用SpringBoot,可以参考笑小枫-SpringBoot系列

  • Spring Boot版本: 2.7.12
  • Knife4j版本: 4.4.0

2. 配置后端接口

2.1 什么是knife4j😴

先贴官网Knife4j

Knife4j是一个集Swagger2 和 OpenAPI3 为一体的增强解决方案。

增强扩展

  • 基础ui组件(自定义文档、动态参数调试、I18n、接口排序、导出等)
  • 基于Springfox框架+Swagger2规范的自动注入starter
  • 基于Springdoc-openapi+OAS3规范的自动注入starter
  • 提供对主流网关组件的统一聚合OpenAPI接口文档的解决方案

2.2 怎么使用knife4j🎨

版本选择

关于版本,可以前往官网查看 Knife4j版本参考

Spring Boot 3

  • Spring Boot 3 只支持OpenAPI3规范
  • Knife4j提供的starter已经引用springdoc-openapi的jar,开发者需注意避免jar包冲突
  • JDK版本必须 >= 17

Spring Boot 2

  • Spring Boot 版本建议 2.4.0~3.0.0之间
  • Spring Boot 版本 < 2.4 版本则建议选择Knife4j 4.0之前的版本

👉第一步:在maven项目的pom.xml中引入Knife4j的依赖包,代码如下:👇

        <!-- 引入knife4j依赖 -->
        <dependency>
            <groupId>com.github.xiaoymin</groupId>
            <artifactId>knife4j-openapi2-spring-boot-starter</artifactId>
            <version>4.4.0</version>
        </dependency>

👉第二步:创建Swagger配置依赖,代码如下:👇

package com.maple.knife4j.config;

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.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2WebMvc;

/**
 * @author 笑小枫 <https://www.xiaoxiaofeng.com/>
 * @date 2023/12/21
 */
@Configuration
@EnableSwagger2WebMvc
public class Knife4jConfiguration {

    /**
     * 接口分类:配置模块一的接口
     * 如果只有一个模块,删掉模块二即可
     * 如果有多个,可以继续配置
     */
    @Bean(value = "exampleOne")
    public Docket exampleOne() {
        return new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(new ApiInfoBuilder()
                        .title("笑小枫演示接口1")
                        .description("笑小枫演示接口1")
                        .termsOfServiceUrl("http://127.0.0.1:8080")
                        .contact(new Contact("笑小枫", "https://www.xiaoxiaofeng.com", "zfzjava@163.com"))
                        .version("1.0")
                        .build())
                //分组名称
                .groupName("笑小枫演示接口1")
                .select()
                //这里指定Controller扫描包路径
                .apis(RequestHandlerSelectors.basePackage("com.maple.knife4j.controller.one"))
                .paths(PathSelectors.any())
                .build();
    }

    /**
     * 接口分类:配置模块二的接口
     */
    @Bean(value = "exampleTwo")
    public Docket exampleTwo() {
        return new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(new ApiInfoBuilder()
                        .title("笑小枫演示接口2")
                        .description("笑小枫演示接口2")
                        .termsOfServiceUrl("http://127.0.0.1:8080")
                        .contact(new Contact("笑小枫", "https://www.xiaoxiaofeng.com", "zfzjava@163.com"))
                        .version("1.0")
                        .build())
                //分组名称
                .groupName("笑小枫演示接口2")
                .select()
                //这里指定Controller扫描包路径
                .apis(RequestHandlerSelectors.basePackage("com.maple.rest.controller.two"))
                .paths(PathSelectors.any())
                .build();
    }
}

👉第三步:创建两个不同目录的Controller,模拟上面的两个模块👇

com.maple.knife4j.controller.one.TestKnife4jOneController

package com.maple.knife4j.controller.one;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import io.swagger.annotations.ApiOperation;
import lombok.Data;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author 笑小枫 <https://www.xiaoxiaofeng.com/>
 * @date 2023/12/21
 */
@Api(tags = "实例演示1-Knife4j接口文档")
@RestController
@RequestMapping("/one")
public class TestKnife4jOneController {

    @ApiOperation(value = "Knife4j接口文档演示")
    @GetMapping("/testKnife4j")
    public User testKnife4j(User param) {
        User user = new User();
        user.setName("笑小枫");
        user.setAge(18);
        user.setRemark("大家好,我是笑小枫,喜欢我的小伙伴点个赞呗,欢迎访问我的个人博客:https://www.xiaoxiaofeng.com");
        return user;
    }

    @Data
    @ApiModel("用户对象")
    static class User {
        @ApiModelProperty(value = "姓名")
        private String name;

        @ApiModelProperty(value = "年龄")
        private Integer age;

        @ApiModelProperty(value = "描述")
        private String remark;
    }
}

com.maple.knife4j.controller.one.TestKnife4jTwoController

package com.maple.knife4j.controller.two;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import io.swagger.annotations.ApiOperation;
import lombok.Data;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author 笑小枫 <https://www.xiaoxiaofeng.com/>
 * @date 2023/12/21
 */
@Api(tags = "实例演示2-Knife4j接口文档")
@RestController
@RequestMapping("/two")
public class TestKnife4jTwoController {

    @ApiOperation(value = "Knife4j接口文档演示")
    @GetMapping("/testKnife4j")
    public User testKnife4j(User param) {
        User user = new User();
        user.setName("笑小枫");
        user.setAge(18);
        user.setRemark("大家好,我是笑小枫,喜欢我的小伙伴点个赞呗,欢迎访问我的个人博客:https://www.xiaoxiaofeng.com");
        return user;
    }

    @Data
    @ApiModel("用户对象")
    static class User {
        @ApiModelProperty(value = "姓名")
        private String name;

        @ApiModelProperty(value = "年龄")
        private Integer age;

        @ApiModelProperty(value = "描述")
        private String remark;
    }
}

2.3 看下页面效果👌

项目启动后,在浏览器输入http://127.0.0.1:6666/doc.html访问

image-20231221173516411

接口调试:

image-20231221173619001

2.4 增强模式😦

更多的增强模式使用可以参考官方文档增强模式

Knife4j自2.0.6版本开始,将目前在Ui界面中一些个性化配置剥离,开发者可以在后端进行配置,并且提供的knife4j-spring-boot-strater组件自动装载

spring.factories配置如下:

# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.github.xiaoymin.knife4j.spring.configuration.Knife4jAutoConfiguration

在Spring Boot配置文件中,完整的配置如下:

knife4j:
  enable: true
  documents:
    -
      group: 2.X版本
      name: 接口签名
      locations: classpath:sign/*
  setting:
    language: zh-CN
    enableSwaggerModels: true
    enableDocumentManage: true
    swaggerModelName: 实体类列表
    enableVersion: false
    enableReloadCacheParameter: false
    enableAfterScript: true
    enableFilterMultipartApiMethodType: POST
    enableFilterMultipartApis: false
    enableRequestCache: true
    enableHost: false
    enableHostText: 192.168.0.193:8000
    enableHomeCustom: true
    homeCustomLocation: classpath:markdown/home.md
    enableSearch: false
    enableFooter: false
    enableFooterCustom: true
    footerCustomContent: Copyright  2022-[笑小枫](https://www.xiaoxiaofeng.com)
    enableDynamicParameter: false
    enableDebug: true
    enableOpenApi: false
    enableGroup: true
  cors: false
  production: false
  basic:
    enable: false
    username: test
    password: 123123

在以前的版本中,开发者需要在配置文件中手动使用@EnableKnife4j来使用增强,自2.0.6版本后,只需要在配置文件中配置knife4j.enable=true即可不在使用注解

注意:要使用Knife4j提供的增强,knife4j.enable=true必须开启

各个配置属性说明如下:

属性默认值说明值
knife4j.enablefalse是否开启Knife4j增强模式
knife4j.corsfalse是否开启一个默认的跨域配置,该功能配合自定义Host使用
knife4j.productionfalse是否开启生产环境保护策略,详情参考文档
knife4j.basic对Knife4j提供的资源提供BasicHttp校验,保护文档
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前端Ui的个性化配置属性
knife4j.setting.enableAfterScripttrue调试Tab是否显示AfterScript功能,默认开启
knife4j.setting.languagezh-CNUi默认显示语言,目前主要有两种:中文(zh-CN)、英文(en-US)
knife4j.setting.enableSwaggerModelstrue是否显示界面中SwaggerModel功能
knife4j.setting.swaggerModelNameSwagger Models重命名SwaggerModel名称,默认
knife4j.setting.enableDocumentManagetrue是否显示界面中"文档管理"功能
knife4j.setting.enableReloadCacheParameterfalse是否在每个Debug调试栏后显示刷新变量按钮,默认不显示
knife4j.setting.enableVersionfalse是否开启界面中对某接口的版本控制,如果开启,后端变化后Ui界面会存在小蓝点
knife4j.setting.enableRequestCachetrue是否开启请求参数缓存
knife4j.setting.enableFilterMultipartApisfalse针对RequestMapping的接口请求类型,在不指定参数类型的情况下,如果不过滤,默认会显示7个类型的接口地址参数,如果开启此配置,默认展示一个Post类型的接口地址
knife4j.setting.enableFilterMultipartApiMethodTypePOST具体接口的过滤类型
knife4j.setting.enableHostfalse是否启用Host
knife4j.setting.enableHomeCustomfalse是否开启自定义主页内容
knife4j.setting.homeCustomLocation主页内容Markdown文件路径
knife4j.setting.enableSearchfalse是否禁用Ui界面中的搜索框
knife4j.setting.enableFootertrue是否显示Footer
knife4j.setting.enableFooterCustomfalse是否开启自定义Footer
knife4j.setting.footerCustomContentfalse自定义Footer内容
knife4j.setting.enableDynamicParameterfalse是否开启动态参数调试功能
knife4j.setting.enableDebugtrue启用调试
knife4j.setting.enableOpenApitrue显示OpenAPI规范
knife4j.setting.enableGrouptrue显示服务分组

关于个性化文档(knife4j.documents)以及个性化设置(knife4j.setting),有一些细微的区别,开发者在配置文件中进行配合好后,还需要在创建Docket对象时调用Knife4j提供的扩展Extesions进行赋值

示例代码如下:

package com.maple.knife4j.config;

import com.github.xiaoymin.knife4j.spring.extension.OpenApiExtensionResolver;
import lombok.AllArgsConstructor;
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.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2WebMvc;

/**
 * @author 笑小枫 <https://www.xiaoxiaofeng.com/>
 * @date 2023/12/21
 */
@Configuration
@EnableSwagger2WebMvc
@AllArgsConstructor
public class Knife4jConfiguration {

    /**
     * 引入Knife4j提供的扩展类
     */
    private final OpenApiExtensionResolver openApiExtensionResolver;

    /**
     * 接口分类:配置模块一的接口
     * 如果只有一个模块,删掉模块二即可
     * 如果有多个,可以继续配置
     */
    @Bean(value = "exampleOne")
    public Docket exampleOne() {
        return new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(new ApiInfoBuilder()
                        .title("笑小枫演示接口1")
                        .description("笑小枫演示接口1")
                        .termsOfServiceUrl("http://127.0.0.1:8080")
                        .contact(new Contact("笑小枫", "https://www.xiaoxiaofeng.com", "zfzjava@163.com"))
                        .version("1.0")
                        //赋予插件体系
                        .build()
                )
                //分组名称
                .groupName("笑小枫演示接口1")
                .select()
                //这里指定Controller扫描包路径
                .apis(RequestHandlerSelectors.basePackage("com.maple.knife4j.controller.one"))
                .paths(PathSelectors.any())
                .build()
                //赋予插件体系
                .extensions(openApiExtensionResolver.buildExtensions("笑小枫演示接口1"));
    }

    /**
     * 接口分类:配置模块二的接口
     */
    @Bean(value = "exampleTwo")
    public Docket exampleTwo() {
        return new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(new ApiInfoBuilder()
                        .title("笑小枫演示接口2")
                        .description("笑小枫演示接口2")
                        .termsOfServiceUrl("http://127.0.0.1:8080")
                        .contact(new Contact("笑小枫", "https://www.xiaoxiaofeng.com", "zfzjava@163.com"))
                        .version("1.0")
                        .build())
                //分组名称
                .groupName("笑小枫演示接口2")
                .select()
                //这里指定Controller扫描包路径
                .apis(RequestHandlerSelectors.basePackage("com.maple.rest.controller.two"))
                .paths(PathSelectors.any())
                .build();
    }
}

buildExtensions方法需要传入分组名称,该分组名称主要是为了区分开发者在构建自定义文档时,在不同的Docket逻辑分组下进行区别显示。

OpenApiExtensionResolver辅助类需要配置knife4j.enable=true才能自动@Autowired

增强效果开启后,在最终调用接口时,Knife4j会添加扩展属性x-openapi,如下图:

image-20220630132424363

更多功能,请参考官方文档:https://doc.xiaominfo.com/knife4j/

3. 项目源码💕

本文到此就结束了,如果帮助到你了,帮忙点个赞👍

本文源码:https://github.com/hack-feng/maple-product/tree/main/maple-knife4j

🐾我是笑小枫,全网皆可搜的【笑小枫】

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

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

相关文章

瑞_力扣LeetCode_二叉树相关题

文章目录 说明题目 144. 二叉树的前序遍历题解 题目 94. 二叉树的中序遍历题解 题目 145. 二叉树的后序遍历题解 题目 105. 从前序与中序遍历序列构造二叉树题解 题目 106. 从中序与后序遍历序列构造二叉树题解 &#x1f64a; 前言&#xff1a;本文章为瑞_系列专栏之《刷题》的…

NAT几种模式的简介

静态NAT&#xff08;不转换端口号&#xff09;也叫一对一NAT&#xff0c;固定对应关系&#xff1a;内部网络服务器对外提供服务。 动态NAT之NO-PAT&#xff08;不转换端口号&#xff09;&#xff0c;一对多。 动态NAT之NAPT&#xff08;转换端口号&#xff09;&#xff0c;一对…

《Git 简易速速上手小册》第2章:理解版本控制(2024 最新版)

文章目录 2.1 本地仓库与版本历史2.1.1 基础知识讲解2.1.2 重点案例&#xff1a;回滚错误提交2.1.3 拓展案例 1&#xff1a;利用 git bisect 查找引入 bug 的提交2.1.4 拓展案例 2&#xff1a;合并提交历史 2.2 远程仓库的使用2.2.1 基础知识讲解2.2.2 重点案例&#xff1a;在 …

2024年龙年春节热点!过年期间想股票开户可以吗?怎么找到低佣金开户渠道?

股票投资技巧可以帮助投资者在股票市场中进行更明智的决策和更有效的操作。以下是一些常见的股票投资技巧&#xff1a; 研究和分析&#xff1a;在购买股票之前&#xff0c;投资者应该进行充分的研究和分析。这包括了解公司的基本面&#xff0c;如财务状况、业务模式和竞争优势等…

modelsim仿真使用到vivado的IP,该如何使用!

modelsim仿真时&#xff0c;如果使用到了vivado的IP就会报错&#xff0c;本次就告诉大家如何将vivado的IP添加到modelsim中直接仿真。 一、生成ini文件以及IP打包 打开vivado&#xff0c;点击上方的Tools-->Compile Simulation Libraries得到如下界面 simulator&#xff1…

【Linux】基于管道进行进程间通信

进程间通信 一、初识进程间通信1. 进程间通信概念2. 进程间通信分类 二、管道1. 管道概念2. 管道原理3. 匿名管道4. 匿名管道系统接口5. 管道的特性和情况6. 匿名管道的应用&#xff08;1&#xff09;命令行&#xff08;2&#xff09;进程池 7. 命名管道&#xff08;1&#xff…

机器人运动学林沛群——变换矩阵

对于仅有移动&#xff0c;由上图可知&#xff1a; A P B P A P B o r g ^AP^BP^AP_{B org} APBPAPBorg​ 对于仅有转动&#xff0c;可得&#xff1a; A P B A R B P ^AP^A_BR^BP APBA​RBP 将转动与移动混合后&#xff0c;可得&#xff1a; 一个例子 在向量中&#xff…

电力负荷预测 | 电力系统负荷预测模型(Python线性回归、随机森林、支持向量机、BP神经网络、GRU、LSTM)

文章目录 效果一览文章概述源码设计参考资料效果一览 文章概述 电力系统负荷预测模型(Python线性回归、随机森林、支持向量机、BP神经网络、GRU、LSTM) 所谓预测,就是指通过对事物进行分析及研究,并运用合理的方法探索事物的发展变化规律,对其未来发展做出预先估计和判断。…

Linux系统调试课:CPU 利用率中softirq飙高情况分析

文章目录 <font color=#0990d9>一、细化 CPU 利用率监控<font color=#0990d9>二、softirq飙高观测<font color=#0990d9>三、ksoftirqd机制沉淀、分享、成长,让自己和他人都能有所收获!😄 CPU 利用率是一个很笼统的概念,在遇到 CPU 利用率飙高的问题时,…

Spring Boot的打包方式:JAR vs. WAR 打包方式

Spring Boot的打包方式&#xff1a;JAR vs. WAR 打包方式 Spring Boot是一个流行的Java开发框架&#xff0c;提供了快速、便捷的应用程序开发和部署方式。本文将介绍Spring Boot的两种常见打包方式&#xff1a;JAR和WAR。我们将深入探讨它们的特点、适用场景和部署方式&#xf…

BUGKU-WEB 留言板

题目描述 题目无需登录后台&#xff01;需要xss平台接收flag&#xff0c; http协议需要http协议的xss平台打开场景后界面如下&#xff1a; 解题思路 看到此类的题目&#xff0c;应该和存储型xss有关&#xff0c;也就是将恶意代码保存到服务器端即然在服务器端&#xff0c;那就…

Linux操作系统基础(一):操作系统概述

文章目录 操作系统概述 一、计算机分类 二、计算机组成 三、操作系统概述 四、操作系统分类 操作系统概述 一、计算机分类 计算机一般分为个人计算机&#xff08;笔记、台式机&#xff09;与 企业级服务器&#xff08;1U、2U、机柜、塔式、刀片&#xff09;两种形式。 二…

初识C语言·预处理详解

目录 1 预定义符号 2 define定义常量 3 #define定义宏 4 带有副作用的宏 5 宏替换的规则 6 宏和函数的对比 7 # 和 ## i) #运算符 ii) ##运算符 8 命名约定 9 命令行定义 10 条件编译 条件编译1&#xff1a; 条件编译2&#xff1a; 条件编译3&#xff1a; 条件…

Vue源码系列讲解——变化侦测篇【下】(Array的变化侦测)

目录 1. 前言 2. 在哪里收集依赖 3. 使Array型数据可观测 3.1 思路分析 3.2 数组方法拦截器 3.3 使用拦截器 4. 再谈依赖收集 4.1 把依赖收集到哪里 4.2 如何收集依赖 4.3 如何通知依赖 5. 深度侦测 6. 数组新增元素的侦测 7. 不足之处 8. 总结 1. 前言 上一篇文…

gh0st远程控制——客户端界面编写(三)

◉ 主控端界面添加右键弹出菜单的功能 为Onlie_List区域添加右键弹出菜单项的功能&#xff1a; 3个视图&#xff1a;类视图、解决方案视图、资源视图 在资源视图下添加一个Menu&#xff1a; 更改Menu的ID为IDR_MENU_ONLINE&#xff1a; 为各控件添加便于区分的ID&#xff1a…

SERVLET线程模型

1. SERVLET线程模型 Servlet规范定义了两种线程模型来阐明Web容器应该如何在多线程环境中处理servlet。第一种模型称为多线程模型,默认在此模型内执行所有servlet。在此模型中,每次客户机向servlet发送请求时Web容器都启动一个新线程。这意味着可能有多个线程同时访问servle…

【高阶数据结构】B-树详解

文章目录 1. 常见的搜索结构2. 问题提出使用平衡二叉树搜索树的缺陷使用哈希表的缺陷 3. B-树的概念4. B-树的插入分析插入过程分析插入过程总结 5. B-树的代码实现5.1 B-树的结点设计5.2 B-树的查找5.3 B-树的插入实现InsertKey插入和分裂测试 6. B-树的删除&#xff08;思想&…

机器人工具箱学习(一)

一、机器人工具箱介绍 机器人工具箱是由来自昆士兰科技大学的教授Peter Corke开发的&#xff0c;被广泛用于机器人进行仿真&#xff08;主要是串联机器人&#xff09;。该工具箱支持机器人一些基本算法的功能&#xff0c;例如三维坐标中的方向表示&#xff0c;运动学、动力学模…

软件定义网络 SDN 简介、OpenFlow

目录 软件定义网络 SDN 简介 1 SDN 与 协议 OpenFlow 1.1 SDN 1.2 OpenFlow 1.2.1 协议 OpenFlow 1.2.2 OpenFlow 数据层面 &#xff08;1&#xff09;匹配 动作 &#xff08;2&#xff09;流表 1.流表由远程控制器管理 2.流表结构 2 SDN 体系结构 3 SDN 控制器 软…

Matplotlib雷达图教程:学会绘制炫酷多彩的多维数据可视化【第53篇—python:Seaborn大全】

文章目录 Matplotlib雷达图绘制指南&#xff1a;炫酷雷达图参数解析与实战1. 普通雷达图2. 堆叠雷达图3. 多个雷达图4. 矩阵雷达图5. 极坐标雷达图6. 定制化雷达图外观7. 调整雷达图坐标轴范围8. 雷达图的子图布局9. 导出雷达图总结 Matplotlib雷达图绘制指南&#xff1a;炫酷雷…