knife4j接口文档
knife4j是为Java MVC框架集成Swagger生成Api文档的增强解决方案,前身是swagger-bootstrap-ui,取名knife4j是希望它能像一把匕首一样小巧,轻量,并且功能强悍!其底层是对Springfox的封装,使用方式也和Springfox一致,只是对接口文档UI进行了优化。
核心功能:
-
文档说明:根据Swagger的规范说明,详细列出接口文档的说明,包括接口地址、类型、请求示例、请求参数、响应示例、响应参数、响应码等信息,对该接口的使用情况一目了然。
-
在线调试:提供在线接口联调的强大功能,自动解析当前接口参数,同时包含表单验证,调用参数可返回接口响应内容、headers、响应时间、响应状态码等信息,帮助开发者在线调试。
入门案例:
1.创建spring-boot工程knife4j_demo并配置pom.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.2.2.RELEASE</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.example</groupId><artifactId>knife4j_demo</artifactId><version>0.0.1-SNAPSHOT</version><name>knife4j_demo</name><description>Demo project for Spring Boot</description><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>com.github.xiaoymin</groupId><artifactId>knife4j-spring-boot-starter</artifactId><version>2.0.1</version></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency></dependencies>
</project>
从依赖关系中也能看出它是对Springfox的封装,因此使用方式一直

2.创建实体类User和Order和接口UserController和OrderController,并使用swagger的注解
3.创建配置属性类SwaggerProperties
package com.example.config;import lombok.*;
import org.springframework.boot.context.properties.ConfigurationProperties;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;/**配置属性类,用于封装接口文档相关属性,从配置文件读取信息封装成当前对象*/@Data
@ConfigurationProperties(prefix = "myknife4j.swagger")
public class SwaggerProperties {private String title = "在线文档"; //标题private String group = ""; //自定义组名private String description = "在线文档"; //描述private String version = "1.0"; //版本private Contact contact = new Contact(); //联系人private String basePackage = ""; //swagger会解析的包路径private List<String> basePath = new ArrayList<>(); //swagger会解析的url规则private List<String> excludePath = new ArrayList<>();//在basePath基础上需要排除的url规则private Map<String, DocketInfo> docket = new LinkedHashMap<>(); //分组文档public String getGroup() {if (group == null || "".equals(group)) {return title;}return group;}@Datapublic static class DocketInfo {private String title = "在线文档"; //标题private String group = ""; //自定义组名private String description = "在线文档"; //描述private String version = "1.0"; //版本private Contact contact = new Contact(); //联系人private String basePackage = ""; //swagger会解析的包路径private List<String> basePath = new ArrayList<>(); //swagger会解析的url规则private List<String> excludePath = new ArrayList<>();//在basePath基础上需要排除的urlpublic String getGroup() {if (group == null || "".equals(group)) {return title;}return group;}}@Datapublic static class Contact {private String name = ""; //联系人private String url = ""; //联系人urlprivate String email = ""; //联系人email}
}
4.创建配置类SwaggerAutoConfiguration
package com.example.config;import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.bind.annotation.RequestMethod;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;@Configuration
@ConditionalOnProperty(name = "myknife4j.swagger.enabled", havingValue = "true",matchIfMissing = true)
@EnableSwagger2
@EnableConfigurationProperties(SwaggerProperties.class)
public class SwaggerAutoConfiguration implements BeanFactoryAware {@AutowiredSwaggerProperties swaggerProperties;private BeanFactory beanFactory;@Bean@ConditionalOnMissingBeanpublic List<Docket> createRestApi(){ConfigurableBeanFactory configurableBeanFactory =(ConfigurableBeanFactory) beanFactory;List<Docket> docketList = new LinkedList<>();// 没有分组if (swaggerProperties.getDocket().isEmpty()) {Docket docket = createDocket(swaggerProperties);configurableBeanFactory.registerSingleton(swaggerProperties.getTitle(),docket);docketList.add(docket);return docketList;}// 分组创建for (String groupName : swaggerProperties.getDocket().keySet()){SwaggerProperties.DocketInfo docketInfo =swaggerProperties.getDocket().get(groupName);ApiInfo apiInfo = new ApiInfoBuilder()//页面标题.title(docketInfo.getTitle())//创建人.contact(new Contact(docketInfo.getContact().getName(),docketInfo.getContact().getUrl(),docketInfo.getContact().getEmail()))//版本号.version(docketInfo.getVersion())//描述.description(docketInfo.getDescription()).build();// base-path处理// 当没有配置任何path的时候,解析/**if (docketInfo.getBasePath().isEmpty()) {docketInfo.getBasePath().add("/**");}List<Predicate<String>> basePath = new ArrayList<>();for (String path : docketInfo.getBasePath()) {basePath.add(PathSelectors.ant(path));}// exclude-path处理List<Predicate<String>> excludePath = new ArrayList<>();for (String path : docketInfo.getExcludePath()) {excludePath.add(PathSelectors.ant(path));}Docket docket = new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo).groupName(docketInfo.getGroup()).select()//为当前包路径.apis(RequestHandlerSelectors.basePackage(docketInfo.getBasePackage())).paths(Predicates.and(Predicates.not(Predicates.or(excludePath)),Predicates.or(basePath))).build();configurableBeanFactory.registerSingleton(groupName, docket);docketList.add(docket);}return docketList;}//构建 api文档的详细信息private ApiInfo apiInfo(SwaggerProperties swaggerProperties) {return new ApiInfoBuilder()//页面标题.title(swaggerProperties.getTitle())//创建人.contact(new Contact(swaggerProperties.getContact().getName(),swaggerProperties.getContact().getUrl(),swaggerProperties.getContact().getEmail()))//版本号.version(swaggerProperties.getVersion())//描述.description(swaggerProperties.getDescription()).build();}//创建接口文档对象private Docket createDocket(SwaggerProperties swaggerProperties) {//API 基础信息ApiInfo apiInfo = apiInfo(swaggerProperties);// base-path处理// 当没有配置任何path的时候,解析/**if (swaggerProperties.getBasePath().isEmpty()) {swaggerProperties.getBasePath().add("/**");}List<Predicate<String>> basePath = new ArrayList<>();for (String path : swaggerProperties.getBasePath()) {basePath.add(PathSelectors.ant(path));}// exclude-path处理List<Predicate<String>> excludePath = new ArrayList<>();for (String path : swaggerProperties.getExcludePath()) {excludePath.add(PathSelectors.ant(path));}return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo).groupName(swaggerProperties.getGroup()).select().apis(RequestHandlerSelectors.basePackage(swaggerProperties.getBasePackage())).paths(Predicates.and(Predicates.not(Predicates.or(excludePath)),Predicates.or(basePath))).build();}@Overridepublic void setBeanFactory(BeanFactory beanFactory) throws BeansException {this.beanFactory = beanFactory;}
}
5.配置application.yml文件
server:port: 7788
# 对应的SwaggerProperties配置类中的属性
myknife4j:swagger:enabled: true #是否启用swaggertitle: 测试标题description: 测试文档docket:controller: # 对应的SwaggerProperties配置类中的名为docket的map集合的keytitle: controller模块description: controller模块测试文档contact:name: xxxurl: www.xxx.comemail: xxxxx.@xx.combase-package: com.example.controller
6.执行启动类main方法启动项目,访问地址:http://服务地址:端口/doc.html

如果接口文档不分组,我们可以修改application.yml文件:
server:port: 7788
# 对应的SwaggerProperties配置类中的属性
myknife4j:swagger:enabled: true #是否启用swaggertitle: test模块base-package: com.example.controller

相关文章:
knife4j接口文档
knife4j是为Java MVC框架集成Swagger生成Api文档的增强解决方案,前身是swagger-bootstrap-ui,取名knife4j是希望它能像一把匕首一样小巧,轻量,并且功能强悍!其底层是对Springfox的封装,使用方式也和Springfox一致,只是对接口文档UI进行了优化。 核心功能…...
Windows机器安装SSH搭建,自己搞个局域网机房玩一玩
Windows机器安装SSH搭建为啥要装SSH安装OpenSSH使用 Windows 设置来安装 OpenSSHps脚本在线安装ps脚本离线安装其他二进制安装包安装为啥要装SSH 家里有多台Win机器,一台主机两个笔记本,本着不浪费的原则,打算把它们在平时的工作学习中利用起…...
二叉树的前序遍历(力扣144)
目录 题目描述: 解法一:递归法 解法二:迭代法 解法三:Morris 遍历 二叉树的前序遍历 题目描述: 给你二叉树的根节点 root ,返回它节点值的 前序 遍历。 示例 1: 输入:root […...
【数据库管理】①实例与数据库
1.Oracle RDBMS 架构图 2. Oracle 体系结构 由此区分database和instance的区别 No.1.oracle serverdatabase instance2.databasedata file、control file、redo log file3.instancean instance accesses a database4.oracle memorySGA PGA(oracle的内存结构)5.instanceSGA …...
vba:单元格的选择,查找,合并,批注,SpecialCells,图形插入
一: 活动单元格:activecell,工作表中活动单元格只有一个 Sub activecells() a activecell.Address 取得活动单元格地址 Cells(2, 3).Activate 激活指定单元格 End Sub selection光标所选区域 Sub 光标所选区域() Selection 1 End Sub Sub …...
【内网安全】横向移动域控提权NetLogonADCSPACKDC永恒之蓝
文章目录章节点横向移动-系统漏洞-CVE-2017-0146(永恒之蓝)影响版本插件检测-横向移动CS联动MSF-检测&利用横向移动-域控提权-CVE-2014-6324横向移动-域控提权-CVE-2020-1472影响版本横向移动-域控提权-CVE-2021-42287前提条件影响版本python版本EXP利用过程C#版本EXP利用过…...
将本地项目上传到远程仓库的步骤
文章目录将本地项目上传到远程仓库的步骤1.进入想上传的项目文件夹2.初始化本地仓库3.添加该项目下的所有文件4.将文件添加到本地仓库中5.添加远程仓库6.将文件更新到远程仓库上7.将本地文件推送回到指定的远程仓库中将本地项目上传到远程仓库的步骤 1.进入想上传的项目文件夹…...
selenium+opencv实现模拟登陆(滑块验证码)
很多网站登录登陆时都要用到滑块验证码,在某些场景例如使用爬虫爬取信息时常常受到阻碍,想着用opencv的模板匹配试试能不能实现模拟登陆。本来觉得网上资料多应该还蛮容易,但实际上手还是搞了蛮久,在这里记录一下整个流程…...
辽宁申请互联网医院牌照流程
辽宁申请互联网医院牌照流程|沈阳市|大连市|鞍山市|抚顺市|本溪市|丹东市|锦州市|营口市|阜新市|辽阳市|盘锦市|铁岭市|朝阳市|葫芦岛市 很多的人对互联网医院都不是很了解,也不太清楚互联网医院牌照怎么申请,其实牌照申请每个地区都不太一样&#x…...
java实现布隆过滤器
什么是布隆过滤器 布隆过滤器(Bloom Filter)是1970年由布隆提出来的。 它实际上是由一个很长的二进制数组一系列hash算法映射函数,用于判断一个元素是否存在于集合中。 布隆过滤器可以用于检索一个元素是否在一个集合中。它的优点是空间效率和…...
gitlab部署及整合Jenkins持续构建(三)nexus私服的安装及实战、linux安装mysql
文章目录敏捷持续集成是什么?linux安装jdk和maven安装jdk安装mavenlinux安装nexus3.xnexus私服的使用编译安装mysql可能遇到的问题使用cmake时报错敏捷持续集成是什么? 持续集成是一种软件开发实践,即团队开发成员经常集成他们的工作&#x…...
一、Java基础(2)
本章概要 异常的分类及处理 异常的概念异常的分类处理异常的方式 反射机制 动态语言的概念反射机制的概念反射的作用Java 的反射 API反射的过程创建对象的两种方式Method 的 invoke 方法 1.2 异常的分类及处理 1.2.1 异常的概念 异常指在方法不能按正常方式完成时…...
软件设计师重要知识点——第一章——计算机组成与体系结构
目录 1.1数据的表示 1.2数值表示范围 1.3浮点的运算 1.4计算机结构 1.5计算机体系结构分类——Flynn 1.6指令的基本概念 1.7寻址方式 1.8CISC与RISC 1.9流水线 1.10层次化存储结构 1.11Cache 1.12主存——编址与计算 1.13总线 1.14串联系统与并联系统 1.15N模混…...
编程学习心得
我来写一些,我关于编程的简单认识吧。 我觉得编程是一门艺术,也是一项技能,需要不断地学习和练习。无论是初学者还是有经验的开发人员,都需要耐心和恒心,才能够成为一名优秀的程序员。以下是一些关于编程学习的心得和…...
web获取媒体流
1. 下面例子演示了录屏和截图功能: <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport"…...
代码随想录算法训练营第四十二天 | 01背包问题,你该了解这些、01背包问题,你该了解这些 滚动数组、 416. 分割等和子集
打卡第42天,搞搞01背包。 今日任务 01背包问题,你该了解这些!01背包问题,你该了解这些! 滚动数组416.分割等和子集 背包问题1.0 :0-1 背包 有n件物品和一个最多能背重量为w 的背包。第i件物品的重量是weig…...
【Android】JNI静态与动态注册介绍
JNI的两种注册机制:静态注册和动态注册. 一、JNI介绍 JNI(Java Native Interface),即Java本地接口,JNI是Java调用Native 语言的一种特性。通过JNI可以使得Java与C/C机型交互. 方式: 静态注册动态注册:需要提供Java中…...
【算法题解】22. 接雨水
这是一道 困难 题 题目来自: https://leetcode.cn/problems/trapping-rain-water/ 题目 给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。 示例 1: 输入:height [0,…...
集合详解之(四)集合的遍历
文章目录🐒个人主页🏅JavaSE系列专栏📖前言:🎀ArrayList集合forEach()方法遍历🎀for循环遍历(针对List集合)🪅增强for循环(也支持Set集合)&#x…...
【I2C】通用驱动i2c-dev分析
文章目录1. 前言2. i2c-dev驱动的注册过程3. open_i2c_dev函数分析4. set_slave_addr函数分析5. i2c_read_bytes函数分析1. 前言 前面分析i2c-tool测试工具就是基于drivers/i2c/i2c-dev.c驱动来实现的。i2c-dev驱动在加载时会遍历所有的I2C总线(i2c_bus_type)上所有注册的adap…...
蓝牙 BLE 扫描面试题大全(2):进阶面试题与实战演练
前文覆盖了 BLE 扫描的基础概念与经典问题蓝牙 BLE 扫描面试题大全(1):从基础到实战的深度解析-CSDN博客,但实际面试中,企业更关注候选人对复杂场景的应对能力(如多设备并发扫描、低功耗与高发现率的平衡)和前沿技术的…...
c++ 面试题(1)-----深度优先搜索(DFS)实现
操作系统:ubuntu22.04 IDE:Visual Studio Code 编程语言:C11 题目描述 地上有一个 m 行 n 列的方格,从坐标 [0,0] 起始。一个机器人可以从某一格移动到上下左右四个格子,但不能进入行坐标和列坐标的数位之和大于 k 的格子。 例…...
leetcodeSQL解题:3564. 季节性销售分析
leetcodeSQL解题:3564. 季节性销售分析 题目: 表:sales ---------------------- | Column Name | Type | ---------------------- | sale_id | int | | product_id | int | | sale_date | date | | quantity | int | | price | decimal | -…...
成都鼎讯硬核科技!雷达目标与干扰模拟器,以卓越性能制胜电磁频谱战
在现代战争中,电磁频谱已成为继陆、海、空、天之后的 “第五维战场”,雷达作为电磁频谱领域的关键装备,其干扰与抗干扰能力的较量,直接影响着战争的胜负走向。由成都鼎讯科技匠心打造的雷达目标与干扰模拟器,凭借数字射…...
08. C#入门系列【类的基本概念】:开启编程世界的奇妙冒险
C#入门系列【类的基本概念】:开启编程世界的奇妙冒险 嘿,各位编程小白探险家!欢迎来到 C# 的奇幻大陆!今天咱们要深入探索这片大陆上至关重要的 “建筑”—— 类!别害怕,跟着我,保准让你轻松搞…...
TSN交换机正在重构工业网络,PROFINET和EtherCAT会被取代吗?
在工业自动化持续演进的今天,通信网络的角色正变得愈发关键。 2025年6月6日,为期三天的华南国际工业博览会在深圳国际会展中心(宝安)圆满落幕。作为国内工业通信领域的技术型企业,光路科技(Fiberroad&…...
深入理解Optional:处理空指针异常
1. 使用Optional处理可能为空的集合 在Java开发中,集合判空是一个常见但容易出错的场景。传统方式虽然可行,但存在一些潜在问题: // 传统判空方式 if (!CollectionUtils.isEmpty(userInfoList)) {for (UserInfo userInfo : userInfoList) {…...
git: early EOF
macOS报错: Initialized empty Git repository in /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core/.git/ remote: Enumerating objects: 2691797, done. remote: Counting objects: 100% (1760/1760), done. remote: Compressing objects: 100% (636/636…...
MySQL的pymysql操作
本章是MySQL的最后一章,MySQL到此完结,下一站Hadoop!!! 这章很简单,完整代码在最后,详细讲解之前python课程里面也有,感兴趣的可以往前找一下 一、查询操作 我们需要打开pycharm …...
如何把工业通信协议转换成http websocket
1.现状 工业通信协议多数工作在边缘设备上,比如:PLC、IOT盒子等。上层业务系统需要根据不同的工业协议做对应开发,当设备上用的是modbus从站时,采集设备数据需要开发modbus主站;当设备上用的是西门子PN协议时…...
