网关接入新的 Knife4j 版本

This commit is contained in:
YunaiV 2023-03-04 17:57:58 +08:00
parent ec280224a8
commit 6f7df7e53e
6 changed files with 79 additions and 78 deletions

View File

@ -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> <!-- 接口文档 UIknife4j【网关专属】 -->
<artifactId>knife4j-gateway-spring-boot-starter</artifactId>
<version>${knife4j.version}</version>
</dependency>
<!-- DB 相关 --> <!-- DB 相关 -->
<dependency> <dependency>

View File

@ -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>

View File

@ -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));
}
}

View File

@ -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;
} }

View File

@ -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();
}
}

View File

@ -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