Zuul整合Swagger,使用ZuulFilter解决下游服务context-path
问题起因:使用Zuul网关服务,需要整合下游系统的swagger,但是下游服务存在context-path配置,无法正确跳转,最后使用ZuulFilter解决。
1.Zuul整合下游swagger
首先介绍一下Zuul如何整合下游服务swagger,很好理解,就是通过Zuul的swagger地址,实现将下游服务的swagger都放入同一个页面内,流转图如下:

1.1 下游服务整合swagger
这里进行简单介绍服务整合swagger的步骤其实就是分为两步:
- 配置swagger
- 对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的更多相关文章
- Spring Cloud Zuul 网关的分布式系统中整合Swagger(转)和 zuul跨域访问问题
首先恭喜自己终于找对了努力的方向,很荣幸能在公司接触到微服务架构,也很高兴公司一个大佬哥们愿意带我,他技术确实很牛逼,我也很佩服他,前后端通吃,干了六年能有这样的水平.最近跟着在搞微服务架构,给我分配 ...
- 如何Spring Cloud Zuul作为网关的分布式系统中整合Swagger文档在同一个页面上
本文不涉及技术,只是单纯的一个小技巧. 阅读本文前,你需要对spring-cloud-zuul.spring-cloud-eureka.以及swagger的配置和使用有所了解. 如果你的系统也是用zu ...
- springcloud+gateway微服务整合swagger
单一的微服务集成swagger: maven: <dependency> <groupId>io.springfox</groupId> <artifactI ...
- springboot+cloud 学习(四)Zuul整合Swagger2
前言 在微服务架构下,服务是分散的,怎么把所有服务接口整合到一起是我们需要关注的. 下面举例用zuul作为分布式系统的网关,同时使用swagger生成文档,想把整个系统的文档整合在同一个页面上来说明. ...
- springboot整合swagger。完爆前后端调试
web接口开发时在调试阶段最麻烦的就是参数调试,前端需要咨询后端.后端有时候自己也不是很了解.这时候就会造成调试一次接口就需要看一次代码.Swagger帮我们解决对接的麻烦 springboot接入s ...
- springmvc整合swagger
前言 Swagger 是一个规范和完整的框架,用于生成.描述.调用和可视化 RESTful 风格的 Web 服务.总体目标是使客户端和文件系统作为服务器以同样的速度来更新.文件的方法,参数和模型紧密集 ...
- Spring Boot初识(3)- Spring Boot整合Swagger
一.本文介绍 如果Web项目是完全前后端分离的话(我认为现在完全前后端分离已经是趋势了)一般前端和后端交互都是通过接口的,对接口入参和出参描述的文档就是Mock文档.随着接口数量的增多和参数的个数增加 ...
- Spring MVC 整合Swagger的一些问题总结
在做Spring MVC 整合swagger的时候,遇到的两个问题: 第一个问题 在网上找了一些Spring MVC 和Swagger的例子,照着一步步的配置,结果,到最后,项目都起来了,没有任何问题 ...
- Spring Boot:整合Swagger文档
综合概述 spring-boot作为当前最为流行的Java web开发脚手架,越来越多的开发者选择用其来构建企业级的RESTFul API接口.这些接口不但会服务于传统的web端(b/s),也会服务于 ...
随机推荐
- WinForm 窗体间传递数据
前言 做项目的时候,winfrom因为没有B/S的缓存机制,窗体间传递数据没有B/S页面传递数据那么方便,今天我们就说下winfrom中窗体传值的几种方式. 共有字段传递 共有字段传递实现起来很方便, ...
- Kafka学习笔记之Kafka High Availability(下)
0x00 摘要 本文在上篇文章基础上,更加深入讲解了Kafka的HA机制,主要阐述了HA相关各种场景,如Broker failover,Controller failover,Topic创建/删除,B ...
- Git在提交代码时出现的fatal: Authentication failed的问题
git push origin master remote: Incorrect username or password ( access token ) fatal: Authentication ...
- .net core 发布到iis问题 HTTP Error 500.30 - ANCM In-Process Start Failure
1. 没有在Program里配置IIS webBuilder.UseIIS(); 2. StartupProduction 里AutoFac容器注入错误和新版的CORS中间件已经阻止使用允许任意Ori ...
- minggw 安装
windows上如果没有安装 visual studio, 也就是俗称的vs, 在安装一些带有c或者c++代码的Python模块的时候, 会报错Unable to find vcvarsall.bat ...
- ICSharpCode.SharpZipLib 中文乱码问题
今天在调用ICSharpCode.SharpZipLib解压zip文件时出现了中文文件乱码的问题. 解决过程如下: 1.判断是否压缩包本身问题.经查zip文件夹在本地直接解压打开时正确的中文名称,所以 ...
- ASP.NET Core系列:依赖注入
1. 控制反转(IoC) 控制反转(Inversion of Control,IoC),是面向对象编程中的一种设计原则,用来降低代码之间的耦合度. 1.1 依赖倒置 依赖原则: (1)高层次的模块不应 ...
- CTF必备技能丨Linux Pwn入门教程——ROP技术(下)
Linux Pwn入门教程系列分享如约而至,本套课程是作者依据i春秋Pwn入门课程中的技术分类,并结合近几年赛事中出现的题目和文章整理出一份相对完整的Linux Pwn教程. 教程仅针对i386/am ...
- MyCat教程六:全局序列号-全局主键的自增长
前面我们介绍了MyCat的分库分表操作,那么同一张表中的数据会被保存在不同的数据库中,那么这就涉及到了主键维护的问题,此时肯定不能使用单个数据库中id自增的方式来处理了,这时我们就可以通过MyCa ...
- c# 根据一个给定经纬度的点和距离,搜索附近5公里范围的地点
功能需求:需要查询一个站点(已知该站点经纬度)5公里范围内的其它站点. 方 法 一 :对每条记录,去进行遍历,跟数据库中的每一个点进行距离计算,当距离小于5公里时,认为匹配(效率极其低下,耗时长). ...