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

简介: 本文将深入探讨在 Spring Boot 项目中整合 Knife4j,这是一种基于 Swagger 的文档工具。通过使用 Knife4j,你可以轻松生成清晰、美观的 API 文档,提升你的项目文档管理水平。文章从基础概念到高级特性,带你领略 Knife4j 的独特魅力。

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

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

前言

在代码的世界里,有时候注释不足以表达你的思想,而一份优雅的 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 {

   // ...

}

123456

  • tags:指定分组,用于在文档中对接口进行分类展示。
  • description:对整个控制器的描述。

2. 接口方法相关注解:

@ApiOperation 注解:

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

@ApiOperation(value = "获取 Hello 信息", notes = "这是一个示例接口,返回 'Hello, Knife4j!'")

@GetMapping("/hello")

public String getHelloMessage() {

   return "Hello, Knife4j!";

}

12345

  • value:接口的标题。
  • notes:接口的详细说明。
@ApiParam 注解:

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

@GetMapping("/greet")

@ApiOperation(value = "根据名称问候", notes = "根据传入的名称返回问候语")

public String greet(@ApiParam(value = "姓名", required = true) @RequestParam String name) {

   return "Hello, " + name + "!";

}

12345

  • value:参数的描述。
  • required:指定参数是否是必须的。

3. 模型类相关注解:

@ApiModel 注解:

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

@ApiModel(description = "用户信息")

public class User {

   // ...

}

1234

  • description:模型的描述。
@ApiModelProperty 注解:

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

public class User {

   @ApiModelProperty(value = "用户ID", example = "123")

   private Long id;

   @ApiModelProperty(value = "用户姓名", example = "John Doe")

   private String name;

   // ...

}

12345678910

  • value:属性的描述。
  • example:属性的示例值。

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

实战演示

引入maven依赖

<dependency>

 <groupId>com.github.xiaoymin</groupId>

 <artifactId>knife4j-spring-boot-starter</artifactId>

 <version>3.0.3</version>

</dependency>

12345

配置类

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;

   }

 

}

123456789101112131415161718192021222324252627282930313233343536373839404142

请求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;

}

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455

响应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;

}

12345678910111213141516171819202122232425262728293031323334353637383940414243

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 {

   @Resource

   protected 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());

   }

}

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354

效果展示图

彩蛋(报错 解决)

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

spring:

 mvc:

   pathmatch:

     matching-strategy: ant_path_matcher

1234

结语:

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

相关文章
|
9月前
|
XML Java Nacos
Spring Boot 整合Nacos 版本兼容适配 史上最详细文档
本文介绍SpringBoot整合Nacos的完整流程,涵盖Nacos下载安装、配置中心与服务发现集成、版本兼容性问题及实战配置。重点解决SpringBoot 3.3.0与Nacos版本适配难题,推荐使用Spring Cloud Alibaba方案,并提供项目开源地址供参考学习。
|
数据采集 人工智能 Java
1天消化完Spring全家桶文档!DevDocs:一键深度解析开发文档,自动发现子URL并建立图谱
DevDocs是一款基于智能爬虫技术的开源工具,支持1-5层深度网站结构解析,能将技术文档处理时间从数周缩短至几小时,并提供Markdown/JSON格式输出与AI工具无缝集成。
593 1
1天消化完Spring全家桶文档!DevDocs:一键深度解析开发文档,自动发现子URL并建立图谱
|
前端开发
SpringBoot2.3.1集成Knife4j接口文档
SpringBoot2.3.1集成Knife4j接口文档
1194 44
|
11月前
|
存储 人工智能 自然语言处理
用Spring AI搭建本地RAG系统:让AI成为你的私人文档助手
想让AI帮你读懂PDF文档吗?本文教你用Spring AI和Ollama搭建一个本地RAG系统,让AI成为你的私人文档助手。无需GPU,无需云端API,只需几行代码,你的文档就能开口说话了!
2143 2
|
前端开发 Cloud Native Java
Java||Springboot读取本地目录的文件和文件结构,读取服务器文档目录数据供前端渲染的API实现
博客不应该只有代码和解决方案,重点应该在于给出解决方案的同时分享思维模式,只有思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~
Java||Springboot读取本地目录的文件和文件结构,读取服务器文档目录数据供前端渲染的API实现
|
JavaScript Java 测试技术
基于SpringBoot+Vue实现的留守儿童爱心网站设计与实现(计算机毕设项目实战+源码+文档)
博主是一位全网粉丝超过100万的CSDN特邀作者、博客专家,专注于Java、Python、PHP等技术领域。提供SpringBoot、Vue、HTML、Uniapp、PHP、Python、NodeJS、爬虫、数据可视化等技术服务,涵盖免费选题、功能设计、开题报告、论文辅导、答辩PPT等。系统采用SpringBoot后端框架和Vue前端框架,确保高效开发与良好用户体验。所有代码由博主亲自开发,并提供全程录音录屏讲解服务,保障学习效果。欢迎点赞、收藏、关注、评论,获取更多精品案例源码。
|
JavaScript Java 测试技术
基于SpringBoot+Vue实现的家政服务管理平台设计与实现(计算机毕设项目实战+源码+文档)
面向大学生毕业选题、开题、任务书、程序设计开发、论文辅导提供一站式服务。主要服务:程序设计开发、代码修改、成品部署、支持定制、论文辅导,助力毕设!
|
JavaScript 搜索推荐 Java
基于SpringBoot+Vue实现的家乡特色推荐系统设计与实现(源码+文档+部署)
面向大学生毕业选题、开题、任务书、程序设计开发、论文辅导提供一站式服务。主要服务:程序设计开发、代码修改、成品部署、支持定制、论文辅导,助力毕设!
|
JavaScript NoSQL Java
基于SpringBoot+Vue实现的大学生就业服务平台设计与实现(系统源码+文档+数据库+部署等)
面向大学生毕业选题、开题、任务书、程序设计开发、论文辅导提供一站式服务。主要服务:程序设计开发、代码修改、成品部署、支持定制、论文辅导,助力毕设!
|
JavaScript Java 测试技术
基于Java+SpringBoot+Vue实现的车辆充电桩系统设计与实现(系统源码+文档+部署讲解等)
面向大学生毕业选题、开题、任务书、程序设计开发、论文辅导提供一站式服务。主要服务:程序设计开发、代码修改、成品部署、支持定制、论文辅导,助力毕设!