Zuul中聚合Swagger的坑

每一个服务都有本身的接口,经过Swagger来管理接口文档。在服务较多的时候咱们但愿有一个统一的入口来进行文档的查看,这个时候能够在Zuul中进行文档的聚合显示。
下面来看下具体的整合步骤以及采坑记录。Cloud版本:Finchley.SR2, Boot版本:2.0.6
加入Swagger的依赖:

前端

1.  <!-- Swagger -->
2.  <dependency>
3.      <groupId>io.springfox</groupId>
4.      <artifactId>springfox-swagger-ui</artifactId>
5.      <version>2.9.2</version>
6.  </dependency>
7.  <dependency>
8.      <groupId>io.springfox</groupId>
9.      <artifactId>springfox-swagger2</artifactId>
10.     <version>2.9.2</version>
11. </dependency>

增长聚合代码:spring

1.  @EnableSwagger2
2.  @Component
3.  @Primary
4.  public class DocumentationConfig implements SwaggerResourcesProvider {
5.  
6.      @Autowired
7.      private DiscoveryClient discoveryClient;
8.  
9.      @Value("${spring.application.name}")
10.     private String applicationName;
11. 
12.     @Override
13.     public List<SwaggerResource> get() {
14.         List<SwaggerResource> resources = new ArrayList<>();
15.         // 排除自身,将其余的服务添加进去
16.         discoveryClient.getServices().stream().filter(s -> !s.equals(applicationName)).forEach(name -> {
17.             resources.add(swaggerResource(name, "/" + name + "/v2/api-docs", "2.0"));
18.         });
19.         return resources;
20.     }
21. 
22.     private SwaggerResource swaggerResource(String name, String location, String version) {
23.         SwaggerResource swaggerResource = new SwaggerResource();
24.         swaggerResource.setName(name);
25.         swaggerResource.setLocation(location);
26.         swaggerResource.setSwaggerVersion(version);
27.         return swaggerResource;
28.     }
29. 
30. }

我这边直接用DiscoveryClient 获取服务列表进行聚合,固然你也能够固定写上你的服务列表,或者对接配置中心均可以。
其实除了DiscoveryClient 获取服务列表,咱们也能够根据Zuul中路由的配置来获取,能够使用RouteLocator 来操做。方式不少,用哪一种均可以。
正常状况下上面的整合步骤没任何问题,今天有朋友在星球提问,说本身的业务服务加了context-path,Zuul中聚合的Swagger文档没法显示,由于路径错了,少了配置的context-path。效果以下图:
Zuul中聚合Swagger的坑
也就是说在进行资源添加的时候须要将context-path加进去,也就是须要改动下面的代码:



后端

1. resources.add(swaggerResource(name, "/" + name + "/v2/api-docs", "2.0"));api

最简单的就是加一个配置,配置好每一个服务对应的context-path,这样在这里直接拼接上去就完事了。但这样显得有点低端呀,哈哈。
DiscoveryClient 是很强大的,咱们能够用DiscoveryClient 来获取Eureka中的信息,此时我有了一个想法,那就是业务服务将自身的context-path放入Eureka的metadata-map中,而后Zuul中聚合的时候从metadata-map中获取context-path就好了。
业务服务加配置:

缓存

1.  server.servlet.context-path=/yinjihuan
2.  eureka.instance.metadata-map.context-path=${server.servlet.context-path}

Zuul中改造:并发

1.  @Override
2.  public List<SwaggerResource> get() {
3.      List<SwaggerResource> resources = new ArrayList<>();
4.      // 排除自身,将其余的服务添加进去
5.      discoveryClient.getServices().stream().filter(s -> !s.equals(applicationName)).forEach(name -> {
6.          Optional<ServiceInstance> instanceOptional = discoveryClient.getInstances(name).stream().findFirst();
7.          if (instanceOptional.isPresent() && instanceOptional.get().getMetadata().containsKey("context-path")) {
8.              String contexPath = instanceOptional.get().getMetadata().get("context-path");
9.              resources.add(swaggerResource(name, "/" + name + contexPath + "/v2/api-docs", "2.0"));
10.         } else {
11.             resources.add(swaggerResource(name, "/" + name + "/v2/api-docs", "2.0"));
12.         }
13. 
14.     });
15.     return resources;
16. }

这样就完美解决了增长context-path致使的问题,加入星球咱们一块儿学习吧。app

星球正在搞活动,详情请查看:优秀程序猿背后的故事框架

加入星球特权分布式

一、从前端到后端玩转Spring Cloud
二、实战分库分表中间件Sharding-JDBC
三、实战分布式任务调度框架Elastic Job
四、配置中心Apollo实战
五、高并发解决方案之缓存
六、更多课程等你来解锁,20+课程




ide

Zuul中聚合Swagger的坑尹吉欢我不差钱啊喜欢做者

相关文章
相关标签/搜索