SpringBoot3.x SpringCloudGateway与SpringDoc OpenApi整合

 

网关的配置文件

这个是用来转发各个服务的 /v3/api-docs 请求

      routes:
        # 转发swagger接口
        - id: openapi
          uri: http://localhost:${server.port}
          predicates:
            - Path=/service/v3/api-docs/**
          filters:
            - RewritePath=/service/v3/api-docs/(?<path>.*), /$\{path}/v3/api-docs

网关的swagger配置,去掉前缀,就可以直接用 ip:port/swagger-ui/index.html 访问了

springdoc:
  swagger-ui:
    # 禁止默认路径
    disable-swagger-default-url: true
  webjars:
    # 设置为空,不要前缀
    prefix:

Swagger配置类

@Configuration
public class SwaggerConfig {

    @Value(value = "${server.port:8080}")
    private int port;

    @Bean
    public OpenAPI springShopOpenApi() {
        final String loginToken = "BearerAuth";
        return new OpenAPI().info(new Info().title("API")
                        .description("Sky网关")
                        .version("v1.0.0")).externalDocs(new ExternalDocumentation()
                        .description("Sky网关")
                        .url("http://127.0.0.1:" + port))
                .components(new Components().addSecuritySchemes(loginToken, new SecurityScheme()
                        .type(SecurityScheme.Type.HTTP).scheme("Bearer").bearerFormat("JWT")
                        .in(SecurityScheme.In.HEADER)
                        .name(loginToken)))
                .addSecurityItem(new SecurityRequirement().addList(loginToken));
    }

    @Bean
    public GroupedOpenApi service2Api() {
        String[] paths = {"/_default/**"};
        return GroupedOpenApi.builder().group("_default")
                .pathsToMatch(paths)
                .build();
    }

}

动态刷新Swagger下拉


@Component
public class InstancesChangeEventListener extends Subscriber<InstancesChangeEvent> implements InitializingBean {

private static final Logger logger = LoggerFactory.getLogger(InstancesChangeEventListener.class);

@Autowired
private RouteLocator routeLocator;
@Autowired
private SwaggerUiConfigProperties swaggerUiConfigProperties;
@Value("${spring.application.name}")
private String applicationName;

private Set<AbstractSwaggerUiConfigProperties.SwaggerUrl> urls;

@PostConstruct
private void post() {
NotifyCenter.registerSubscriber(this);
}


/**
* Event callback.
*
* @param event {@link Event}
*/
@Override
public void onEvent(InstancesChangeEvent event) {
logger.info("接收到 InstancesChangeEvent 订阅事件:{}", JSON.toJSONString(event));

CachingRouteLocator cachingRouteLocator = (CachingRouteLocator) routeLocator;
cachingRouteLocator.refresh();

List<Route> routeList = routeLocator.getRoutes().collectList().block();

System.out.println(routeList);

LinkedHashSet<AbstractSwaggerUiConfigProperties.SwaggerUrl> set = new LinkedHashSet<>();

if (CollectionUtils.isNotEmpty(this.urls)) {
set.addAll(this.urls);
}

for (Route route : routeList) {
if (route.getMetadata().size() > 0) {
// ReactiveCompositeDiscoveryClient_sky-user
String id = route.getId();
String name = id.replaceAll("ReactiveCompositeDiscoveryClient_", "");
if (applicationName.equals(name)) {
continue;
}
set.add(new AbstractSwaggerUiConfigProperties.SwaggerUrl(name, "/service/v3/api-docs/" + name, ""));
}
}

if (CollectionUtils.isEmpty(set)) {
set.add(new AbstractSwaggerUiConfigProperties.SwaggerUrl("_default", "/v3/api-docs/_default", ""));
}

swaggerUiConfigProperties.setUrls(set);

}

/**
* Type of this subscriber's subscription.
*
* @return Class which extends {@link Event}
*/
@Override
public Class<? extends com.alibaba.nacos.common.notify.Event> subscribeType() {
return InstancesChangeEvent.class;
}

@Override
public void afterPropertiesSet() throws Exception {
this.urls = this.swaggerUiConfigProperties.getUrls();
}
}
 

当没有服务注册在线时,就显示_default这个分组,也避免了报错

 

posted @ 2023-01-29 17:02  Se7end  阅读(2277)  评论(0编辑  收藏  举报