在 Spring Boot 2.x + Spring Cloud Gateway(基于 WebFlux) 的项目中集成 Knife4j,由于 Spring Boot 2 使用的是 Servlet API(javax) 而不是 Jakarta,且 Gateway 是响应式(WebFlux)架构,不能直接使用传统的 Swagger2(Springfox),推荐使用 Springdoc OpenAPI v1.x + Knife4j 3.x 的组合。
✅ 注意:Spring Boot 2.x 不兼容 Knife4j 4.x(Jakarta 版本),必须使用 Knife4j 3.x。
springdoc-openapi-webmvc-core 暴露 /v3/api-docs;springdoc-openapi-webflux + knife4j-spring-boot-starter(3.x)提供统一 UI;GroupedOpenApi 聚合多个服务的文档。<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-webmvc-core</artifactId>
<version>1.7.0</version>
</dependency>
<!-- 可选:如果需要 Swagger UI(微服务单独访问) -->
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-ui</artifactId>
<version>1.7.0</version>
</dependency>
springdoc:
api-docs:
path: /v3/api-docs
swagger-ui:
path: /swagger-ui.html
启动后可通过 http://user-service:port/v3/api-docs 获取 JSON 文档。
<!-- Springdoc WebFlux 支持(用于 Gateway) -->
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-webflux-core</artifactId>
<version>1.7.0</version>
</dependency>
<!-- Knife4j 增强 UI(Spring Boot 2 兼容版) -->
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-spring-boot-starter</artifactId>
<version>3.0.3</version> <!-- 最高支持到 3.x -->
</dependency>
⚠️ 切勿使用
knife4j-openapi3-jakarta-spring-boot-starter(这是给 Spring Boot 3 用的)!
确保能访问下游服务的 OpenAPI 文档:
spring:
cloud:
gateway:
routes:
# 用户服务
- id: user-service
uri: lb://user-service
predicates:
- Path=/user-service/**
filters:
- StripPrefix=1
# 订单服务
- id: order-service
uri: lb://order-service
predicates:
- Path=/order-service/**
filters:
- StripPrefix=1
# 转发 Swagger 文档(关键!)
- id: user-service-api-docs
uri: lb://user-service
predicates:
- Path=/user-service/v3/api-docs
- id: order-service-api-docs
uri: lb://order-service
predicates:
- Path=/order-service/v3/api-docs
这样可以通过:
- http://gateway:port/user-service/v3/api-docs
- http://gateway:port/order-service/v3/api-docs
访问各服务的 OpenAPI 文档。
在网关项目中创建如下配置类:
@Configuration
public class SwaggerResourceConfig {
// 手动定义需要聚合的服务列表
private static final List<String> SERVICES = Arrays.asList("user-service", "order-service");
@Bean
public RouteLocator routeLocator(RouteLocatorBuilder builder) {
return builder.routes().build(); // 仅用于注入 RouteLocator
}
/**
* 提供聚合后的 OpenAPI 资源(用于 Knife4j 分组)
*/
@Bean
public List<GroupedOpenApi> groupedOpenApis() {
return SERVICES.stream()
.map(serviceName -> GroupedOpenApi.builder()
.group(serviceName)
.pathsToMatch("/" + serviceName + "/**")
.build())
.collect(Collectors.toList());
}
}
说明:
GroupedOpenApi会自动为每个 group 生成对应的/v3/api-docs/{groupName},但实际文档仍需通过路由转发到下游服务。因此更推荐使用 自定义 OpenAPI 聚合方式(见下文进阶方案)。
⚠️ 注意:GroupedOpenApi 在 Gateway 中 不会自动拉取远程服务的 OpenAPI 内容,它只适用于本地 Controller。
因此,要真正聚合多个微服务的文档,需要 手动拉取远程 /v3/api-docs 并合并。
SwaggerResourcesProvider(兼容 Springdoc)但由于 Springdoc 已取代 Swagger2,更推荐使用 knife4j-gateway 官方提供的聚合方式。
knife4j 提供的 OpenApiAggregator@Component
@RequiredArgsConstructor
public class OpenApiAggregator {
private final WebClient.Builder webClientBuilder;
public Map<String, Object> getOpenApiFromService(String serviceUrl) {
WebClient client = webClientBuilder.build();
try {
return client.get()
.uri(serviceUrl + "/v3/api-docs")
.retrieve()
.bodyToMono(new ParameterizedTypeReference<Map<String, Object>>() {})
.block(Duration.ofSeconds(5));
} catch (Exception e) {
log.warn("Failed to fetch OpenAPI from {}", serviceUrl, e);
return Collections.emptyMap();
}
}
}
但更简单的方式是:**直接让 Knife4j UI 通过网关路由访问各服务的 /v3/api-docs**,并在前端选择不同服务。
knife4j:
enable: true
production: false
basic:
enable: true
username: admin
password: 123456
启动网关后,访问:
http://localhost:8080/doc.html
在 Knife4j 页面顶部的 “分组”下拉框 中,会显示 user-service、order-service 等分组(前提是配置了 GroupedOpenApi)。
💡 但注意:此时点击分组,Knife4j 会请求
/v3/api-docs/user-service,而该路径在网关本地并不存在!
在 doc.html 页面中,Knife4j 支持手动添加多个 OpenAPI 地址:
http://gateway:8080/doc.html/user-service/v3/api-docs/order-service/v3/api-docs即可切换查看不同服务的 API。
这是最简单、最可靠的方式,无需复杂聚合逻辑。
| 组件 | 依赖版本 |
|---|---|
| Spring Boot | 2.7.x |
| Spring Cloud | 2021.0.x |
| springdoc-openapi | 1.7.0 |
| knife4j-spring-boot-starter | 3.0.3 |
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-webflux-core</artifactId>
<version>1.7.0</version>
</dependency>
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-spring-boot-starter</artifactId>
<version>3.0.3</version>
</dependency>
/xxx/v3/api-docs 可访问;doc.html 手动添加多个文档地址,实现聚合效果。如有需要,也可考虑使用 smart-doc + [smart-doc-maven-plugin] 自动生成静态文档,避免运行时聚合问题。