Knife4j 实战

发布于 2026-07-30 19:37 更新于 2026-07-30 19:38 3116 字 16 min read ... 访问量

文章介绍了在 Spring Boot 3 项目中集成 Knife4j 的完整流程与核心要点。Knife4j 是基于 OpenAPI 3 规范的接口文档增强工具,通过 springdoc-openapi 生成文档,并结合 Swagger UI 提供更友好的展示与调试功能,支持接口搜索、排序、离线导出和访问控制等能力。文章详细说明了环境配置、依赖引入、注解使用、安全策略及常见问题排查,强调了在开发与生产环境中的差异化配置,并明确指出 @Hidden 仅用于隐藏文档不用于权限控制,需结合 Spring Security 等机制实现真实接口的安全防护。

Knife4j 实战

Knife4j 核心认知

什么是 Knife4j

Knife4j 是面向 Java Web 项目的接口文档增强解决方案。它能够读取应用生成的 OpenAPI 文档,并提供更易用的接口展示、在线调试、搜索、排序、离线导出和访问控制等功能。

在 Spring Boot 3 项目中,可以将相关组件理解为以下关系:

  • OpenAPI 3:描述 RESTful API 的规范。
  • springdoc-openapi:扫描 Spring Web 接口并生成 OpenAPI 3 文档。
  • Swagger UI:展示和调试 OpenAPI 文档的通用 Web 界面。
  • Knife4j:在 OpenAPI 文档基础上提供增强界面和扩展能力。

因此,Knife4j 不是一种新的接口规范,也不等同于 OpenAPI 3。对于 Spring Boot 3 项目,Knife4j 的底层文档生成能力主要由 springdoc-openapi 提供。

Spring Boot 2 与 Spring Boot 3 的主要差异

对比项Spring Boot 2 常见方案Spring Boot 3 推荐方案
Java 版本通常可以使用 JDK 8 或更高版本,具体取决于 Spring Boot 版本最低需要 JDK 17
Java EE 包名主要使用 javax.*迁移到 jakarta.*
接口文档规范可以使用 OpenAPI 2 或 OpenAPI 3推荐使用 OpenAPI 3
常见实现Springfox 或 springdoc-openapispringdoc-openapi
Knife4j Starter根据规范和框架版本选择对应 Starter使用 Jakarta 版本的 OpenAPI 3 Starter
常用注解旧项目可能使用 io.swagger.annotations.*使用 io.swagger.v3.oas.annotations.*

注意:并不是 Spring Boot 3 本身“废弃了 Swagger 2 注解”,而是 Spring Boot 3 项目通常不再使用基于 Springfox 的旧方案。迁移到 springdoc-openapi 后,应将旧注解替换为 OpenAPI 3 注解。

Knife4j 相比 Swagger UI 的常见增强

对比项Swagger UIKnife4j
页面展示提供标准 OpenAPI 文档界面提供更适合中文项目的增强界面
接口调试支持在线发送请求增强参数填写、请求调试和结果展示
接口检索支持基础过滤提供接口搜索等增强功能
文档导出默认不提供完整的离线导出流程支持导出 Markdown、HTML、Word 和 OpenAPI 文档
扩展配置使用 Swagger UI 配置项额外提供 Knife4j 增强配置
访问保护通常需要自行结合安全框架处理提供生产保护和 Basic 认证等辅助配置

适用场景

  • 前后端分离项目中自动生成并维护接口文档。
  • 开发和测试阶段在线调用接口。
  • 展示请求参数、响应结构、状态码和字段说明。
  • 多模块或微服务项目中统一管理接口文档。
  • 将接口文档导出后用于交付或归档。

Spring Boot 3 集成 Knife4j

环境要求

本文示例采用以下环境:

  • JDK 17 或更高版本。
  • Spring Boot 3.x。
  • Maven 项目。
  • spring-boot-starter-web
  • Knife4j 4.5.0。

实际项目中应根据 Spring Boot 的具体版本检查依赖兼容性,不要仅凭“版本更高”判断组件一定兼容。

引入 Maven 依赖

Spring Boot 3 使用 Jakarta 版本的 Knife4j Starter:

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

该 Starter 已经集成 OpenAPI 3 所需的 springdoc-openapi 相关依赖。通常不需要再单独引入 Springfox、Swagger 2 或其他版本的 springdoc-openapi,否则可能产生依赖冲突。

配置 application.yml

下面给出一个适合单模块项目的基础配置:

server:
  port: 8080

spring:
  application:
    name: knife4j-spring-boot3-demo

springdoc:
  swagger-ui:
    path: /swagger-ui.html
    tags-sorter: alpha
    operations-sorter: alpha
  api-docs:
    path: /v3/api-docs
  group-configs:
    - group: default
      paths-to-match: /**
      packages-to-scan: com.example.knife4jdemo.controller

knife4j:
  enable: true
  setting:
    language: zh_cn

配置说明:

  • springdoc.api-docs.path 用于配置 OpenAPI JSON 文档地址。
  • springdoc.group-configs 用于配置文档分组、接口路径和控制器扫描包。
  • packages-to-scan 必须替换为当前项目实际的控制器包名。
  • knife4j.enable 用于开启 Knife4j 增强功能。
  • knife4j.setting.language 用于设置界面语言。

配置接口文档基本信息

通过声明 OpenAPI Bean 可以统一设置文档标题、版本、说明和联系信息:

package com.example.knife4jdemo.config;

import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.info.Contact;
import io.swagger.v3.oas.models.info.Info;
import io.swagger.v3.oas.models.info.License;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class Knife4jOpenApiConfig {

    @Bean
    public OpenAPI customOpenAPI() {
        return new OpenAPI()
                .info(new Info()
                        .title("用户管理系统接口文档")
                        .version("1.0.0")
                        .description("基于 Spring Boot 3、OpenAPI 3 和 Knife4j 构建的接口文档")
                        .contact(new Contact()
                                .name("项目开发组")
                                .email("demo@example.com"))
                        .license(new License()
                                .name("Apache 2.0")));
    }
}

启动项目并访问文档

启动 Spring Boot 项目后,在浏览器中访问:

http://localhost:8080/doc.html

OpenAPI JSON 文档的默认访问地址为 /v3/api-docs。如果配置了分组,还可能生成对应的分组文档地址。

doc.html 无法访问时的排查顺序

正常情况下,引入 Starter 后不需要手动配置静态资源映射。如果出现 404401403,应按照以下顺序排查:

  1. 检查 Maven 依赖是否使用了 Spring Boot 3 对应的 Jakarta Starter。

  2. 检查项目是否错误引入了多个 springdoc-openapi 或 Springfox 版本。

  3. 检查 packages-to-scan 是否为真实的控制器包路径。

  4. 检查项目是否使用了 @EnableWebMvc,或者是否完全接管了 Spring MVC 配置。

  5. 检查 Spring Security 是否拦截了文档页面和 OpenAPI 文档接口。

  6. 检查应用是否配置了 context-path,访问地址是否需要增加上下文路径。

只有在项目确实自定义了静态资源规则,并确认自动配置没有生效时,才考虑补充资源映射:

package com.example.knife4jdemo.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class WebResourceConfig implements WebMvcConfigurer {

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/doc.html")
                .addResourceLocations("classpath:/META-INF/resources/");

        registry.addResourceHandler("/webjars/**")
                .addResourceLocations("classpath:/META-INF/resources/webjars/");
    }
}

这段配置属于故障排查方案,不是所有 Spring Boot 3 项目的固定必配项。

OpenAPI 3 常用注解

旧注解与新注解对照

功能旧版 Swagger 2 注解OpenAPI 3 注解
控制器分组@Api@Tag
接口说明@ApiOperation@Operation
参数说明@ApiParam@ApiImplicitParam@Parameter
多个参数说明@ApiImplicitParams@Parameters
模型说明@ApiModel@Schema
字段说明@ApiModelProperty@Schema
隐藏接口或类@ApiIgnore@Hidden@Operation(hidden = true)

使用 @Schema 描述实体类

package com.example.knife4jdemo.domain;

import io.swagger.v3.oas.annotations.media.Schema;

@Schema(description = "用户信息")
public class User {

    @Schema(
            description = "用户主键",
            requiredMode = Schema.RequiredMode.REQUIRED,
            example = "10001"
    )
    private Long id;

    @Schema(
            description = "用户名",
            requiredMode = Schema.RequiredMode.REQUIRED,
            example = "zhangsan"
    )
    private String username;

    @Schema(
            description = "手机号码",
            requiredMode = Schema.RequiredMode.REQUIRED,
            example = "13800138000"
    )
    private String phone;

    @Schema(description = "年龄", example = "26")
    private Integer age;

    @Schema(description = "用户状态:0 表示禁用,1 表示正常", example = "1")
    private Integer status;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPhone() {
        return phone;
    }

    public void setPhone(String phone) {
        this.phone = phone;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public Integer getStatus() {
        return status;
    }

    public void setStatus(Integer status) {
        this.status = status;
    }
}

使用 Lombok 的项目可以通过 @Data 简化 Getter 和 Setter,但需要确保项目已经正确引入 Lombok 并启用注解处理。

使用 @Tag@Operation 描述控制器

package com.example.knife4jdemo.controller;

import com.example.knife4jdemo.domain.User;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
@RequestMapping("/users")
@Tag(name = "用户管理", description = "提供用户查询接口")
public class UserController {

    @GetMapping("/{id}")
    @Operation(
            summary = "根据编号查询用户",
            description = "根据用户主键查询用户详细信息"
    )
    public User getUserById(
            @Parameter(
                    description = "用户主键",
                    required = true,
                    example = "10001"
            )
            @PathVariable("id") Long id
    ) {
        User user = new User();
        user.setId(id);
        user.setUsername("zhangsan");
        user.setPhone("13800138000");
        user.setAge(26);
        user.setStatus(1);
        return user;
    }

    @GetMapping
    @Operation(
            summary = "查询用户列表",
            description = "查询当前系统中的用户数据"
    )
    public List<User> listUsers() {
        return List.of(getUserById(10001L));
    }
}

重启项目后访问:

http://localhost:8080/doc.html

页面中应展示用户管理分组、接口摘要、参数说明和响应模型。

Knife4j 进阶功能

配置全局 JWT 认证

对于使用 JWT 的项目,可以在 OpenAPI 文档中声明 HTTP Bearer 认证方案。下面的配置是前面 OpenAPI Bean 的升级版本,实际项目中只保留一个 OpenAPI Bean:

package com.example.knife4jdemo.config;

import io.swagger.v3.oas.models.Components;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.info.Contact;
import io.swagger.v3.oas.models.info.Info;
import io.swagger.v3.oas.models.info.License;
import io.swagger.v3.oas.models.security.SecurityRequirement;
import io.swagger.v3.oas.models.security.SecurityScheme;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class Knife4jOpenApiConfig {

    private static final String SECURITY_SCHEME_NAME = "BearerAuth";

    @Bean
    public OpenAPI customOpenAPI() {
        SecurityScheme securityScheme = new SecurityScheme()
                .type(SecurityScheme.Type.HTTP)
                .scheme("bearer")
                .bearerFormat("JWT")
                .description("输入登录后获得的 JWT");

        return new OpenAPI()
                .info(new Info()
                        .title("用户管理系统接口文档")
                        .version("1.0.0")
                        .description("支持 JWT 调试的接口文档")
                        .contact(new Contact()
                                .name("项目开发组")
                                .email("demo@example.com"))
                        .license(new License()
                                .name("Apache 2.0")))
                .components(new Components()
                        .addSecuritySchemes(SECURITY_SCHEME_NAME, securityScheme))
                .addSecurityItem(new SecurityRequirement()
                        .addList(SECURITY_SCHEME_NAME));
    }
}

配置完成后,文档页面会显示认证入口。开发人员输入 JWT 后,调试请求会按照 Bearer 认证方式携带 Authorization 请求头。

注意:将安全方案添加到 OpenAPI 对象表示文档默认要求认证,但它不会替代 Spring Security 的服务端鉴权逻辑。

导出离线文档

Knife4j 的文档管理功能可以导出以下内容:

  • Markdown 文档。
  • 离线 HTML 文档。
  • Word 文档。
  • 原始 OpenAPI JSON 文档。

Knife4j 官方导出功能不直接生成 PDF。需要 PDF 时,可以先导出 Markdown 或 HTML,再使用其他工具转换为 PDF。

隐藏不需要展示的接口

使用 @Hidden 可以隐藏控制器或接口:

package com.example.knife4jdemo.controller;

import io.swagger.v3.oas.annotations.Hidden;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@Hidden
@RestController
@RequestMapping("/admin")
public class AdminController {

    @PostMapping("/password")
    public String updatePassword() {
        return "密码修改成功";
    }
}

也可以只隐藏单个方法:

@Hidden
@PostMapping("/internal/reset")
public String resetData() {
    return "重置成功";
}

重要说明@Hidden 只控制接口是否出现在 OpenAPI 文档中,不会阻止客户端访问该接口。敏感接口仍然必须通过 Spring Security、权限校验和网关策略进行保护。

生产环境安全配置

开发环境配置

开发环境可以开启接口文档:

knife4j:
  enable: true
  production: false

生产环境关闭文档

生产环境可以同时关闭 Knife4j 页面、Swagger UI 和 OpenAPI JSON 接口:

springdoc:
  api-docs:
    enabled: false
  swagger-ui:
    enabled: false

knife4j:
  enable: false
  production: true

其中:

  • knife4j.production 用于开启 Knife4j 的生产环境保护策略。
  • springdoc.api-docs.enabled 用于关闭 OpenAPI JSON 接口。
  • springdoc.swagger-ui.enabled 用于关闭 Swagger UI。

生产环境是否完全禁用接口文档,应根据项目的网络隔离、权限模型和运维要求决定。

使用 Basic 认证保护文档

在内部测试环境确实需要开放文档时,可以启用 Basic 认证:

knife4j:
  enable: true
  production: false
  basic:
    enable: true
    username: doc_user
    password: ${KNIFE4J_PASSWORD}

不要在代码仓库中直接保存真实密码。示例使用环境变量 KNIFE4J_PASSWORD 注入密码。

Basic 认证只能作为文档访问保护的一部分。生产系统还应结合 HTTPS、网络访问控制、Spring Security 和统一身份认证等措施。

常见问题

页面能够打开,但没有接口

重点检查:

  • packages-to-scan 是否配置正确。
  • 控制器是否使用了 @RestController
  • 请求方法是否使用了 @GetMapping@PostMapping 等映射注解。
  • 控制器是否位于 Spring Boot 默认扫描范围内。
  • 是否错误配置了 paths-to-match

文档页面返回 401403

这通常表示请求被安全过滤器拦截。需要在开发环境中按需放行以下资源:

  • /doc.html
  • /webjars/**
  • /v3/api-docs/**
  • /swagger-ui/**
  • /swagger-ui.html

是否放行以及如何放行,应以项目实际使用的 Spring Security 版本和权限策略为准。

文档页面返回 404

重点检查:

  • Starter 是否选择正确。
  • 依赖是否下载成功。
  • 是否存在依赖冲突。
  • 是否配置了应用上下文路径。
  • 是否使用 @EnableWebMvc 覆盖了自动配置。
  • 是否自定义了静态资源映射。

注解没有显示在文档中

检查注解导包是否来自 io.swagger.v3.oas.annotations。不要混用旧版 io.swagger.annotations 和 OpenAPI 3 注解。

修改接口后文档没有变化

可以依次尝试:

  1. 确认代码已经重新编译并重启应用。

  2. 刷新浏览器页面。

  3. 清除 Knife4j 页面缓存。

  4. 检查当前查看的是否为正确分组。

  5. 直接访问 /v3/api-docs,确认后端生成的 OpenAPI JSON 是否已经更新。

总结

Spring Boot 3 集成 Knife4j 的核心流程如下:

  1. 使用 JDK 17 或更高版本。

  2. 引入 Jakarta 版本的 Knife4j OpenAPI 3 Starter。

  3. 通过 springdoc 配置扫描包、分组和 OpenAPI 文档路径。

  4. 通过 OpenAPI Bean 设置文档基本信息和认证方案。

  5. 使用 @Tag@Operation@Parameter@Schema 描述接口。

  6. 在开发环境开放文档,在生产环境按安全要求关闭或限制访问。

  7. 明确区分“隐藏接口文档”和“保护真实接口”,不能将 @Hidden 当作权限控制手段。

喜欢的话,留下你的评论吧~

... 访问量
© 2026 跨越星轨的客 @Hoshiumi
Powered by theme astro-koharu · Inspired by Shoka