网关接入新的 Knife4j 版本
parent
ec280224a8
commit
6f7df7e53e
|
@ -233,6 +233,11 @@
|
||||||
<artifactId>knife4j-openapi3-spring-boot-starter</artifactId>
|
<artifactId>knife4j-openapi3-spring-boot-starter</artifactId>
|
||||||
<version>${knife4j.version}</version>
|
<version>${knife4j.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.github.xiaoymin</groupId> <!-- 接口文档 UI:knife4j【网关专属】 -->
|
||||||
|
<artifactId>knife4j-gateway-spring-boot-starter</artifactId>
|
||||||
|
<version>${knife4j.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<!-- DB 相关 -->
|
<!-- DB 相关 -->
|
||||||
<dependency>
|
<dependency>
|
||||||
|
|
|
@ -58,8 +58,7 @@
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.github.xiaoymin</groupId> <!-- 接口文档 -->
|
<groupId>com.github.xiaoymin</groupId> <!-- 接口文档 -->
|
||||||
<artifactId>knife4j-spring-boot-starter</artifactId>
|
<artifactId>knife4j-gateway-spring-boot-starter</artifactId>
|
||||||
<version>3.0.3</version>
|
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- RPC 远程调用相关 -->
|
<!-- RPC 远程调用相关 -->
|
||||||
|
@ -85,7 +84,6 @@
|
||||||
<groupId>cn.iocoder.cloud</groupId>
|
<groupId>cn.iocoder.cloud</groupId>
|
||||||
<artifactId>yudao-spring-boot-starter-monitor</artifactId>
|
<artifactId>yudao-spring-boot-starter-monitor</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,54 +0,0 @@
|
||||||
package cn.iocoder.yudao.gateway.swagger;
|
|
||||||
|
|
||||||
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.http.HttpStatus;
|
|
||||||
import org.springframework.http.ResponseEntity;
|
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
|
||||||
import reactor.core.publisher.Mono;
|
|
||||||
import springfox.documentation.swagger.web.*;
|
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Swagger Controller
|
|
||||||
*
|
|
||||||
* @author zxliu
|
|
||||||
* @date 2022-10-25 11:24
|
|
||||||
*/
|
|
||||||
@RestController
|
|
||||||
@RequestMapping("/swagger-resources")
|
|
||||||
public class SwaggerHandler {
|
|
||||||
|
|
||||||
@Resource
|
|
||||||
private SwaggerResourcesProvider swaggerResources;
|
|
||||||
|
|
||||||
@SuppressWarnings("SpringJavaAutowiredFieldsWarningInspection") // 只有 @Autowired 可以实现可选注入
|
|
||||||
@Autowired(required = false)
|
|
||||||
private SecurityConfiguration securityConfiguration;
|
|
||||||
@SuppressWarnings("SpringJavaAutowiredFieldsWarningInspection") // 只有 @Autowired 可以实现可选注入
|
|
||||||
@Autowired(required = false)
|
|
||||||
private UiConfiguration uiConfiguration;
|
|
||||||
|
|
||||||
@GetMapping("")
|
|
||||||
public Mono<ResponseEntity<List<SwaggerResource>>> swaggerResources() {
|
|
||||||
return Mono.just((new ResponseEntity<>(swaggerResources.get(), HttpStatus.OK)));
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping("/configuration/security")
|
|
||||||
public Mono<ResponseEntity<SecurityConfiguration>> securityConfiguration() {
|
|
||||||
return Mono.just(new ResponseEntity<>(Optional.ofNullable(securityConfiguration)
|
|
||||||
.orElse(SecurityConfigurationBuilder.builder().build()), HttpStatus.OK));
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping("/configuration/ui")
|
|
||||||
public Mono<ResponseEntity<UiConfiguration>> uiConfiguration() {
|
|
||||||
return Mono.just(new ResponseEntity<>(Optional.ofNullable(uiConfiguration)
|
|
||||||
.orElse(UiConfigurationBuilder.builder().build()), HttpStatus.OK));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -2,45 +2,49 @@ package cn.iocoder.yudao.gateway.swagger;
|
||||||
|
|
||||||
import cn.hutool.core.collection.CollUtil;
|
import cn.hutool.core.collection.CollUtil;
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.cloud.gateway.config.GatewayProperties;
|
import org.springframework.cloud.gateway.config.GatewayProperties;
|
||||||
import org.springframework.cloud.gateway.handler.predicate.PredicateDefinition;
|
import org.springframework.cloud.gateway.handler.predicate.PredicateDefinition;
|
||||||
import org.springframework.cloud.gateway.route.RouteDefinition;
|
import org.springframework.cloud.gateway.route.RouteDefinition;
|
||||||
import org.springframework.cloud.gateway.support.NameUtils;
|
import org.springframework.cloud.gateway.support.NameUtils;
|
||||||
import org.springframework.context.annotation.Primary;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
import springfox.documentation.swagger.web.SwaggerResource;
|
import org.springframework.web.reactive.function.server.HandlerFunction;
|
||||||
import springfox.documentation.swagger.web.SwaggerResourcesProvider;
|
import org.springframework.web.reactive.function.server.ServerRequest;
|
||||||
|
import org.springframework.web.reactive.function.server.ServerResponse;
|
||||||
|
import reactor.core.publisher.Mono;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Swagger 资源的 Provider 实现类
|
* 获得 Swagger 资源的 {@link HandlerFunction} 实现类
|
||||||
*
|
*
|
||||||
* @author zxliu
|
* @author zxliu
|
||||||
* @since 2022-10-25 11:23
|
* @since 2022-10-25 11:23
|
||||||
*/
|
*/
|
||||||
@Component
|
@RequiredArgsConstructor
|
||||||
@Primary
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class SwaggerProvider implements SwaggerResourcesProvider {
|
public class SwaggerResourceHandlerFunction implements HandlerFunction<ServerResponse> {
|
||||||
|
|
||||||
@Resource
|
private final GatewayProperties gatewayProperties;
|
||||||
private GatewayProperties gatewayProperties;
|
|
||||||
|
@Override
|
||||||
|
public Mono<ServerResponse> handle(ServerRequest request) {
|
||||||
|
return ServerResponse.ok()
|
||||||
|
.contentType(MediaType.APPLICATION_JSON)
|
||||||
|
.bodyValue(getSwaggerResourceList());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获得 SwaggerResource 列表
|
* 获得 SwaggerResource 列表
|
||||||
*
|
*
|
||||||
* @return SwaggerResource 列表
|
* @return SwaggerResource 列表
|
||||||
*/
|
*/
|
||||||
@Override
|
public List<Map<String, String>> getSwaggerResourceList() {
|
||||||
public List<SwaggerResource> get() {
|
|
||||||
// 将 RouteDefinition 转换成 SwaggerResource
|
// 将 RouteDefinition 转换成 SwaggerResource
|
||||||
List<SwaggerResource> resources = new ArrayList<>();
|
List<Map<String, String>> resources = new ArrayList<>();
|
||||||
Set<String> serviceNames = new HashSet<>(); // 已处理的服务名,避免重复
|
Set<String> serviceNames = new HashSet<>(); // 已处理的服务名,避免重复
|
||||||
gatewayProperties.getRoutes().forEach(route -> {
|
gatewayProperties.getRoutes().forEach(route -> {
|
||||||
// 已存在的服务,直接忽略
|
// 已存在的服务,直接忽略
|
||||||
|
@ -64,11 +68,12 @@ public class SwaggerProvider implements SwaggerResourcesProvider {
|
||||||
return resources;
|
return resources;
|
||||||
}
|
}
|
||||||
|
|
||||||
private SwaggerResource buildSwaggerResource(String name, String location) {
|
private Map<String, String> buildSwaggerResource(String name, String location) {
|
||||||
SwaggerResource swaggerResource = new SwaggerResource();
|
Map<String, String> swaggerResource = new HashMap<>();
|
||||||
swaggerResource.setName(name);
|
swaggerResource.put("name", name);
|
||||||
swaggerResource.setLocation(location);
|
swaggerResource.put("location", location);
|
||||||
swaggerResource.setSwaggerVersion("3.0.3");
|
swaggerResource.put("url", location);
|
||||||
|
swaggerResource.put("swaggerVersion", "3.0.3");
|
||||||
return swaggerResource;
|
return swaggerResource;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,42 @@
|
||||||
|
package cn.iocoder.yudao.gateway.swagger;
|
||||||
|
|
||||||
|
import com.github.xiaoymin.knife4j.spring.gateway.configuration.Knife4jGatewayAutoConfiguration;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||||
|
import org.springframework.cloud.gateway.config.GatewayProperties;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.web.reactive.function.server.RouterFunction;
|
||||||
|
import org.springframework.web.reactive.function.server.RouterFunctions;
|
||||||
|
import org.springframework.web.reactive.function.server.ServerResponse;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 网关 Swagger 接口文档的自动配置类
|
||||||
|
*
|
||||||
|
* 参考 {@link Knife4jGatewayAutoConfiguration} 实现,进行功能的增强,核心实现在 {@link SwaggerResourceHandlerFunction} 类中
|
||||||
|
* 它通过解析 spring.cloud.gateway.routes 配置,获得 Swagger 资源分组。
|
||||||
|
*
|
||||||
|
* 另外,目前官方 Knif4j 网关的实现,不会通过注册中心加载对应的 URL 地址。等到他们完善了,就可以去掉自己的这个实现了。
|
||||||
|
*
|
||||||
|
* @see <a href="https://doc.xiaominfo.com/docs/middleware-sources/spring-cloud-gateway/spring-gateway-introduction">Knife4j + Spring Cloud Gateway 网关聚合</a>
|
||||||
|
*
|
||||||
|
* @author 芋道源码
|
||||||
|
*/
|
||||||
|
@Configuration
|
||||||
|
@ConditionalOnProperty(name = "knife4j.gateway.enable", havingValue = "true")
|
||||||
|
@Slf4j
|
||||||
|
public class YudaoSwaggerAutoConfiguration {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Swagger 资源分组 URL
|
||||||
|
*/
|
||||||
|
public static final String GATEWAY_SWAGGER_GROUP_URL = "/swagger-resources";
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public RouterFunction<ServerResponse> swaggerResourceHandlerFunction(GatewayProperties gatewayProperties) {
|
||||||
|
log.info("[swaggerResourceHandlerFunction][初始化完成]");
|
||||||
|
SwaggerResourceHandlerFunction handlerFunction = new SwaggerResourceHandlerFunction(gatewayProperties);
|
||||||
|
return RouterFunctions.route().GET(GATEWAY_SWAGGER_GROUP_URL, handlerFunction).build();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -49,3 +49,8 @@ spring:
|
||||||
- Path=/jmreport/**
|
- Path=/jmreport/**
|
||||||
x-forwarded:
|
x-forwarded:
|
||||||
prefix-enabled: false # 避免 Swagger 重复带上额外的 /admin-api/system 前缀
|
prefix-enabled: false # 避免 Swagger 重复带上额外的 /admin-api/system 前缀
|
||||||
|
|
||||||
|
knife4j:
|
||||||
|
# 聚合 Swagger 文档
|
||||||
|
gateway:
|
||||||
|
enable: true
|
||||||
|
|
Loading…
Reference in New Issue