Spring Boot 整合 Knife4j:打造更优雅的 API 文档

news2025/1/19 4:31:31

  在现代 Web 应用开发中,API 文档的重要性不言而喻。清晰、准确、易用的 API 文档不仅可以方便开发者理解和使用 API,还能提高团队协作效率。Knife4j 是一个基于 Swagger 的增强型 API 文档工具,它可以为 Spring Boot 项目生成美观、易于交互的 API 文档,本文将介绍如何在 Spring Boot 项目中整合 Knife4j,并提供详细的代码示例和最佳实践。

一、为什么选择 Knife4j?

  Knife4j 是一个基于 Swagger 的增强型 API 文档框架,相比于 Swagger UI,Knife4j 提供了更强大的功能和更好的用户体验:

  1. 界面美观: Knife4j 提供了更加美观和现代的界面,使得 API 文档更具吸引力。
  2. 功能强大: Knife4j支持在线调试、参数示例、离线文档导出等多种实用功能。
  3. 易于集成: Knife4j 可以轻松地与 Spring Boot 集成。
  4. 支持多种主题: Knife4j 提供了多种主题,可以自定义 API 文档的风格。
  5. 更好的可读性: Knife4j 在 API文档的呈现上做了优化,使其更易于阅读和理解。

二、Spring Boot 整合 Knife4j实践

2.1 添加 Knife4j 依赖

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

<dependency>
    <artifactId>guava</artifactId>
    <groupId>com.google.guava</groupId>
    <version>29.0-jre</version>
</dependency>

注意: 请使用合适的版本号,确保你的 Spring Boot 版本与 Knife4j 和 Swagger 兼容。

2.2 创建 Swagger 配置类

import com.github.xiaoymin.knife4j.spring.annotations.EnableKnife4j;
import com.google.common.base.Function;
import com.google.common.base.Optional;
import com.google.common.base.Predicate;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import springfox.documentation.RequestHandler;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

@Configuration
@EnableSwagger2
@EnableKnife4j
@ConditionalOnWebApplication
public class SwaggerConfig implements WebMvcConfigurer {

    /**
     * 定义分隔符
     */
    private static final String SPLITOR = ";";

    @Bean(value = "systemApi")
    public Docket createSystemRestApi() {
        return new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(apiInfo())
                .groupName("1.系统管理模块")
                .select()
                .apis(basePackage("com.extend.chk.system.controller"))
                .paths(PathSelectors.any())
                .build();
    }

    @Bean(value = "reportApi")
    public Docket createReportRestApi() {
        return new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(apiInfo())
                .groupName("2.数据可视化模块")
                .select()
                .apis(basePackage("com.extend.chk.report.controller"))
                .paths(PathSelectors.any())
                .build();
    }

    @Bean(value = "warnApi")
    public Docket createWarnRestApi() {
        return new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(apiInfo())
                .groupName("3.预警模块")
                .select()
                .apis(basePackage(("com.extend.chk.warn.controller")))
                .paths(PathSelectors.any())
                .build();
    }

    private ApiInfo apiInfo() {
        return new ApiInfoBuilder()
                .description("学习管理平台接口文档")
                .version("v1.0.0")
                .title("学习管理平台接口文档")
                .build();
    }

    /**
     * 重写basePackage方法,使能够实现多包访问
     * @param basePackage
     * @return
     */
    public static Predicate<RequestHandler> basePackage(final String basePackage) {
        return input -> declaringClass(input).transform(handlerPackage(basePackage)).or(true);
    }

    private static Function<Class<?>, Boolean> handlerPackage(final String basePackage) {
        return input -> {
            // 循环判断匹配
            for (String strPackage : basePackage.split(SPLITOR)) {
                boolean isMatch = input.getPackage().getName().startsWith(strPackage);
                if (isMatch) {
                    return true;
                }
            }
            return false;
        };
    }

    private static Optional<? extends Class<?>> declaringClass(RequestHandler input) {
        return Optional.fromNullable(input.declaringClass());
    }

    /**
     * 配置静态资源
     * @param registry
     */
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/static/**").addResourceLocations("classpath:/static/");
    }
}
  1. @Configuration: 标识这是一个配置类,用来定义 Bean 或其他配置信息。
  2. @EnableSwagger2: 启用 Swagger 2 来生成和管理 RESTful API 的文档。
  3. @EnableKnife4j:增强 Swagger UI 的展示效果,提供更美观、功能更丰富的 API 文档界面。
  4. @ConditionalOnWebApplication:确保上述配置仅在应用程序为 Web 应用时才生效。
  5. @Bean: 创建 Docket Bean,用于配置 Swagger 文档信息。
  6. apiInfo(): 配置 API的基本信息,例如标题、描述、版本号等。
  7. apis(basePackage(("com.extend.chk.warn.controller"))): 指定生成API 文档的 Controller 所在的包。
  8. paths(PathSelectors.any()): 定义路径过滤规则,决定哪些 URL 路径应被包含在文档中,这里设置为所有路径。
  9. groupName("1.系统管理模块"):为生成的 API 分组指定名称。这可以将不同的 API 接口按功能或模块进行分类展示。

2.3 在类上使用 Swagger 注解

2.3.1 在controller里面使用Swagger 注解
@Api(tags = "项目管理")
@RestController
@RequestMapping("/project/manage")
public class ProjectManageController extends BaseController {

    @Autowired
    private ProjectManageService ProjectManageService;

    @ApiOperation(value = "查询项目列表")
    @GetMapping("/list")
    public Result<PageDataInfo<ProjectManage>> queryProjectManageList(ProjectManageReq req) {
        return success(buildPageDataInfo(ProjectManageService.queryProjectManageList(req)));
    }

    @ApiOperation(value = "查询项目详情")
    @GetMapping("/query")
    public Result<ProjectManage> queryProjectManageById(Integer workspaceId, Integer projectId) {
        return success(ProjectManageService.queryProjectManageById(workspaceId, projectId));
    }

    @ApiOperation(value = "项目新增")
    @PostMapping(value = "/add")
    @Log(title = "项目新增", businessType = BusinessType.INSERT)
    public Result addProjectManage(@Validated @RequestBody ProjectManage ProjectManage) {
        ProjectManageService.addProjectManage(ProjectManage);
        return success();
    }

    @ApiOperation(value = "项目修改")
    @PostMapping(value = "/update")
    @Log(title = "项目修改", businessType = BusinessType.UPDATE)
    public Result updateProjectManage(@Validated @RequestBody ProjectManage ProjectManage) {
        ProjectManageService.updateProjectManage(ProjectManage);
        return success();
    }

    @ApiOperation(value = "项目删除")
	@ApiImplicitParams({
            @ApiImplicitParam(name = "workspaceId", value = "空间id", required = true),
            @ApiImplicitParam(name = "projectId", value = "项目id", required = true)
    })
    @PutMapping(value = "/delete")
    @Log(title = "项目删除", businessType = BusinessType.DELETE)
    public Result operateProjectManage(Integer workspaceId, Integer projectId) {
        ProjectManageService.operateProjectManage(workspaceId, projectId);
        return success();
    }
}
  1. @Api: 用于描述 Controller 的基本信息,例如分类标签。
  2. @ApiOperation: 用于描述 API的基本信息,例如接口名称、描述等。
  3. @ApiImplicitParam: 用于描述 API的参数信息,例如参数名称、类型、是否必填等。
2.3.2 在请求类和返回类里面使用Swagger 注解
@ApiModel(value = "ProjectManage对象", description = "项目管理表")
public class ProjectManage extends BaseEntity<ProjectManage> {

    private static final long serialVersionUID = 1L;

    @ApiModelProperty("主键id")
    private Integer id;

    @ApiModelProperty("项目名称")
    private String name;

    @ApiModelProperty("项目负责人id")
    private String ownerId;

    @ApiModelProperty("项目成员id")
    private String memberId;

    @ApiModelProperty("工作空间id")
    private Integer workspaceId;

    @ApiModelProperty("项目状态(1-有效 2-失效)")
    private String status;

    @Override
    public Serializable pkVal() {
        return this.id;
    }
}
  1. @ApiModel:用于描述一个模型类(通常是一个 DTO 或实体类),提供该模型的详细信息,如名称、描述等。它使得生成的 API文档能够清晰地展示数据模型的用途和结构。
  2. @ApiModelProperty:用于描述模型类中的具体字段,指定字段的名称、类型、是否必填、默认值、备注等信息。这有助于开发者更好地理解每个字段的意义和用法。

2.4 访问 Knife4j 文档

启动 Spring Boot 应用,并在浏览器中访问以下地址,即可查看 Knife4j 生成的 API 文档:

http://localhost:8080/extend/doc.html#/home

三、最佳实践

  1. 使用 Swagger 注解描述 API: 使用 Swagger 注解详细描述 API 的参数、响应、错误码等,提高文档的可读性。
  2. 根据API 分组: 使用 Swagger 的分组功能,将 API 分类展示,方便用户查找。
  3. 添加 API 示例: 在 Swagger注解中添加 API 示例,帮助用户快速了解 API 的使用方法。
  4. 保持 API 文档与代码同步: 确保 API文档和代码同步更新,避免出现文档与代码不一致的问题。
  5. 使用清晰的 API 命名: 使用清晰的 API 命名和参数命名,提高 API的可读性。

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

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

相关文章

【FlutterDart】MVVM(Model-View-ViewModel)架构模式例子-http版本(30 /100)

动图更精彩 MVVM&#xff08;Model-View-ViewModel&#xff09; 特点 Model&#xff1a;负责数据管理和业务逻辑。 View&#xff1a;负责显示数据&#xff0c;通常是一个UI组件。 ViewModel&#xff1a;负责处理用户交互&#xff0c;更新Model&#xff0c;并将数据转换为View可…

C#实现字符串反转的4种方法

见过不少人、经过不少事、也吃过不少苦&#xff0c;感悟世事无常、人心多变&#xff0c;靠着回忆将往事串珠成链&#xff0c;聊聊感情、谈谈发展&#xff0c;我慢慢写、你一点一点看...... 1、string.Reverse 方法 string content "Hello World";string reverseStri…

音频语言模型与多模态体系结构

音频语言模型与多模态体系结构 多模态模型正在创造语言、视觉和语音等以前独立的研究领域的协同效应。这些模型使用通用架构,将每种模式视为不同的“token”,使它们能够以一种与人类认知非常相似的方式联合建模和理解世界。 ​ ​可以将多模态分为两个主要领域:输入空间(…

几个Linux系统安装体验(续): 深度桌面系统

本文介绍深度桌面系统&#xff08;deepin&#xff09;的安装。 下载 下载地址&#xff1a; https://www.deepin.org/zh/download/ 下载文件&#xff1a;本文下载文件名称为NFSDesktop-5.0-G230-240806-amd64.iso。 下载注意事项&#xff1a;镜像可直接下载&#xff0c;无须…

LabVIEW实车四轮轮速信号再现系统

开发了一个基于LabVIEW的实车四轮轮速信号再现系统。该系统解决现有电机驱动传感器成本高、重复性差、真实性差和精度低等问题&#xff0c;提供一种高精度、低成本的轮速信号再现解决方案。 项目背景 ABS轮速传感器在现代汽车安全系统中发挥着至关重要的作用。为保证其准确性和…

C#异步多线程——浅谈async/await底层原理

async/await是块语法糖&#xff0c;编译器帮助我们做了很多工作&#xff0c;下面我们就简单剖析一下async/await的底层原理。 反编译工具ILSpy安装 我用的是ILSpy反编译生成的dll程序集。还没有ILSpy工具的小伙伴可以直接在VS中安装&#xff1b;点击Extensions>Manage Ext…

1,Linux环境变量基本定义(基于Ubuntu示例进行讲解)

linux环境变量的概念 Linux环境变量&#xff08;准确说应该是shell变量&#xff09;&#xff0c;是直接存储在操作系统中的一组键值对&#xff08;dict类型&#xff09;&#xff0c;用于配置系统和应用程序的操作行为。 【有经验的描述】&#xff1a;它们的工作原理很简单&am…

【Python通过UDP协议传输视频数据】(界面识别)

提示&#xff1a;界面识别项目 前言 随着网络通信技术的发展&#xff0c;视频数据的实时传输在各种场景中得到了广泛应用。UDP&#xff08;User Datagram Protocol&#xff09;作为一种无连接的协议&#xff0c;凭借其低延迟、高效率的特性&#xff0c;在实时性要求较高的视频…

深度学习中的张量 - 使用PyTorch进行广播和元素级操作

深度学习中的张量 - 使用PyTorch进行广播和元素级操作 元素级是什么意思&#xff1f; 元素级操作在神经网络编程中与张量的使用非常常见。让我们从一个元素级操作的定义开始这次讨论。 一个_元素级_操作是在两个张量之间进行的操作&#xff0c;它作用于各自张量中的相应元素…

几个Linux系统安装体验(续): 中科方德服务器系统

本文介绍中科方德服务器系统&#xff08;NFSDesktop&#xff09;的安装。 下载 下载地址&#xff1a; https://www.nfschina.com/index.php?catid68 下载文件&#xff1a;本文下载的文件名称为NFSCNS-4.0-G330-x86_64-241128.iso。 下载注意事项&#xff1a;无法直接下载&…

浅谈计算机网络03 | 现代网络组成

现代网络组成 一 、网络生态体系1.1网络生态系统的多元主体1.2 网络接入设施的多样类型 二、现代网络的典型体系结构解析三、高速网络技术3.1 以太网技术3.2 Wi-Fi技术的深度剖析3.2.1 应用场景的多元覆盖3.2.2 标准升级与性能提升 3.3 4G/5G蜂窝网的技术演进3.3.1 蜂窝技术的代…

JavaWeb 前端基础 html + CSS 快速入门 | 018

今日推荐语 指望别人的救赎&#xff0c;势必走向毁灭——波伏娃 日期 学习内容 打卡编号2025年01月17日JavaWeb 前端基础 html CSS018 前言 哈喽&#xff0c;我是菜鸟阿康。 今天 正式进入JavaWeb 的学习&#xff0c;简单学习 html CSS 这2各前端基础部分&am…

内网渗透测试工具及渗透测试安全审计方法总结

1. 内网安全检查/渗透介绍 1.1 攻击思路 有2种思路&#xff1a; 攻击外网服务器&#xff0c;获取外网服务器的权限&#xff0c;接着利用入侵成功的外网服务器作为跳板&#xff0c;攻击内网其他服务器&#xff0c;最后获得敏感数据&#xff0c;并将数据传递到攻击者&#xff0…

Git 安装 操作 命令 远程仓库 多人协作

Git作用 Git诞生史 很多人都知道&#xff0c;Linus在1991年创建了开源的Linux&#xff0c;从此&#xff0c;Linux系统不断发展&#xff0c;已经成为最大的服务器系统软件了。Linus虽然创建了Linux&#xff0c;但Linux的壮大是靠全世界热心的志愿者参与的&#xff0c;这么多人在…

Mockito+PowerMock+Junit单元测试

一、单元测试用途 1、日常开发团队要求规范&#xff0c;需要对开发需求代码进行单元测试并要求行覆盖率达到要求&#xff0c;DevOps流水线也会开设相关门禁阀值阻断代码提交&#xff0c;一般新增代码行覆盖率80%左右。 二、Mock测试介绍 1、Mock是为了解决不同的单元之间由于…

2024CVPR《HomoFormer》

这篇论文提出了一种名为HomoFormer的新型Transformer模型,用于图像阴影去除。论文的主要贡献和创新点如下: 1. 研究背景与动机 阴影去除的挑战:阴影在自然场景图像中普遍存在,影响图像质量并限制后续计算机视觉任务的性能。阴影的空间分布不均匀且模式多样,导致传统的卷积…

JavaEE之CAS

上文我们认识了许许多多的锁&#xff0c;此篇我们的CAS就是从上文的锁策略开展的新概念&#xff0c;我们来一探究竟吧 1. 什么是CAS&#xff1f; CAS: 全称Compare and swap&#xff0c;字⾯意思:“比较并交换”&#xff0c;⼀个CAS涉及到以下操作&#xff1a; 我们假设内存中…

国产编辑器EverEdit - 复制为RTF

1 复制为RTF 1.1 应用背景 在写产品手册或者其他文档时&#xff0c;可能会用到要将产品代码以样例的形式放到文档中&#xff0c;一般的文本编辑器拷贝粘贴到Word中也就是普通文本&#xff0c;没有语法着色&#xff0c;这样感观上不是太好&#xff0c;为了让读者的感观更好一点…

LLM - 大模型 ScallingLaws 的 C=6ND 公式推导 教程(1)

欢迎关注我的CSDN&#xff1a;https://spike.blog.csdn.net/ 本文地址&#xff1a;https://spike.blog.csdn.net/article/details/145185794 Scaling Laws (缩放法则) 是大模型领域中&#xff0c;用于描述 模型性能(Loss) 与 模型规模N、数据量D、计算资源C 之间关系的经验规律…

CSS认识与实践

目录 CSS 是什么 基本语法规范 引入方式 内部样式表 行内样式表 外部样式 空格规范 选择器 选择器的功能 选择器的种类 基础选择器 标签选择器 类选择器 id 选择器 通配符选择器 基础选择器小结 复合选择器 后代选择器 子选择器 并集选择器 伪类选择器 复合…