问题起因:使用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. hdu-5573 Binary Tree

    The Old Frog King lives on the root of an infinite tree. According to the law, each node should conn ...

  2. sql语句将一个表的数据拷贝到另一个表中

    假定有一个a表,一个b表,要将a表的数据拷贝到b表中. 1.如果a表和b表结构相同. insert into b select * from a; 2.如果a表和b表的结构不相同. insert in ...

  3. vsdbg 下载方法 使用下载工具下载后手动安装

    vsdbg国内下载太慢了,这里提供一个使用下载工具下载后,手动安装的处理方法 查看vs build控制台输出: 1>C:\WINDOWS\System32\WindowsPowerShell\v ...

  4. SAP PI接口(RFC类型)在函数字段修改或增加后,出现字段映射错误问题

    在解决标题所言问题之前,我们先回头看看RFC和sproxy这两种接口的优缺点. 关于PI接口的实现,目前我了解到的各大国企项目像中海油.中石化.国网等,普遍实现方式是RFC和代理类sproxy这两种. ...

  5. 基于直接缓冲区和非直接缓冲区的javaIO文件操作

    基本概念: 1. 非直接缓冲区:  指的是通过jvm来缓存数据的,应用程序要读取本地数据要经历从本地磁盘到物理内存,然后copy到jvm中,然后再通过流的方式读取到应用程序中,写的操作正好与之相反. ...

  6. Java获取客户端真实IP地址

    Java代码 import javax.servlet.http.HttpServletRequest; /** * 获取对象的IP地址等信息 */ public class IPUtil { /** ...

  7. Django基本知识

    一.安装及使用 下载安装 命令行:pip3 install django==1.11.21 pycharm 创建项目 命令行: 找一个文件夹存放项目文件,打开终端: django-admin star ...

  8. 利用Python调用pastebin.com API自动创建paste

    在上一篇文章中,已经实现了模拟pastebin.com的账号登录,并且获取了api_dev_key,这一篇文章主要讲一下调用API创建paste 登录之后,进入API页面,发现网站已经提供了几个API ...

  9. 21个React开发神器

    摘要: React开发神器. 原文:22 Miraculous Tools for React Developers in 2019 译者:前端小智 下列工具中的重要性与排序无关. 1.Webpack ...

  10. 动态样式语言less初识

    资料参考与http://lesscss.cn/ Bootstrap--(less)下载安装配置 http://lesscss.cn Less使用两种方法 (1)在客户端使用LESS--学习 编写 x. ...