SpringCloudGateway+Discovery+Swagger 动态更新分组API清单

SpringCloudGateway+Discovery+Swagger 搭建服务文档中心
中使用配置方法创建分组API清单,如果服务发生变更,需重启gateway才能生效

解决

修改SwaggerConfig.java

@Configuration
public class SwaggerConfig {
	...
	// 注入SWAGGER-UI配置参数
    @Autowired
    SwaggerUiConfigParameters swaggerUiConfigParameters;
    ...
      // 撤销分组API JAVA配置
//    @Bean
//    public List<GroupedOpenApi> apis() {
//        List<GroupedOpenApi> groups = new ArrayList<>();
//        List<RouteDefinition> definitions = locator.getRouteDefinitions().collectList().block();
//        definitions.stream().forEach(routeDefinition -> {
//            String name = routeDefinition.getUri().getHost();
//            GroupedOpenApi groupedOpenApi =
//                    GroupedOpenApi.builder()
//                            .group(name)
//                            .pathsToMatch(
//                                    routeDefinition.getPredicates().get(0).getArgs().get("pattern")
//                            ).build();
//            groups.add(groupedOpenApi);
//        });
//        return groups;
//    }
	// 定时更新API分组
    @Scheduled(fixedDelay = 200)
    public void refreshGroupedApi() {
        List<RouteDefinition> definitions = locator.getRouteDefinitions().collectList().block();
        swaggerUiConfigParameters.getUrls().clear();
        definitions.stream().forEach(routeDefinition -> {
            String name = routeDefinition.getUri().getHost();
            swaggerUiConfigParameters.addGroup(name);
        });
    }
}

源码分析

SWAGGER-UI获取配置信息的端点
org.springdoc.webflux.ui.SwaggerWelcomeActuator

@ControllerEndpoint(
    id = "swaggerui"
)
public class SwaggerWelcomeActuator extends SwaggerWelcomeCommon {
	@GetMapping(
        value = {"/swagger-config"},
        produces = {"application/json"}
    )
    @ResponseBody
    public Map<String, Object> getSwaggerUiConfig(ServerHttpRequest request) {
        return super.getSwaggerUiConfig(request);
    }
}

org.springdoc.webflux.ui.AbstractSwaggerWelcome

public abstract class SwaggerWelcomeCommon extends AbstractSwaggerWelcome {
	// 构造时注入swaggerUiConfigParameters
	public AbstractSwaggerWelcome(SwaggerUiConfigProperties swaggerUiConfig, SpringDocConfigProperties springDocConfigProperties, SwaggerUiConfigParameters swaggerUiConfigParameters) {
		this.swaggerUiConfig = swaggerUiConfig;
		this.springDocConfigProperties = springDocConfigProperties;
		this.swaggerUiConfigParameters = swaggerUiConfigParameters;
	}
	// 这里会根据分组API配置来创建UI需要使用的分组下拉清单数据
	@Override
	public void afterPropertiesSet() {
		springDocConfigProperties.getGroupConfigs().forEach(groupConfig -> swaggerUiConfigParameters.addGroup(groupConfig.getGroup()));
		calculateUiRootPath();
	}
	protected Map<String, Object> getSwaggerUiConfig(ServerHttpRequest request) {
		this.buildFromCurrentContextPath(request);
		return swaggerUiConfigParameters.getConfigParameters();
	}
	private void buildFromCurrentContextPath(ServerHttpRequest request) {
		contextPath = request.getPath().contextPath().value();
		String url = UriComponentsBuilder.fromHttpRequest(request).toUriString();
		if (!AntPathMatcher.DEFAULT_PATH_SEPARATOR.equals(request.getPath().toString()))
			url = url.replace(request.getPath().toString(), "");
		buildConfigUrl(UriComponentsBuilder.fromUriString(url));
	}
}

org.springdoc.webflux.ui.AbstractSwaggerWelcome

public abstract class AbstractSwaggerWelcome implements InitializingBean {
	protected void buildConfigUrl(UriComponentsBuilder uriComponentsBuilder) {
		if (StringUtils.isEmpty(swaggerUiConfig.getConfigUrl())) {
			apiDocsUrl = buildApiDocUrl();
			swaggerConfigUrl = buildSwaggerConfigUrl(); // 默认值为 /v3/api-docs
			swaggerUiConfigParameters.setConfigUrl(swaggerConfigUrl);
			if (CollectionUtils.isEmpty(swaggerUiConfigParameters.getUrls())) {
				String swaggerUiUrl = swaggerUiConfig.getUrl();
				if (StringUtils.isEmpty(swaggerUiUrl))
					swaggerUiConfigParameters.setUrl(apiDocsUrl);
				else
					swaggerUiConfigParameters.setUrl(swaggerUiUrl); // 这一步会给每个api分组的配置url初始化赋值 /v3/api-docs/groupedApiName
			}
			else
				swaggerUiConfigParameters.addUrl(apiDocsUrl);
		}
		calculateOauth2RedirectUrl(uriComponentsBuilder);
	}
}

org.springdoc.core.SwaggerUiConfigParameters

public class SwaggerUiConfigParameters extends AbstractSwaggerUiConfigProperties {
	public void addUrl(String url) {
		this.urls.forEach(elt ->
				{
					if (!isSwaggerUrlDefined(elt.getName()))
						elt.setUrl(url + DEFAULT_PATH_SEPARATOR + elt.getName());
				}
		);
	}
}

posted on   路过君  阅读(94)  评论(0编辑  收藏  举报

相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?
历史上的今天:
2020-04-11 spring 启动时自动运行
2020-04-11 spring cloud oauth2授权服务 默认tokenService配置源码
2020-04-11 spring cloud 搭建oauth2授权服务 使用redis存储令牌
2020-04-11 spring cloud oauth2授权服务 clientDetails配置源码
2020-04-11 spring 验证框架
2020-04-11 IDEA 插件整理
2020-04-11 spring security笔记 默认登陆页面源码

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
点击右上角即可分享
微信分享提示