问题起因:使用Zuul网关服务,需要整合下游系统的swagger,但是下游服务存在context-path配置,无法正确跳转,最后使用ZuulFilter解决。

1.Zuul整合下游swagger

首先介绍一下Zuul如何整合下游服务swagger,很好理解,就是通过Zuul的swagger地址,实现将下游服务的swagger都放入同一个页面内,流转图如下:

1.1 下游服务整合swagger

这里进行简单介绍服务整合swagger的步骤其实就是分为两步:

  1. 配置swagger
  2. 对api和model等进行注释

这里不做代码介绍,具体可以查看我的另一篇文章:https://www.dalaoyang.cn/article/21,或者查看本文源码。

这里只新建了一个服务,服务名为test-service。

1.2 Zuul聚合下游Swagger

Zuul相关配置这里不做介绍,首先配置下游服务路由,即访问test-service/**转发到test-service服务,配置如下:

zuul.routes.test-service.path=/test-service/**
zuul.routes.test-service.service-id=test-service

配置swagger配置文件,如下:

@Configuration
@EnableSwagger2
public class SwaggerConfig { @Bean
public Docket createRestApi() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo());
} private ApiInfo apiInfo() {
return new ApiInfoBuilder()
.title("使用Swagger2构建RESTful APIs")
.description("关注博主博客:https://www.dalaoyang.cn/")
.termsOfServiceUrl("https://www.dalaoyang.cn/")
.contact("dalaoyang")
.version("1.0")
.build();
}
}

新建文档配置,这里主要目的是为了聚合下游服务的swagger,内容很好理解,就是讲SwaggerResource赋值,其中name为swagger的api文档名,location为对应api-docs地址,version为版本,这里利用ZuulProperties来生成对应文档,避免写死代码,完整内容如下:

@Primary
@Component
public class DocumentConfig implements SwaggerResourcesProvider { @Autowired
private ZuulProperties zuulProperties; @Override
public List<SwaggerResource> get() {
List<SwaggerResource> swaggerResources = new ArrayList<>();
Map<String, ZuulProperties.ZuulRoute> routes = zuulProperties.getRoutes();
for (String serviceName : routes.keySet()) {
SwaggerResource swaggerResource = initSwaggerResource(serviceName,
"/" + serviceName + "/v2/api-docs", "1.0.0");
swaggerResources.add(swaggerResource);
}
return swaggerResources;
} private SwaggerResource initSwaggerResource(String name, String location, String version) {
SwaggerResource swaggerResource = new SwaggerResource();
swaggerResource.setName(name);
swaggerResource.setLocation(location);
swaggerResource.setSwaggerVersion(version);
return swaggerResource;
}
}

配置到这里,其实已经完成了,访问网关swagger如图所示:

2.下游服务存在context-path怎么办?

从上面其实可以了解到,聚合文档的操作,其实就是将下游服务的/v2/api-docs整合进来,当然,可以在本文DocumentConfig中将下游服务context-path加入其中,注意注释阶段,完整代码如下:

@Primary
@Component
public class DocumentConfig implements SwaggerResourcesProvider { @Autowired
private ZuulProperties zuulProperties; @Override
public List<SwaggerResource> get() {
List<SwaggerResource> swaggerResources = new ArrayList<>();
Map<String, ZuulProperties.ZuulRoute> routes = zuulProperties.getRoutes();
for (String serviceName : routes.keySet()) {
//假设下游服务的context-path为服务名
SwaggerResource swaggerResource = initSwaggerResource(serviceName,
"/" + serviceName +"/" + serviceName + "/v2/api-docs", "1.0.0");
swaggerResources.add(swaggerResource);
}
return swaggerResources;
} private SwaggerResource initSwaggerResource(String name, String location, String version) {
SwaggerResource swaggerResource = new SwaggerResource();
swaggerResource.setName(name);
swaggerResource.setLocation(location);
swaggerResource.setSwaggerVersion(version);
return swaggerResource;
}
}

下游服务加入context-path配置,如下:

server.servlet.context-path=/test-service

启动服务,访问Zuul的swagger文档,还是可以同样的访问,但是测试一下在swagger请求一下下游服务api,如下

很明显,404的原因就是因为转发下游服务的时候,没有加上context-path,在本文DocumentConfig配置的方式肯定不是正确的方式,那么如何解决呢?

可以加入一个ZuulFilter来进行统一添加下游服务context-path,首先还原上面修改的DocumentConfig,接下来新建一个Filter继承ZuulFilter,创建一个转发前的拦截器,将转发地址进行修改,也就是我们需要的加入context-pa路径,由于本文下游context-path路径为服务名,所以案例比较简单,内容如下:

@Component
public class UrlPathFilter extends ZuulFilter { @Override
public String filterType() {
return FilterConstants.PRE_TYPE;
} @Override
public int filterOrder() {
return 6;
} @Override
public boolean shouldFilter() {
return true;
} @Override
public Object run() throws ZuulException {
RequestContext requestContext = RequestContext.getCurrentContext();
Object requestURI = requestContext.get(FilterConstants.REQUEST_URI_KEY);
Object server = requestContext.get(FilterConstants.PROXY_KEY);
String finalURI = "/" + server + requestURI;
requestContext.put(FilterConstants.REQUEST_URI_KEY, finalURI);
return null;
}
}

需要注意一点,这个拦截器需要在默认ZuulFilter后执行,才能获取requestURI和server。

再次启动项目,就可以正常使用和访问swagger了。

3.源码地址

Zuul地址:https://gitee.com/dalaoyang/springcloud_learn/tree/master/springcloud_swagger_zuul

Test-service地址:https://gitee.com/dalaoyang/springcloud_learn/tree/master/springcloud_swagger_service

Zuul整合Swagger,使用ZuulFilter解决下游服务context-path的更多相关文章

  1. Spring Cloud Zuul 网关的分布式系统中整合Swagger(转)和 zuul跨域访问问题

    首先恭喜自己终于找对了努力的方向,很荣幸能在公司接触到微服务架构,也很高兴公司一个大佬哥们愿意带我,他技术确实很牛逼,我也很佩服他,前后端通吃,干了六年能有这样的水平.最近跟着在搞微服务架构,给我分配 ...

  2. 如何Spring Cloud Zuul作为网关的分布式系统中整合Swagger文档在同一个页面上

    本文不涉及技术,只是单纯的一个小技巧. 阅读本文前,你需要对spring-cloud-zuul.spring-cloud-eureka.以及swagger的配置和使用有所了解. 如果你的系统也是用zu ...

  3. springcloud+gateway微服务整合swagger

    单一的微服务集成swagger: maven: <dependency> <groupId>io.springfox</groupId> <artifactI ...

  4. springboot+cloud 学习(四)Zuul整合Swagger2

    前言 在微服务架构下,服务是分散的,怎么把所有服务接口整合到一起是我们需要关注的. 下面举例用zuul作为分布式系统的网关,同时使用swagger生成文档,想把整个系统的文档整合在同一个页面上来说明. ...

  5. springboot整合swagger。完爆前后端调试

    web接口开发时在调试阶段最麻烦的就是参数调试,前端需要咨询后端.后端有时候自己也不是很了解.这时候就会造成调试一次接口就需要看一次代码.Swagger帮我们解决对接的麻烦 springboot接入s ...

  6. springmvc整合swagger

    前言 Swagger 是一个规范和完整的框架,用于生成.描述.调用和可视化 RESTful 风格的 Web 服务.总体目标是使客户端和文件系统作为服务器以同样的速度来更新.文件的方法,参数和模型紧密集 ...

  7. Spring Boot初识(3)- Spring Boot整合Swagger

    一.本文介绍 如果Web项目是完全前后端分离的话(我认为现在完全前后端分离已经是趋势了)一般前端和后端交互都是通过接口的,对接口入参和出参描述的文档就是Mock文档.随着接口数量的增多和参数的个数增加 ...

  8. Spring MVC 整合Swagger的一些问题总结

    在做Spring MVC 整合swagger的时候,遇到的两个问题: 第一个问题 在网上找了一些Spring MVC 和Swagger的例子,照着一步步的配置,结果,到最后,项目都起来了,没有任何问题 ...

  9. Spring Boot:整合Swagger文档

    综合概述 spring-boot作为当前最为流行的Java web开发脚手架,越来越多的开发者选择用其来构建企业级的RESTFul API接口.这些接口不但会服务于传统的web端(b/s),也会服务于 ...

随机推荐

  1. redis之线程IO模型

    非阻塞 IO 当我们调用套接字的读写方法,默认它们是阻塞的,比如 read 方法要传递进去一个参数n,表示读取这么多字节后再返回,如果没有读够线程就会卡在那里,直到新的数据到来或者连接关闭了,read ...

  2. poj-2935 BFS Basic Wall Maze

    Basic Wall Maze Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 3384   Accepted: 1525   ...

  3. java架构之路-(JVM优化与原理)JVM的运行时内存模型

    还是我们上次的图,我们上次大概讲解了类加载子系统的执行过程,验证,准备,解析,初始化四个过程.还有我们的双亲委派机制. 我们这次来说一下运行时内存模型.上一段小代码. public class Mai ...

  4. OfType<string>()

    object[] vals = { 1, "Hello", true, "World", 9.1 }; IEnumerable<double> ju ...

  5. 转 Fortofy扫描漏洞解决方案2

    Fortify漏洞之Portability Flaw: File Separator 和 Poor Error Handling: Return Inside Finally   继续对Fortify ...

  6. Fundebug 微信小游戏异常监控插件更新至 0.5.0,支持监控 HTTP 慢请求

    摘要: 支持监控 HTTP 慢请求,同时修复了记录的 HTTP 响应时间偏小的 BUG. Fundebug是专业微信小游戏 BUG 监控服务,可以第一时间捕获线上环境中小游戏的异常.错误或者 BUG, ...

  7. 利用javascript动态加载头部出现点击事件与hover事件无效解决方法

    这里是利用es6的promise函数来异步加载,当HTML动态加载过去的HTML片段加载完毕再执行绑定事件的js代码: 具体过程如下 这里是用了jQuery框架的例子 $(function(){ // ...

  8. SUSE12-SP2安装教程(虚拟机)

    创建虚拟机,安装系统,安装系统后的系统设置 创建虚拟机 将SUSE12-SP2镜像(大于3G)上传到虚拟机主机存储. 创建虚拟机创建虚拟机,CPU>=8核,内存>=16G(注:我这里仅演示 ...

  9. iTerm2 + Oh My Zsh 打造舒适终端体验[mac os系统]

    当使用Mac OS系统登陆服务器时,发现tab键不能提示系统默认的命令,于是参照各种网络文章,网友提供一种软件oh my zsh [网址:https://ohmyz.sh/] 其实最重要一个命令足矣 ...

  10. 队列(Quene)

    对multiprocessing中的Quene进行演示 import multiprocessing """ 队列Quene是mutiprocessing 中 的一个类 ...