SpringBoot实战:整合Knife4j
- 发布时间:2026-04-19 20:50:59
- 本文热度:浏览 3 赞 0 评论 0
- 文章标签: SpringBoot Knife4j OpenAPI3
- 全文共1字,阅读约需1分钟
Knife4j 在 Spring Boot 项目里的作用很直接:把接口定义、参数说明、返回结构、调试入口和分组展示整合到一套文档界面里。放到实际开发中,它解决的不是“有没有文档”问题,而是“文档能不能跟代码一起演进、能不能直接调接口、能不能让前后端和测试用同一份说明”问题。
先把版本关系说清楚
整合 Knife4j,第一步不是写配置,而是先选对依赖。这个地方最容易抄错。
-
Spring Boot 3.x
- 只建议走 OpenAPI 3
- 使用
knife4j-openapi3-jakarta-spring-boot-starter - 底层基于
springdoc-openapi - JDK 要求至少 17
- 不要再额外重复引入其他 springdoc starter,避免 Jar 冲突 (doc.xiaominfo.com)
-
Spring Boot 2.4.x ~ 2.7.x
- 如果项目还是 OpenAPI 3,使用
knife4j-openapi3-spring-boot-starter - 如果项目还是 Swagger 2 / OpenAPI 2,使用
knife4j-openapi2-spring-boot-starter - 官方对 Spring Boot 2 的建议区间是 2.4.0 ~ 3.0.0 之前
- Spring Boot 低于 2.4 时,更适合使用 Knife4j 4.0 之前的版本 (doc.xiaominfo.com)
- 如果项目还是 OpenAPI 3,使用
这篇文章后面的代码,统一按 Spring Boot 3.x + Knife4j + OpenAPI 3 来写。这也是现在新项目更合理的组合。Knife4j 在 Boot 3 场景下本质上是对 springdoc 的增强展示层,因此很多扫描、分组、文档路径配置仍然遵循 springdoc 的方式。(doc.xiaominfo.com)
一套能直接落地的整合方式
先看 Maven 依赖。核心思路很简单:Web、参数校验、Knife4j starter 三件套就够了。
<dependencies>
<!-- Web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 参数校验 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<!-- Knife4j:Spring Boot 3.x 使用 Jakarta Starter -->
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-openapi3-jakarta-spring-boot-starter</artifactId>
<version>4.4.0</version>
</dependency>
</dependencies>
对于 Spring Boot 3,官方文档给出的 starter 就是 knife4j-openapi3-jakarta-spring-boot-starter。同时,Knife4j 已经带上 springdoc 相关能力,通常不需要你再手动补一个 springdoc-openapi-starter-webmvc-ui。(doc.xiaominfo.com)
application.yml 配置
下面这份配置足够覆盖大部分业务项目。
server:
port: 8080
springdoc:
api-docs:
path: /v3/api-docs
swagger-ui:
path: /swagger-ui.html
tags-sorter: alpha
operations-sorter: alpha
group-configs:
- group: default
paths-to-match: /**
packages-to-scan: com.example.demo.controller
knife4j:
enable: true
setting:
language: zh_cn
这里有三个关键点:
springdoc.group-configs决定扫描哪些包、哪些路径。knife4j.enable=true表示启用 Knife4j 增强能力。- 接口元数据输出路径默认是
/v3/api-docs,Knife4j 页面入口通常还是/doc.html。官方示例也明确保留了 springdoc 配置项和 Knife4j 增强配置的组合方式。(doc.xiaominfo.com)
补一份 OpenAPI 基础信息
如果你只配了 starter,页面能出来,但文档标题、描述、联系人这些信息还是空的。生产项目里最好显式补上。
package com.example.demo.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 org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class OpenApiConfig {
@Bean
public OpenAPI customOpenAPI() {
return new OpenAPI()
.info(new Info()
.title("用户中心接口文档")
.description("提供用户查询、创建、更新等接口")
.version("1.0.0")
.contact(new Contact()
.name("backend-team")
.email("backend@example.com")));
}
}
这部分虽然不是 Knife4j 独有配置,但在 Boot 3 方案里,Knife4j 基于 OpenAPI 3 和 springdoc 工作,因此文档基础信息仍然建议按 OpenAPI 对象方式统一声明。(doc.xiaominfo.com)
Controller 怎么写,文档才会完整
如果只是把接口暴露出来而不写注解,Knife4j 也能扫描到基础信息,但说明会很贫瘠。实际项目里建议至少把接口摘要、字段含义、参数约束写出来。
请求对象
package com.example.demo.model.request;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Size;
@Schema(description = "创建用户请求")
public class UserCreateRequest {
@Schema(description = "用户名", example = "zhangsan")
@NotBlank(message = "用户名不能为空")
@Size(max = 32, message = "用户名长度不能超过32")
private String username;
@Schema(description = "邮箱", example = "zhangsan@example.com")
@NotBlank(message = "邮箱不能为空")
@Email(message = "邮箱格式不正确")
private String email;
@Schema(description = "昵称", example = "张三")
@Size(max = 50, message = "昵称长度不能超过50")
private String nickname;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getNickname() {
return nickname;
}
public void setNickname(String nickname) {
this.nickname = nickname;
}
}
返回对象
package com.example.demo.model.vo;
import io.swagger.v3.oas.annotations.media.Schema;
@Schema(description = "用户详情")
public class UserVO {
@Schema(description = "用户ID", example = "1")
private Long id;
@Schema(description = "用户名", example = "zhangsan")
private String username;
@Schema(description = "邮箱", example = "zhangsan@example.com")
private String email;
@Schema(description = "昵称", example = "张三")
private String nickname;
public UserVO() {
}
public UserVO(Long id, String username, String email, String nickname) {
this.id = id;
this.username = username;
this.email = email;
this.nickname = nickname;
}
public Long getId() {
return id;
}
public String getUsername() {
return username;
}
public String getEmail() {
return email;
}
public String getNickname() {
return nickname;
}
}
Controller 示例
package com.example.demo.controller;
import com.example.demo.model.request.UserCreateRequest;
import com.example.demo.model.vo.UserVO;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/users")
@Tag(name = "用户管理")
public class UserController {
@GetMapping("/{id}")
@Operation(summary = "根据ID查询用户")
public UserVO getById(
@Parameter(description = "用户ID", required = true, example = "1")
@PathVariable Long id) {
return new UserVO(id, "zhangsan", "zhangsan@example.com", "张三");
}
@PostMapping
@Operation(summary = "创建用户")
public UserVO create(@Valid @RequestBody UserCreateRequest request) {
return new UserVO(
1L,
request.getUsername(),
request.getEmail(),
request.getNickname()
);
}
}
这种写法有几个实际效果:
@Tag决定文档里的模块分组@Operation决定接口摘要@Schema决定模型字段说明jakarta.validation注解不仅参与运行时校验,也能帮助文档更准确展示字段约束
springdoc 官方文档明确说明,它会自动基于 Spring 配置、类结构和注解推断 API 语义,并支持校验注解信息的整合。(OpenAPI 3 Library for spring-boot)
启动后访问哪些地址
项目启动后,最常用的是这两个地址:
http://localhost:8080/doc.htmlhttp://localhost:8080/v3/api-docs
其中:
/doc.html是 Knife4j 的增强文档入口/v3/api-docs是 OpenAPI 原始描述数据- 如果你启用了
springdoc.swagger-ui.path=/swagger-ui.html,那么 Swagger UI 页面也会存在于对应路径下 (OpenAPI 3 Library for spring-boot)
很多团队会把 /v3/api-docs 作为网关聚合、测试平台或自动化工具的输入,把 /doc.html 作为日常联调入口,这样分层会更清楚。
如果项目接了 Spring Security
很多人说“Knife4j 配好了但打不开”,根因不是 Knife4j 本身,而是安全配置把文档地址拦住了。Boot 3 项目如果用了 Spring Security,至少要把文档相关路径放行。
package com.example.demo.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.web.SecurityFilterChain;
@Configuration
public class SecurityConfig {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.csrf(csrf -> csrf.disable())
.authorizeHttpRequests(auth -> auth
.requestMatchers(
"/doc.html",
"/swagger-ui.html",
"/swagger-ui/**",
"/v3/api-docs/**",
"/webjars/**"
).permitAll()
.anyRequest().authenticated()
)
.httpBasic(Customizer.withDefaults());
return http.build();
}
}
这里放行的重点不是只写 /doc.html,而是要把它依赖的静态资源和 OpenAPI 数据地址一起放开。否则页面能进,但脚本或接口文档请求还是会 401/403。
Boot 2 项目要怎么改
如果你的项目还在 Spring Boot 2,不是不能用 Knife4j,但要区分你当前走的是哪套规范。
Spring Boot 2 + OpenAPI 3
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-openapi3-spring-boot-starter</artifactId>
<version>4.4.0</version>
</dependency>
Spring Boot 2 + OpenAPI 2 / Swagger 2
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-openapi2-spring-boot-starter</artifactId>
<version>4.4.0</version>
</dependency>
Boot 2 和 Boot 3 最大的区别,不只是 starter 名字不同,而是 Boot 3 进入了 Jakarta 体系。因此你在代码里看到的校验、Servlet、注解生态都会和 Boot 2 的 javax.* 时代不同。Knife4j 官方文档也明确把 Boot 3 的 starter 单独拆成了 jakarta 版本。(doc.xiaominfo.com)
实战里最常见的几个坑
1. doc.html 返回 404
优先检查这几项:
- Starter 是否选错版本
- Boot 3 是否误用了 Boot 2 的 starter
- 是否被 Spring Security 拦截
- 是否又额外引入了别的 springdoc / swagger 相关依赖,导致资源路径或自动配置冲突
Boot 3 官方示例明确提示:Knife4j starter 已经引用 springdoc 相关 Jar,需要注意依赖冲突。(doc.xiaominfo.com)
2. 页面能打开,但没有接口
这个问题通常不是“Knife4j 扫不到”,而是“你限制了扫描范围”。
重点检查:
packages-to-scan是否写对包名paths-to-match是否把接口路径排除了- Controller 是否真的是
@RestController - 接口是否走了 WebMVC,而不是其他未被当前 starter 覆盖的模式
3. 模型字段说明不完整
根因一般有两个:
- DTO 没有写
@Schema - 只在实体类里堆数据库字段,没给接口层单独定义请求对象和返回对象
真正要把文档写清楚,接口模型最好和持久化模型分离。文档展示的是“接口契约”,不是数据库表结构。
4. Boot 3 项目里还在混用 javax.*
这个问题最隐蔽。项目能编译不代表文档一定正常,特别是从 Boot 2 升级上来的项目,常见情况是:
- 旧 DTO 还在用
javax.validation.* - 旧拦截器、过滤器还在用
javax.servlet.*
Boot 3 既然已经切到 Jakarta 体系,接口文档相关注解和校验体系也应一起迁移。
一套更适合团队项目的组织方式
单体项目里,Knife4j 常常只是“把接口展示出来”;但在团队项目里,更推荐按下面的方式组织:
- 用
group-configs按模块分组,比如用户、订单、支付 - 所有接口都补
@Operation - 请求对象、响应对象都补
@Schema - 对公共错误码、鉴权方式、Header 约定做统一描述
- 在网关层或 CI 流程里复用
/v3/api-docs
这样做的好处是,Knife4j 就不再只是一个“可视化页面”,而是项目接口契约的一部分。接口是否变更、参数是否新增、返回结构是否变化,都能通过代码提交一起被管理。
小结
Spring Boot 整合 Knife4j 本身并不复杂,真正容易出问题的地方有两个:版本选错,以及 把它当成一个纯前端页面看待。
只要记住下面这条线,整合基本不会偏:
- Boot 3:
knife4j-openapi3-jakarta-spring-boot-starter - Boot 2 + OpenAPI 3:
knife4j-openapi3-spring-boot-starter - Boot 2 + OpenAPI 2:
knife4j-openapi2-spring-boot-starter
然后围绕 springdoc 的思路去做扫描、分组、模型注解和安全放行,Knife4j 就能稳定落地。对于新项目,优先选 Spring Boot 3 + OpenAPI 3,这条路线更清晰,也更符合现在的文档生态。(doc.xiaominfo.com)
参考资料
- Knife4j 官方快速开始与 Spring Boot 2/3 版本说明。(doc.xiaominfo.com)
- springdoc-openapi 官方文档。(OpenAPI 3 Library for spring-boot)