精雕细琢的文档体验: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://www.mzph.cn/news/669621.shtml

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

相关文章

Nodejs基础6之HTTP模块的获取请求行和请求头、获取请求体、获取请求路径和查询字符串、http请求练习、设置HTTP响应报文、http响应练习

Nodejs基础 HTTP模块获取请求行和请求头获取请求体获取请求路径和查询字符串方式一方式二 http请求练习设置HTTP响应报文状态码响应状态描述响应头响应体 HTTP响应练习 HTTP模块 含义语法重点掌握请求方法request.method*请求版本request.httpVersion请求路径request.url*URL …

Mac利用brew安装mysql并设置初始密码

前言 之前一直是在windows上开发后段程序&#xff0c;所以只在windows上装mysql。(我记得linux只需要适应yum之类的命令即可) 另外, linux的移步 linux安装mysql (详细步骤,初次初始化,sql小例子,可视化操作客户端推荐) 好家伙&#xff0c;我佛了&#xff0c;写完当天网上发…

机器学习聚类算法

聚类算法是一种无监督学习方法&#xff0c;用于将数据集中的样本划分为多个簇&#xff0c;使得同一簇内的样本相似度较高&#xff0c;而不同簇之间的样本相似度较低。在数据分析中&#xff0c;聚类算法可以帮助我们发现数据的内在结构和规律&#xff0c;从而为进一步的数据分析…

深度学习缝模块怎么描述创新点?(附写作模板+涨点论文)

深度学习缝了别的模块怎么描述创新点、怎么讲故事写成一篇优质论文&#xff1f; 简单框架&#xff1a;描述自己这个领域&#xff0c;该领域出现了什么问题&#xff0c;你用了什么方法解决&#xff0c;你的方法有了多大的性能提升。 其中&#xff0c;重点讲清楚这两点&#xf…

QtAV学习:(一)Windows下编译QtAV

QtAV 主页&#xff1a; QtAV by wang-bin 作者的编译构建说明文档&#xff1a; Build QtAV wang-bin/QtAV Wiki GitHub 我的编译环境&#xff1a; 编译环境&#xff1a;win10/msvc2015/Qt5.6.3 第一步&#xff1a;GitHub拉取代码,执行子模块初始化 地址&#xff1a; …

2024-01-07-AI 大模型全栈工程师 - 做自己的产品经理

摘要 2024-01-07 周日 杭州 阴 本节内容: a. 如何做好独立开发设计&#xff0c;实现财富自由&#xff1b; 课程内容 1. 独立开发者 英文 indie hacker&#xff0c;是指独立开发软件产品的人&#xff1b;一人承担一个项目产品的所有工作&#xff1b; 2. 创业机会 云计算设…

C++ 内存模型

C内存模型 - MrYun - 博客园 (cnblogs.com) 内存区域 C内存分为5个区域&#xff1a;堆 heap &#xff1a; 由new分配的内存块&#xff0c;其释放编译器不去管&#xff0c;由我们程序自己控制&#xff08;一个new对应一个delete&#xff09;。如果程序员没有释放掉&#xff0c…

abap - 发送邮件,邮件正文带表格和excel附件

发送内容 的数据获取&#xff1a; 正文部分使用cl_document_bcs>create_document静态方法实现 传入参数为html内表结构 CLEAR lo_document .lo_document cl_document_bcs>create_document(i_type HTMi_text lt_htmli_length conlengthsi_subject lv_subje…

【漏洞复现】EPON上行A8-C政企网关信息泄露漏洞

Nx01 产品简介 EPON上行A8-C政企网关是一款终端产品&#xff0c;提供企业网络解决方案。 Nx02 漏洞描述 EPON上行A8-C政企网关敏感信息泄露漏洞&#xff0c;攻击者通过敏感信息泄露获取管理员密码。 Nx03 产品主页 fofa-query: "ZXECS" && title"Web…

【机器学习】机器学习简单入门

&#x1f388;个人主页&#xff1a;甜美的江 &#x1f389;欢迎 &#x1f44d;点赞✍评论⭐收藏 &#x1f917;收录专栏&#xff1a;matplotlib &#x1f91d;希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff0c;让我们共同学习、交流进…

<.Net>使用visual Studio 2022在VB.net中新添自定义画图函数(优化版)

前言 这是基于我之前的一篇博文&#xff1a; 使用visual Studio 2019在VB.net中新添自定义画图函数 在此基础上&#xff0c;我优化了一下&#xff0c;改进了UI&#xff0c;添加了示例功能&#xff0c;即以画圆函数为基础&#xff0c;添加了走马灯功能。 先看一下最终效果&#…

Google Chrome Close AutoUpdate

DOMException: play() failed because the user didn‘t interact with the document first.-CSDN博客 html5 audio video-CSDN博客 Google Chrome Close AutoUpdate 关闭google浏览器自动更新 1&#xff1a;检查是否已安装google浏览器&#xff0c;并卸载&#xff1a; 2&…

router路由跳转的两种模板

<router-link><router-link/> <router-view><router-view/> link &#xff1a;链接&#xff0c;联系 view&#xff1a;指看见展现在人们面前的、可以稳定地进行详细审视的事物 将语境拉回到router里&#xff0c;抽象概括一下 router-link就是一个…

55. 右旋字符串(卡码网KamaCoder)

文章目录 55. 右旋字符串题目描述暴力优化&#xff1a;不能申请额外空间&#xff0c;只能在本串上操作思路代码 55. 右旋字符串 题目描述 字符串的右旋转操作是把字符串尾部的若干个字符转移到字符串的前面。给定一个字符串 s 和一个正整数 k&#xff0c;请编写一个函数&…

Spark SQL调优实战

1、新添参数说明 // Driver和Executor内存和CPU资源相关配置 --是否开启executor动态分配&#xff0c;开启时spark.executor.instances不生效 spark.dynamicAllocation.enabledfalse --配置Driver内存 spark.dirver.memory5g --driver最大结果大小&#xff0c;设置为0代…

SQLserver2008 r2 下载安装配置、使用、新建登录用户及通过Navicat远程连接

目录 一、下载 二、安装配置 1.安装 2.许可条款 3.安装程序支持文件 4.功能选择 5.实例配置 6.服务器配置 7.数据库引擎配置 8.Reporting Services 配置 9.安装进度 ​编辑 10.完成 三、使用 四、新建登录用户 1.新建登录名 2.常规 3.服务器角色 4. 用户映…

基于CNN+LSTM深度学习网络的时间序列预测matlab仿真

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 4.1 卷积神经网络&#xff08;CNN&#xff09; 4.2 长短时记忆网络&#xff08;LSTM&#xff09; 4.3 CNNLSTM网络结构 5.算法完整程序工程 1.算法运行效果图预览 2.算法运行软件版本 MA…

Java设计模式大全:23种常见的设计模式详解(一)

本系列文章简介&#xff1a; 设计模式是在软件开发过程中&#xff0c;经过实践和总结得到的一套解决特定问题的可复用的模板。它是一种在特定情境中经过验证的经验和技巧的集合&#xff0c;可以帮助开发人员设计出高效、可维护、可扩展和可复用的软件系统。设计模式提供了一种在…

架构学习(四):scrapy下载中间件实现动态切换User-Agent

scrapy下载中间件实现动态与固定UserAgent 前言关卡&#xff1a;实现动态切换User-Agentscrapy设置User-Agent方式梳理User-Agent生效梳理为何选择在下载中间件中实现自定义User-Agent下载中间件 结束 前言 请求头User-Agent是比较常规的反爬手段&#xff0c;不同站点对其检测…

thinkphp6入门(17)-- 网站开发中session、cache、cookie的区别

Session&#xff08;会话&#xff09;: 定义&#xff1a; Session是一种用于在服务器端存储用户信息的机制&#xff0c;以跟踪用户的状态。 数据存储位置&#xff1a; 存储在服务器端&#xff0c;可以存在于内存、数据库或文件系统中。 生命周期&#xff1a; 存在于用户访问应…