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 2022-04-11 22:38  路过君  阅读(91)  评论(0编辑  收藏  举报

导航