精雕细琢的文档体验:Spring Boot 与 Knife4j 完美交汇

欢迎来到我的博客,代码的世界里,每一行都是一个故事

精雕细琢的文档体验:Spring Boot 与 Knife4j 完美交汇

    • 前言
    • Knife4j 与 Swagger 的区别
      • 1. 特性与优劣势对比:
        • Knife4j:
        • Swagger:
      • 2. 选择 Knife4j 的理由:
    • Knife4j中的注解说明
      • 1. 控制器类相关注解:
        • `@Api` 注解:
      • 2. 接口方法相关注解:
        • `@ApiOperation` 注解:
        • `@ApiParam` 注解:
      • 3. 模型类相关注解:
        • `@ApiModel` 注解:
        • `@ApiModelProperty` 注解:
    • 实战演示
      • 引入maven依赖
      • 配置类
      • 请求vo实现
      • 响应VO实现
      • controller实现
      • 效果展示图
    • 彩蛋(报错 解决)
    • 结语:

前言

在代码的世界里,有时候注释不足以表达你的思想,而一份优雅的 API 文档则能够让你的代码更加生动、易读。今天,我们将探讨如何通过整合 Knife4j,为你的 Spring Boot 项目添加一把锐利的文档利器。就像在一场精彩的武术表演中,每一刀都能展现出独特的艺术魅力,Knife4j 也将为你的文档世界带来新的精彩。

Knife4j 与 Swagger 的区别

Knife4j 和 Swagger 是两个用于 API 文档生成和展示的工具,它们都基于 OpenAPI(以前称为 Swagger)规范。下面是 Knife4j 与 Swagger 的区别以及对比它们的特性和优劣:

1. 特性与优劣势对比:

Knife4j:

特性:

  1. UI 界面美观: Knife4j 提供了一套漂亮的、易用的 UI 界面,展示了 API 文档的信息,并支持在线调试和测试。

  2. 支持多种注解: Knife4j 支持众多的 Swagger 注解,并且提供了一些额外的扩展注解,如 @ApiImplicitParams@ApiOperationSupport 等。

  3. 在线调试: 提供了在线调试和测试 API 的功能,开发者可以直接在文档中进行接口的测试。

  4. 强大的扩展性: 支持自定义扩展,开发者可以根据需求进行定制化。

优势:

  • UI 界面美观,易用性好。
  • 支持丰富的 Swagger 注解,提供了更多的功能。
  • 提供了在线调试功能,方便开发者测试接口。
Swagger:

特性:

  1. 标准化规范: Swagger 是 OpenAPI 规范的实现之一,具有广泛的支持和社区。

  2. 生态系统丰富: 由于是较早的 API 文档工具,有庞大的社区和丰富的插件生态系统。

  3. 强大的生态支持: 支持多种语言和框架,适用于各种项目。

优势:

  • 作为 OpenAPI 规范的实现,与其他支持 OpenAPI 的工具和库更好地集成。
  • 有着较长时间的发展历史,生态系统较为成熟。

2. 选择 Knife4j 的理由:

  1. UI 界面更友好: Knife4j 的 UI 界面相较于原生 Swagger 更加美观和易用,提供了更好的用户体验。

  2. 功能扩展更丰富: Knife4j 在 Swagger 的基础上进行了功能扩展,支持更多的 Swagger 注解和一些额外的扩展注解,提供了更多的功能。

  3. 在线调试更方便: Knife4j 提供了在线调试和测试 API 的功能,方便开发者在文档中直接进行接口测试。

  4. 社区支持良好: 尽管相对于 Swagger,Knife4j 的用户规模可能较小,但其社区仍然活跃,能够提供一定的支持。

综合考虑上述因素,选择 Knife4j 的主要理由在于其更友好的 UI 界面、丰富的功能扩展和方便的在线调试功能。然而,具体选择应该根据项目需求、开发者团队的偏好以及其他因素来决定。

Knife4j中的注解说明

Knife4j 中的注解主要用于配置和描述 API 文档。这些注解帮助开发者更精确地定义 API 接口、模型类等信息,以便生成详细的 API 文档。以下是一些在 Knife4j 中常用的注解及其作用:

1. 控制器类相关注解:

@Api 注解:

@Api 注解用于对整个控制器类进行描述,指定一些全局信息,如分组、描述等。

@Api(tags = "示例接口", description = "用于演示 Knife4j 的 API 接口")
@RestController
@RequestMapping("/api")
public class SampleController {// ...
}
  • tags:指定分组,用于在文档中对接口进行分类展示。
  • description:对整个控制器的描述。

2. 接口方法相关注解:

@ApiOperation 注解:

@ApiOperation 注解用于对单个接口方法进行描述,指定该接口的一些信息,如标题、说明等。

@ApiOperation(value = "获取 Hello 信息", notes = "这是一个示例接口,返回 'Hello, Knife4j!'")
@GetMapping("/hello")
public String getHelloMessage() {return "Hello, Knife4j!";
}
  • value:接口的标题。
  • notes:接口的详细说明。
@ApiParam 注解:

@ApiParam 注解用于对接口方法的参数进行描述,指定参数的一些信息,如名称、是否必须、描述等。

@GetMapping("/greet")
@ApiOperation(value = "根据名称问候", notes = "根据传入的名称返回问候语")
public String greet(@ApiParam(value = "姓名", required = true) @RequestParam String name) {return "Hello, " + name + "!";
}
  • value:参数的描述。
  • required:指定参数是否是必须的。

3. 模型类相关注解:

@ApiModel 注解:

@ApiModel 注解用于对模型类进行描述,指定模型的一些信息,如描述、子类等。

@ApiModel(description = "用户信息")
public class User {// ...
}
  • description:模型的描述。
@ApiModelProperty 注解:

@ApiModelProperty 注解用于对模型类的属性进行描述,指定属性的一些信息,如描述、示例值等。

public class User {@ApiModelProperty(value = "用户ID", example = "123")private Long id;@ApiModelProperty(value = "用户姓名", example = "John Doe")private String name;// ...
}
  • value:属性的描述。
  • example:属性的示例值。

这些注解使得 Knife4j 能够生成更加详细、清晰的 API 文档。在实际应用中,结合这些注解,可以使 API 文档更具可读性和易用性。

实战演示

引入maven依赖

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

配置类

package fun.todoitbo.botally.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.EnableSwagger2;/*** @author xiaobo*/
@Configuration
@EnableSwagger2
public class Knife4jConfiguration {@Bean(value = "defaultApi2")public Docket defaultApi2() {// 设置分组名称String groupName="记账API";// 创建 Docket 对象Docket docket=new Docket(DocumentationType.OAS_30).apiInfo(new ApiInfoBuilder().title("记账 API ").description("# 关于记账软件的 API").contact(new Contact("一只牛博","https://todoitbo.fun","todoitbo@qq.com")).version("3.0").build())// 设置分组名称.groupName(groupName).select()// 指定Controller扫描包路径.apis(RequestHandlerSelectors.basePackage("fun.todoitbo.botally.controller")).paths(PathSelectors.any()).build();return docket;}}

请求vo实现

package fun.todoitbo.botally.vo;import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;import java.time.LocalDateTime;/*** 用户账单表(TbBill)实体类** @author todoitbo* @since 2024-01-03 13:57:52*/
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class GetTbBillReqVo {@ApiModelProperty(value = "账单主键id")private Long id;@ApiModelProperty(value = "账单类别id")private Long categoryId;@ApiModelProperty(value = "最小金额")private Double minAmount;@ApiModelProperty(value = "最大金额")private Double maxAmount;@ApiModelProperty(value = "名称")private String name;@ApiModelProperty(value = "开始时间")@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")private LocalDateTime startTime;@ApiModelProperty(value = "结束时间")@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")private LocalDateTime endTime;@ApiModelProperty(value = "账单出账")private int inBill;@ApiModelProperty(value = "账单时间")@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")private LocalDateTime belongTime;}

响应VO实现

package fun.todoitbo.botally.vo;import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;import java.math.BigDecimal;
import java.time.LocalDateTime;/*** @author todoitbo* @date 2024/1/3*/
@Data
public class TbBillRespVo {@ApiModelProperty(value = "账单ID,主键")@JsonSerialize(using = ToStringSerializer.class)private Long id;@ApiModelProperty(value = "账单类别id")@JsonSerialize(using = ToStringSerializer.class)private Long categoryId;@ApiModelProperty(value = "账单时间")@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")private LocalDateTime billTime;@ApiModelProperty(value = "金额")private BigDecimal amount;@ApiModelProperty(value = "名称")private String name;@ApiModelProperty(value = "账单类别名称")private String categoryName;@ApiModelProperty(value = "是否收入")private int inBill;
}

controller实现

package fun.todoitbo.botally.controller;import fun.todoitbo.botally.dto.BoResult;
import fun.todoitbo.botally.service.ITbBillService;
import fun.todoitbo.botally.vo.DetailRespVo;
import fun.todoitbo.botally.vo.GetTbBillReqVo;
import fun.todoitbo.botally.vo.SaveTbBillReqVo;
import fun.todoitbo.botally.vo.TbBillRespVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;import javax.annotation.Resource;
import javax.validation.constraints.NotNull;
import java.util.List;/*** 用户账单表(TbBill)控制器** @author todoitbo* @since 2024-01-03 13:57:52*/
@RestController
@RequestMapping(value = "TbBill")
@Api(tags = "用户账单表(TbBill)控制器")
@Validated
public class TbBillController {@Resourceprotected ITbBillService service;@PostMapping("/saveBill")@ApiOperation(value = "新增账单")public BoResult<Boolean> saveBill(@Validated @RequestBody SaveTbBillReqVo saveTbBillReqVo) {return BoResult.resultOk(service.saveBill(saveTbBillReqVo));}@DeleteMapping("/deleteBill")@ApiOperation(value = "删除账单")public BoResult<Boolean> deleteBill(@NotNull(message = "id不能为空") Long id) {return BoResult.resultOk(service.deleteBill(id));}@GetMapping("/getBillList")@ApiOperation(value = "获取账单列表")public BoResult<List<TbBillRespVo>> getBillList(@Validated GetTbBillReqVo getTbBillReqVo) {return BoResult.resultOk(service.getBillList(getTbBillReqVo));}@GetMapping("/getDetail")@ApiOperation(value = "获取账单详情")public BoResult<DetailRespVo> getDetail() {return BoResult.resultOk(service.getDetail());}
}

效果展示图

在这里插入图片描述

彩蛋(报错 解决)

在这里插入图片描述

这个报错是因为springboot版本高,由于现代浏览器和中间件对URL的敏感性增加,一些场景下使用ant风格的URL匹配可能会出现问题。因此,为了保证最大的兼容性和可移植性,建议在Spring Boot项目中添加这个配置。

spring:mvc:pathmatch:matching-strategy: ant_path_matcher

结语:

希望通过这篇文章,你能够更深入地了解 Knife4j 在 Spring Boot 中的应用。在文档的世界里,每一刀都是为了更好地表达思想,而 Knife4j 就是我们的得力助手。让我们一同投入这场文档的舞台,为代码增色不少,为开发带来更多的便利与乐趣。

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

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

相关文章

STL之stack+queue的使用及其实现

STL之stackqueue的使用及其实现 1. stack&#xff0c;queue的介绍与使用1.1stack的介绍1.2stack的使用1.3queue的介绍1.4queue的使用 2.stack&#xff0c;queue的模拟实现2.1stack的模拟是实现2.2queue的模拟实现 3.总结 所属专栏&#xff1a;C“嘎嘎" 系统学习❤️ &…

话题:IT行业有哪些证书含金量高?

IT行业有哪些证书含金量高? 1. 以下是一些在IT行业中我认为具有高含金量的证书&#xff1a; 思科认证&#xff08;Cisco Certifications&#xff09;&#xff1a;思科认证是由网络领域的著名厂商——Cisco公司推出的&#xff0c;是互联网领域的国际权威认证。这个认证体系包含…

如何像工程师一样阅读 - 快速阅读技术书籍的9个技巧

0. 目的 在看了 Read Like an Engineer: 9 Tips for Reading Technical Books Fast 之后&#xff0c; 记录一些个人的看法&#xff0c;并在这篇英文文章上作为实验&#xff0c; 记录一下正确的阅读方法。 1. 第一次阅读 1.1 生词表 parcel of the job: 工作中必不可少的部分…

使用cocos2d-console初始化一个项目

先下载好cocos2d-x的源码包 地址 https://www.cocos.com/cocos2dx-download 这里使用的版本是 自己的电脑要先装好python27 用python安装cocos2d-console 看到项目中有个setup.py的一个文件 python setup.py 用上面的命令执行一下。 如果执行正常的话回出现上面的图 然后…

Vue事件中如何使用 event 对象

在Vue中&#xff0c;事件处理函数常常需要获取事件触发时的相关信息&#xff0c;比如鼠标位置、按键信息等。而要获取这些信息&#xff0c;就需要使用event对象。那么在Vue的事件中如何正确使用event对象呢&#xff1f;接下来就来详细介绍一下。 首先&#xff0c;在Vue的事件中…

通过遵循最佳做法来提高 EDA 和 HPC 应用程序的 Azure NetApp 文件性能

介绍 Azure NetApp 文件是一项托管存储解决方案&#xff0c;适用于各种方案&#xff0c;包括高性能计算 (HPC) 基础结构。 低延迟和每秒高 I/O 操作数 (IOPS) 对于大规模企业而言是一种很好的组合。 假设你就职于一家半导体公司。 你的任务是设计公司的集成电路芯片&#xff…

P59---第二阶段B C 相电流

P59---第二阶段B C 相电流

curl8.6.0 - CURLE_PEER_FAILED_VERIFICATION

文章目录 curl8.6.0 - CURLE_PEER_FAILED_VERIFICATION概述笔记END curl8.6.0 - CURLE_PEER_FAILED_VERIFICATION 概述 在看一个开源工程, 里面用到了curl和openssl, 但是工程使用vcpkg来管理的包, 用CMake来编译 依赖太多了, win10 编译选项为 vs2019 x64/Win32(或者Ninja)…

STM32F1 - 标准外设库_规范

STM32F10x_StdPeriph_Lib_V3.6.0 1> 头文件包含关系2> .c文件内部结构3> 宏定义位置4> 位掩码bit mask5> .c文件中定义私有变量 1> 头文件包含关系 1个头文件stm32f10x.h 就把整个MCU以及标准外设库&#xff0c;就管理了&#xff1b; 2> .c文件内部结构 …

【服务器数据恢复】服务器RAID模块硬件损坏的数据恢复案例

服务器数据恢复环境&故障&#xff1a; 某品牌服务器中有一组由数块SAS硬盘组建的RAID5磁盘阵列&#xff0c;服务器操作系统是WINDOWS SERVER&#xff0c;服务器中存放企业数据&#xff0c;无数据库文件。 服务器出故障之前出现过几次意外断电的情况&#xff0c;服务器断电…

C++ 中的模型预测控制(01/2)

目录 一、说明二、MPC原理说明三、分解算法的来源并显示关键特征&#xff0c;四、C 实现说明五、平衡 Q 和 R六、资源下载地址 一、说明 以下文章介绍了应用模型预测控制器的简单控制系统方法。本文讨论了这种控制的基本机制&#xff0c;该机制适用于各种工程领域。 MPC 涉及对…

4.5 特效规范与拆分实现及程序的调用原理

一、特效基础流程 落地方案 连入游戏 需求 策划需求,美术需求 需要的SHADER,功能 测试/反馈/修改 效果迭代 满足功能的特效 概念设计 参考图,设计图 二、规范的设计原理与目的 节约沟通成本 保持项目的一致性 工作交接可以更加便捷 降低出错的概率 提升工作效率…

【数据结构】前缀树的模拟实现

目录 1、什么是前缀树&#xff1f; 2、模拟实现 2.1、前缀树节点结构 2.2、字符串的添加 2.3、字符串的查寻 2.3.1、查询树中有多少个以字符串"pre"作为前缀的字符串 2.3.2、查询某个字符串被添加过多少次 2.4、字符串的删除 3、完整代码 1、什么是前缀树&…

Vue-Vue3 集成编辑器功能

1、安装依赖 编辑器插件需要安装 wangeditor/editor 和 wangeditor/editor-for-vue 两个插件 npm install wangeditor/editor --savevue3运行如下命令安装 npm install wangeditor/editor-for-vuenext --savevue2运行如下命令安装 npm install wangeditor/editor-for-vue -…

设计模式3-责任链模式

责任链模式是一种行为设计模式&#xff0c;它允许你创建一个对象链。请求沿着这条链传递&#xff0c;直到有一个对象处理它为止。这种模式通常用于需要以某种方式动态地决定处理请求的顺序或方式的情况。 类图&#xff1a; 从图中可见最大的特点是AbstractHandler它自己聚合了自…

华清作业day56

SQLite特性&#xff1a; 零配置一无需安装和管理配置&#xff1b;储存在单一磁盘文件中的一个完整的数据库&#xff1b;数据库文件可以在不同字节顺序的机器间自由共享&#xff1b;支持数据库大小至2TB&#xff1b;足够小&#xff0c;全部源码大致3万行c代码&#xff0c;250KB…

Redis——集群环境部署

一般情况下的Redis&#xff0c;我们都是在一台服务器上进行操作的&#xff0c;也就是说读、写以及备份操作都是在一台Redis服务器上进行的。随着项目访问量的增加&#xff0c;对Redis服务器的操作也更加频繁&#xff0c;虽然Redis读写速度都很快&#xff0c;但是一定程度上也会…

书生·浦语大模型全链路开源体系

参考&#xff1a;https://www.bilibili.com/video/BV1Rc411b7ns/?spm_id_from333.788&vd_source3bbd0d74033e31cbca9ee35e111ed3d1 背景&#xff1a; 人工智能的发展从针对特定任务&#xff0c;用一个模型解决一个问题过渡到一个模型来应对多模态、多任务&#xff0c;大模…

程序设计基础实验破解(5)

一.前言 我上大一时接触到程序设计基础这门课&#xff0c;这门课有时会有实验&#xff0c;我便常常摸鱼&#xff0c;利用CSDN来做&#xff0c; 虽然有时搜不到&#xff0c;但每次搜到时我想&#xff1a;爽&#xff01;&#xff01;&#xff01; 于是我也开始写&#xff0c;写…

【FFmpeg】ffplay 命令行参数 ⑤ ( 设置音频滤镜 -af 参数 | 设置统计信息 -stats 参数 | 设置同步时钟类型 -sync 参数 )

文章目录 一、ffplay 命令行参数 - 音频滤镜1、设置音频滤镜 -af 参数2、常用的 音频滤镜 参数3、音频滤镜链 示例 二、ffplay 命令行参数 - 统计信息1、设置统计信息 -stats 参数2、关闭统计信息 -nostats 参数 三、ffplay 命令行参数 - 同步时钟类型1、设置同步时钟类型 -syn…