diff --git a/yudao-dependencies/pom.xml b/yudao-dependencies/pom.xml index 0846e47c3..228c99b2f 100644 --- a/yudao-dependencies/pom.xml +++ b/yudao-dependencies/pom.xml @@ -233,6 +233,11 @@ knife4j-openapi3-spring-boot-starter ${knife4j.version} + + com.github.xiaoymin + knife4j-gateway-spring-boot-starter + ${knife4j.version} + diff --git a/yudao-gateway/pom.xml b/yudao-gateway/pom.xml index cef02f3d9..e605770e2 100644 --- a/yudao-gateway/pom.xml +++ b/yudao-gateway/pom.xml @@ -58,8 +58,7 @@ com.github.xiaoymin - knife4j-spring-boot-starter - 3.0.3 + knife4j-gateway-spring-boot-starter @@ -85,7 +84,6 @@ cn.iocoder.cloud yudao-spring-boot-starter-monitor - diff --git a/yudao-gateway/src/main/java/cn/iocoder/yudao/gateway/swagger/SwaggerHandler.java b/yudao-gateway/src/main/java/cn/iocoder/yudao/gateway/swagger/SwaggerHandler.java deleted file mode 100644 index 7cae3c810..000000000 --- a/yudao-gateway/src/main/java/cn/iocoder/yudao/gateway/swagger/SwaggerHandler.java +++ /dev/null @@ -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>> swaggerResources() { - return Mono.just((new ResponseEntity<>(swaggerResources.get(), HttpStatus.OK))); - } - - @GetMapping("/configuration/security") - public Mono> securityConfiguration() { - return Mono.just(new ResponseEntity<>(Optional.ofNullable(securityConfiguration) - .orElse(SecurityConfigurationBuilder.builder().build()), HttpStatus.OK)); - } - - @GetMapping("/configuration/ui") - public Mono> uiConfiguration() { - return Mono.just(new ResponseEntity<>(Optional.ofNullable(uiConfiguration) - .orElse(UiConfigurationBuilder.builder().build()), HttpStatus.OK)); - } - -} diff --git a/yudao-gateway/src/main/java/cn/iocoder/yudao/gateway/swagger/SwaggerProvider.java b/yudao-gateway/src/main/java/cn/iocoder/yudao/gateway/swagger/SwaggerResourceHandlerFunction.java similarity index 66% rename from yudao-gateway/src/main/java/cn/iocoder/yudao/gateway/swagger/SwaggerProvider.java rename to yudao-gateway/src/main/java/cn/iocoder/yudao/gateway/swagger/SwaggerResourceHandlerFunction.java index 03aee0fbc..b88a50e2b 100644 --- a/yudao-gateway/src/main/java/cn/iocoder/yudao/gateway/swagger/SwaggerProvider.java +++ b/yudao-gateway/src/main/java/cn/iocoder/yudao/gateway/swagger/SwaggerResourceHandlerFunction.java @@ -2,45 +2,49 @@ package cn.iocoder.yudao.gateway.swagger; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.util.StrUtil; +import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.cloud.gateway.config.GatewayProperties; import org.springframework.cloud.gateway.handler.predicate.PredicateDefinition; import org.springframework.cloud.gateway.route.RouteDefinition; import org.springframework.cloud.gateway.support.NameUtils; -import org.springframework.context.annotation.Primary; +import org.springframework.http.MediaType; import org.springframework.stereotype.Component; -import springfox.documentation.swagger.web.SwaggerResource; -import springfox.documentation.swagger.web.SwaggerResourcesProvider; +import org.springframework.web.reactive.function.server.HandlerFunction; +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 java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Set; +import java.util.*; /** - * Swagger 资源的 Provider 实现类 + * 获得 Swagger 资源的 {@link HandlerFunction} 实现类 * * @author zxliu * @since 2022-10-25 11:23 */ -@Component -@Primary +@RequiredArgsConstructor @Slf4j -public class SwaggerProvider implements SwaggerResourcesProvider { +public class SwaggerResourceHandlerFunction implements HandlerFunction { - @Resource - private GatewayProperties gatewayProperties; + private final GatewayProperties gatewayProperties; + + @Override + public Mono handle(ServerRequest request) { + return ServerResponse.ok() + .contentType(MediaType.APPLICATION_JSON) + .bodyValue(getSwaggerResourceList()); + } /** * 获得 SwaggerResource 列表 * * @return SwaggerResource 列表 */ - @Override - public List get() { + public List> getSwaggerResourceList() { // 将 RouteDefinition 转换成 SwaggerResource - List resources = new ArrayList<>(); + List> resources = new ArrayList<>(); Set serviceNames = new HashSet<>(); // 已处理的服务名,避免重复 gatewayProperties.getRoutes().forEach(route -> { // 已存在的服务,直接忽略 @@ -64,11 +68,12 @@ public class SwaggerProvider implements SwaggerResourcesProvider { return resources; } - private SwaggerResource buildSwaggerResource(String name, String location) { - SwaggerResource swaggerResource = new SwaggerResource(); - swaggerResource.setName(name); - swaggerResource.setLocation(location); - swaggerResource.setSwaggerVersion("3.0.3"); + private Map buildSwaggerResource(String name, String location) { + Map swaggerResource = new HashMap<>(); + swaggerResource.put("name", name); + swaggerResource.put("location", location); + swaggerResource.put("url", location); + swaggerResource.put("swaggerVersion", "3.0.3"); return swaggerResource; } diff --git a/yudao-gateway/src/main/java/cn/iocoder/yudao/gateway/swagger/YudaoSwaggerAutoConfiguration.java b/yudao-gateway/src/main/java/cn/iocoder/yudao/gateway/swagger/YudaoSwaggerAutoConfiguration.java new file mode 100644 index 000000000..313a956f8 --- /dev/null +++ b/yudao-gateway/src/main/java/cn/iocoder/yudao/gateway/swagger/YudaoSwaggerAutoConfiguration.java @@ -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 Knife4j + Spring Cloud Gateway 网关聚合 + * + * @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 swaggerResourceHandlerFunction(GatewayProperties gatewayProperties) { + log.info("[swaggerResourceHandlerFunction][初始化完成]"); + SwaggerResourceHandlerFunction handlerFunction = new SwaggerResourceHandlerFunction(gatewayProperties); + return RouterFunctions.route().GET(GATEWAY_SWAGGER_GROUP_URL, handlerFunction).build(); + } + +} diff --git a/yudao-gateway/src/main/resources/application.yaml b/yudao-gateway/src/main/resources/application.yaml index 6a3a6257c..211dfb596 100644 --- a/yudao-gateway/src/main/resources/application.yaml +++ b/yudao-gateway/src/main/resources/application.yaml @@ -49,3 +49,8 @@ spring: - Path=/jmreport/** x-forwarded: prefix-enabled: false # 避免 Swagger 重复带上额外的 /admin-api/system 前缀 + +knife4j: + # 聚合 Swagger 文档 + gateway: + enable: true