一、 什么是 Knife4j?

Knife4j是一个基于SpringDoc的、为Java MVC框架集成Swagger生成Api文档增强解决方案。它并不是重新实现一套OpenAPI规范,而是在SpringDoc的基础上,提供了更强大的UI界面和更多的增强功能

Knife4j的定义与定位: Knife4j(原名Swagger-Bootstrap-UI)是一个集Swagger2OpenAPI3为一体的增强解决方案,旨在为Java开发者提供更强大更美观的API文档界面和更多的·调试功能

Knife4jSpringDoc的关系: Knife4j在4.0版本之后,基于SpringDoc进行了重构,因此它完全兼容OpenAPI3规范。在Knife4j中,你仍然使用标准的OpenAPI注解(如@Tag@Operation@Parameter等),因为Knife4j只是增强了UI功能,底层规范仍然遵循OpenAPI


二、准备工作

明确一点,我们只用Knife4j的UI界面,其他的全部使用OpenApi协议!!!
切记切记,防止出现后期变更为其他文档系统导致的不兼容问题

1. 导入knife4j项目依赖

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

项目pom导入knife4j依赖项

2. knife4j依赖包分析

knife4j依赖项内部分析引用springdoc

  • Knife4j 4.0版本开始,Knife4j采用了这种基于SpringDoc的方式。
  • 在之前的版本中,Knife4j是基于SpringFox的,但SpringFox已经停止维护,因此Knife4j转向了SpringDoc

3. 配置OpenAPI

通过注入 GroupedOpenApi 的 Bean,可以根据包路径路径匹配来拆分文档。

import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.info.Info;
import org.springdoc.core.models.GroupedOpenApi;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class Knife4jConfiguration {

    @Bean
    public OpenAPI openAPI() {
        return new OpenAPI()
                .info(new Info()
                        .title("Knife4j 项目文档")
                        .version("1.0")
                        .description("整个项目以学习Knife4j项目为主")
                );
    }
    /**
     * 分组配置:包路径匹配,显示路径下全部接口
     * @return Default
     */
    @Bean
    public GroupedOpenApi defaultOpenApi() {
        return GroupedOpenApi.builder()
                .group("Default")
                .packagesToScan("com.framework.demo.controller")
                .build();
    }

    /**
     * 分组配置:路径匹配
     * @return 用户信息分组
     */
    @Bean
    public GroupedOpenApi userOpenApi() {
        return GroupedOpenApi.builder()
                .group("用户信息模块")
                .pathsToMatch("/user/**")
                .build();
    }

    @Bean
    public GroupedOpenApi animalOpenApi() {
        return GroupedOpenApi.builder()
                .group("动物信息模块")
                .pathsToMatch("/animal/**")
                .build();
    }

    @Bean
    public GroupedOpenApi systemOpenApi() {
        return GroupedOpenApi.builder()
                .group("系统管理")
                .pathsToMatch("/dict/**", "/log/**")
                .build();
    }

}

Knife4j项目文档预览

4. 注解定义API接口

Knife4j 完美兼容 OpenAPI 3 标准,并提供了独有的增强注解来控制文档细节。

功能 标准注解 (OpenAPI 3) Knife4j 增强注解
模块描述 @Tag(name = "用户中心") @ApiSupport(author = "张三", order = 1)
接口描述 @Operation(summary = "用户登录") @ApiOperationSupport(order = 5)
参数描述 @Parameter(description = "主键ID") -
实体类描述 @Schema(description = "用户信息") -

提示:若要让 order 排序生效,必须在配置文件中开启增强 knife4j.enable: true

@Tag(name = "动物信息管理")  
@RestController  
@RequestMapping("animal")  
@Slf4j  
public class AnimalController {  
  
    @RequestMapping("info")  
    @Operation(summary = "动物信息接口")  
    public String info(){  
        return "animal - info";  
    }  
  
    @GetMapping("{id}")  
    @Operation(summary = "查询动物接口")  
    public Animal getAnimal(@Parameter(description = "根据唯一Id查询动物") @PathVariable Long id){  
        Animal animal = new Animal();  
        animal.setId(id);  
        return animal;  
    }  
  
    @PostMapping  
    @Operation(summary = "保存动物接口")  
    public Animal save(@Parameter(description = "保存动物类Json") @RequestBody Animal animal){  
        return animal;  
    }  
}
  • Animal类
@Data  
@AllArgsConstructor  
@NoArgsConstructor  
public class Animal {  
    @Schema(description = "动物主键id")  
    private Long id;  
    @Schema(description = "动物名称")  
    private String name;  
    @Schema(description = "年龄")  
    private Integer age;  
}

5. 访问Knife4j页面

应用启动后,访问:http://localhost:8080/doc.html

三、springdoc-openapi配置

基础配置详情

# springdoc-openapi项目配置
springdoc:
  swagger-ui:
    path: /swagger-ui.html        # Swagger UI 的访问路径
    tags-sorter: alpha            # 标签按字母顺序排序
    operations-sorter: alpha      # 接口按字母顺序排序
  api-docs:
    path: /v3/api-docs            # OpenAPI JSON 文档的访问路径
  group-configs:
    - group: 'default'            # 分组名称
      paths-to-match: '/**'       # 匹配所有路径
      packages-to-scan: com.xiaominfo.knife4j.demo.web  # 扫描的包路径

1. 指定原生 Swagger UI 的访问路径

springdoc:
  swagger-ui:
    path: /swagger-ui.html

含义:指定原生 Swagger UI 的访问路径。

  • 默认值:/swagger-ui.html
  • 访问方式:http://localhost:8080/swagger-ui.html
  • 注意:即使启用了 Knife4j,这个路径仍然有效,但通常建议访问 Knife4j 的界面(/doc.html

2. 设置 UI 中的排序方式

    tags-sorter: alpha
    operations-sorter: alpha

含义:设置 UI 中的排序方式。

  • tags-sorter: alpha → 左侧的分组标签按字母顺序排序
  • operations-sorter: alpha → 接口列表按字母顺序排序
  • 其他可选值:
    • alpha:字母顺序
    • method:HTTP方法顺序(GET、POST等)
    • path:路径顺序

3. OpenAPI 访问路径

  api-docs:
    path: /v3/api-docs

含义OpenAPI 规范 JSON 数据的访问路径。

  • 默认值:/v3/api-docs
  • 这是标准的 OpenAPI 3.0+ 规范端点
  • 访问示例:http://localhost:8080/v3/api-docs
  • 返回格式:JSON 格式的 OpenAPI 规范

4. API 分组配置

  group-configs:
    - group: 'default'
      paths-to-match: '/**'
      packages-to-scan: com.xiaominfo.knife4j.demo.web

含义:API 分组配置。

  • group: 'default':分组名称为 “default”
  • paths-to-match: '/**':匹配所有路径的接口
  • packages-to-scan: com.xiaominfo.knife4j.demo.web:只扫描指定包下的 Controller
  • 效果:只显示 com.xiaominfo.knife4j.demo.web 包下的 API 接口

四、knife4j增强配置详情

官网地址:https://doc.xiaominfo.com/docs/features/enhance

增强配置

## 开启增强配置,不需要增强可以不配置
knife4j:  
  enable: true  

安全配置

  • 开启增强配置
  • 开启基础认证配置
knife4j:
  enable: true  # 开启增强
  basic:
    enable: true  # 开启基础认证
    username: admin  # 用户名
    password: 123456  # 密码

五、 安全防范:如何在正式环境关闭文档?

接口文档包含敏感信息,绝不能在生产环境暴露。

  • 必须开启增强功能开启生产环境屏蔽,才能彻底关闭文档!!!。
  • 这个地方有点别扭!切记切记,必须同时为true。

knife4j官网屏蔽文档说明:351-生产环境屏蔽doc.html页面资源

application-prod.yml 中配置:

  • “双重锁定”策略:
knife4j:
  enable: true        # 开启增强功能
  production: true     # 开启生产环境屏蔽(界面提示禁用)

springdoc:
  api-docs:
    enabled: false    # 彻底关闭 JSON 元数据接口
  swagger-ui:
    enabled: false    # 彻底关闭原生 UI 访问

关闭knife4j文档页面,直接拦截

六、常见原因与解决方案‌‌

全局异常处理器干扰‌

若项目中使用了 @RestControllerAdvice 注解的全局异常处理器类,Knife4j/Swagger 会将其误认为 Controller 并尝试扫描其中的 @ExceptionHandler 方法,导致文档生成失败或接口不显示。

解决‌:在全局异常类上添加 @Hidden 注解,使其被 Swagger 忽略。

@Slf4j
@RestControllerAdvice
@Hidden
public class GlobalExceptionHandler {

    @ExceptionHandler(BusinessException.class)
    public Result<Void> handleBusiness(BusinessException e) {
        return Result.fail(e.getCode(), e.getMessage());
    }

    @ExceptionHandler(NotLoginException.class)
    public Result<Void> handleNotLogin(NotLoginException e) {
        return Result.fail(401, "请先登录");
    }

    @ExceptionHandler(NotPermissionException.class)
    public Result<Void> handleNotPermission(NotPermissionException e) {
        return Result.fail(403, "无权限");
    }

    @ExceptionHandler(MethodArgumentNotValidException.class)
    public Result<Void> handleValidation(MethodArgumentNotValidException e) {
        String msg = e.getBindingResult().getFieldErrors().stream()
                .map(FieldError::getDefaultMessage)
                .collect(Collectors.joining("; "));
        return Result.fail(400, msg);
    }

    @ExceptionHandler(NoResourceFoundException.class)
    public Result<Void> handleNoResource(NoResourceFoundException e) {
        return Result.fail(404, e.getMessage());
    }

    @ExceptionHandler(Exception.class)
    public Result<Void> handleException(Exception e) {
        log.error("Unhandled exception", e);
        return Result.fail("服务器内部错误");
    }
}

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐