在微服务化的过程中,每个微服务都有自己的 swagger 接口,能不能在统一的一个地方显示,比如在网关显示
springboot + zuul + swagger 就不说了,网上一搜一大把
SwaggerButler (https://github.com/dyc87112/swagger-butler)是一个开源项目,方便集成 swagger-zuul 聚合网关的,大家看看文档就行
如果笔者一切顺利,就不会有这篇博客了。这里说一下笔者遇到的问题
如果你的各个微服务没有设置 server.servlet.context-path 就不用往下看了
1 当 通过 SwaggerButler 聚合网关之后
2 在网关的swagger-ui
3 通过 zuul 调用带有 context-path 的服务的接口
4 发现 404
如果你打印了 请求路由,你会发现缺少了 context-path
通过新增 zuul 的前缀过滤器, 修改 x-forwarded-prefix,拼接上下文解决
package com.surfilter.core.config.swagger;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.X_FORWARDED_PREFIX_HEADER;
/**
* @description: 转换请求头, 添加上下文
* @author: huangwenjun
* @createDate: 2019/12/20
*/
@Slf4j
public class XForwardedFilter extends ZuulFilter {
@Autowired
SwaggerButlerProperties swaggerButlerProperties;
@Override
public String filterType() {
return "pre";
}
@Override
public int filterOrder() {
return 6;
}
@Override
public boolean shouldFilter() {
RequestContext ctx = RequestContext.getCurrentContext();
String prefix = ctx.getZuulRequestHeaders().get("x-forwarded-prefix");
if (StringUtils.isNotBlank(prefix)) {
return true;
}
return false;
}
@Override
public Object run() {
try {
RequestContext ctx = RequestContext.getCurrentContext();
String prefix = ctx.getZuulRequestHeaders().get("x-forwarded-prefix");
if (StringUtils.isNotBlank(prefix)) {
String serviceId = String.valueOf(ctx.get("serviceId"));
String contextPath = swaggerButlerProperties.getServiceContextConfig().get(serviceId);
if (StringUtils.isNotBlank(contextPath)) {
contextPath = "/" + contextPath;
prefix = prefix + contextPath;
ctx.addZuulRequestHeader(X_FORWARDED_PREFIX_HEADER, prefix);
}
}
} catch (Exception e) {
log.error("请求头 x-forwarded-prefix 转换失败 {}", e);
}
return null;
}
}
# 聚合网关配置
swagger.butler.auto-generate-from-zuul-routes=true
# 配置需要聚合的服务id
swagger.butler.generate-routes=ga-system-service-252,ga-data-open-service-hwj
# serviceId 和 context-path 的映射
swagger.butler.serviceContextConfig.ga-system-service-252=system
swagger.butler.serviceContextConfig.ga-data-open-service-hwj=dataservice
如果你去看看 Swagger2Controller 源码就知道了
如果传了 x-forwarded-prefix ,则会根据传的参数确定 basePath
swagger basePath 拼装接口路由
其实 getway 实现聚合网关的方式应该类似
无非就是要多传一个 x-forwarded-prefix
笔者没用实现过,就不多说了