本章介绍Spring Cloud Gateway网关如何集成knife4j,通过网关聚合所有的Swagger微服务文档

1、gitegg-gateway中引入knife4j依赖,如果没有后端代码编写的话,仅仅引入一个swagger的前端ui模块就可以了

  1. <dependency>
  2. <groupid>io.springfox</groupid>
  3. <artifactid>springfox-swagger2</artifactid>
  4. </dependency>
  5. <dependency>
  6. <groupid>com.github.xiaoymin</groupid>
  7. <artifactid>knife4j-spring-ui</artifactid>
  8. </dependency>

2、修改配置文件,增加knife4j、Swagger2的配置

  1. server:
  2. port: 80
  3. spring:
  4. application:
  5. name: gitegg-service-gateway
  6. cloud:
  7. nacos:
  8. discovery:
  9. server-addr: 127.0.0.1:8848
  10. config:
  11. server-addr: 127.0.0.1:8848
  12. file-extension: yaml
  13. group: DEFAULT_GROUP
  14. enabled: true
  15. gateway:
  16. discovery:
  17. locator:
  18. enabled: true
  19. routes:
  20. - id: gitegg-service-system
  21. uri: lb://gitegg-service-system
  22. predicates:
  23. - Path=/gitegg-system/**
  24. filters:
  25. - SwaggerHeaderFilter
  26. - StripPrefix=1
  27. - id: gitegg-service-base
  28. uri: lb://gitegg-service-base
  29. predicates:
  30. - Path=/gitegg-base/**
  31. filters:
  32. - SwaggerHeaderFilter
  33. - StripPrefix=1
文档聚合业务编码

在我们使用Spring Boot等单体架构集成swagger项目时,是通过对包路径进行业务分组,然后在前端进行不同模块的展示,而在微服务架构下,我们的一个服务就类似于原来我们写的一个业务组

springfox-swagger提供的分组接口是swagger-resource,返回的是分组接口名称、地址等信息

在Spring Cloud微服务架构下,我们需要重写该接口,主要是通过网关的注册中心动态发现所有的微服务文档,代码如下:

  1. package com.gitegg.gateway.config;
  2. import lombok.AllArgsConstructor;
  3. import lombok.extern.slf4j.Slf4j;
  4. import org.springframework.cloud.gateway.config.GatewayProperties;
  5. import org.springframework.cloud.gateway.route.RouteLocator;
  6. import org.springframework.cloud.gateway.support.NameUtils;
  7. import org.springframework.context.annotation.Primary;
  8. import org.springframework.stereotype.Component;
  9. import springfox.documentation.swagger.web.SwaggerResource;
  10. import springfox.documentation.swagger.web.SwaggerResourcesProvider;
  11. import java.util.ArrayList;
  12. import java.util.List;
  13. @Slf4j
  14. @Component
  15. @Primary
  16. @AllArgsConstructor
  17. public class SwaggerResourceConfig implements SwaggerResourcesProvider {
  18. private final RouteLocator routeLocator;
  19. private final GatewayProperties gatewayProperties;
  20. @Override
  21. public List<swaggerresource> get() {
  22. List<swaggerresource> resources = new ArrayList<>();
  23. List<string> routes = new ArrayList<>();
  24. routeLocator.getRoutes().subscribe(route -> routes.add(route.getId()));
  25. gatewayProperties.getRoutes().stream().filter(routeDefinition -> routes.contains(routeDefinition.getId())).forEach(route -> {
  26. route.getPredicates().stream()
  27. .filter(predicateDefinition -> ("Path").equalsIgnoreCase(predicateDefinition.getName()))
  28. .forEach(predicateDefinition -> resources.add(swaggerResource(route.getId(),
  29. predicateDefinition.getArgs().get(NameUtils.GENERATED_NAME_PREFIX + "0")
  30. .replace("**", "v2/api-docs?group=1.X版本"))));
  31. });
  32. return resources;
  33. }
  34. private SwaggerResource swaggerResource(String name, String location) {
  35. log.info("name:{},location:{}",name,location);
  36. SwaggerResource swaggerResource = new SwaggerResource();
  37. swaggerResource.setName(name);
  38. swaggerResource.setLocation(location);
  39. swaggerResource.setSwaggerVersion("1.0.0");
  40. return swaggerResource;
  41. }
  42. }
  1. package com.gitegg.gateway.filter;
  2. import org.apache.commons.lang.StringUtils;
  3. import org.springframework.cloud.gateway.filter.GatewayFilter;
  4. import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
  5. import org.springframework.http.server.reactive.ServerHttpRequest;
  6. import org.springframework.stereotype.Component;
  7. import org.springframework.web.server.ServerWebExchange;
  8. @Component
  9. public class SwaggerHeaderFilter extends AbstractGatewayFilterFactory {
  10. private static final String HEADER_NAME = "X-Forwarded-Prefix";
  11. private static final String URI = "/v2/api-docs";
  12. @Override
  13. public GatewayFilter apply(Object config) {
  14. return (exchange, chain) -> {
  15. ServerHttpRequest request = exchange.getRequest();
  16. String path = request.getURI().getPath();
  17. if (!StringUtils.endsWithIgnoreCase(path,URI )) {
  18. return chain.filter(exchange);
  19. }
  20. String basePath = path.substring(0, path.lastIndexOf(URI));
  21. ServerHttpRequest newRequest = request.mutate().header(HEADER_NAME, basePath).build();
  22. ServerWebExchange newExchange = exchange.mutate().request(newRequest).build();
  23. return chain.filter(newExchange);
  24. };
  25. }
  26. }
  1. package com.gitegg.gateway.handler;
  2. import org.springframework.beans.factory.annotation.Autowired;
  3. import org.springframework.http.HttpStatus;
  4. import org.springframework.http.ResponseEntity;
  5. import org.springframework.web.bind.annotation.GetMapping;
  6. import org.springframework.web.bind.annotation.RestController;
  7. import reactor.core.publisher.Mono;
  8. import springfox.documentation.swagger.web.*;
  9. import java.util.Optional;
  10. @RestController
  11. public class SwaggerHandler {
  12. @Autowired(required = false)
  13. private SecurityConfiguration securityConfiguration;
  14. @Autowired(required = false)
  15. private UiConfiguration uiConfiguration;
  16. private final SwaggerResourcesProvider swaggerResources;
  17. @Autowired
  18. public SwaggerHandler(SwaggerResourcesProvider swaggerResources) {
  19. this.swaggerResources = swaggerResources;
  20. }
  21. @GetMapping("/swagger-resources/configuration/security")
  22. public Mono<responseentity<securityconfiguration>> securityConfiguration() {
  23. return Mono.just(new ResponseEntity<>(
  24. Optional.ofNullable(securityConfiguration).orElse(SecurityConfigurationBuilder.builder().build()), HttpStatus.OK));
  25. }
  26. @GetMapping("/swagger-resources/configuration/ui")
  27. public Mono<responseentity<uiconfiguration>> uiConfiguration() {
  28. return Mono.just(new ResponseEntity<>(
  29. Optional.ofNullable(uiConfiguration).orElse(UiConfigurationBuilder.builder().build()), HttpStatus.OK));
  30. }
  31. @GetMapping("/swagger-resources")
  32. public Mono<responseentity> swaggerResources() {
  33. return Mono.just((new ResponseEntity<>(swaggerResources.get(), HttpStatus.OK)));
  34. }
  35. }

3、访问gitegg-gateway服务地址http://127.0.0.1/doc.html,可以看到聚合后的文档

本文源码在https://gitee.com/wmz1930/GitEgg 的chapter-19分支。

SpringCloud微服务实战——搭建企业级开发框架(十九):Gateway使用knife4j聚合微服务文档的更多相关文章

  1. SpringCloud微服务实战——搭建企业级开发框架(九):使用Nacos发现、配置和管理微服务

    Nacos是一个更易于构建云原生应用的动态服务发现.配置管理和服务管理平台,Nacos 致力于帮助您发现.配置和管理微服务.Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现.服务配置 ...

  2. SpringCloud微服务实战——搭建企业级开发框架(四十二):集成分布式任务调度平台XXL-JOB,实现定时任务功能

      定时任务几乎是每个业务系统必不可少的功能,计算到期时间.过期时间等,定时触发某项任务操作.在使用单体应用时,基本使用Spring提供的注解即可实现定时任务,而在使用微服务集群时,这种方式就要考虑添 ...

  3. SpringCloud微服务实战——搭建企业级开发框架(三十四):SpringCloud + Docker + k8s实现微服务集群打包部署-Maven打包配置

      SpringCloud微服务包含多个SpringBoot可运行的应用程序,在单应用程序下,版本发布时的打包部署还相对简单,当有多个应用程序的微服务发布部署时,原先的单应用程序部署方式就会显得复杂且 ...

  4. SpringCloud微服务实战——搭建企业级开发框架(四十四):【微服务监控告警实现方式一】使用Actuator + Spring Boot Admin实现简单的微服务监控告警系统

      业务系统正常运行的稳定性十分重要,作为SpringBoot的四大核心之一,Actuator让你时刻探知SpringBoot服务运行状态信息,是保障系统正常运行必不可少的组件.   spring-b ...

  5. SpringCloud微服务实战——搭建企业级开发框架(三十六):使用Spring Cloud Stream实现可灵活配置消息中间件的功能

      在以往消息队列的使用中,我们通常使用集成消息中间件开源包来实现对应功能,而消息中间件的实现又有多种,比如目前比较主流的ActiveMQ.RocketMQ.RabbitMQ.Kafka,Stream ...

  6. SpringCloud微服务实战——搭建企业级开发框架(三十五):SpringCloud + Docker + k8s实现微服务集群打包部署-集群环境部署

    一.集群环境规划配置 生产环境不要使用一主多从,要使用多主多从.这里使用三台主机进行测试一台Master(172.16.20.111),两台Node(172.16.20.112和172.16.20.1 ...

  7. SpringCloud微服务实战——搭建企业级开发框架(三十八):搭建ELK日志采集与分析系统

      一套好的日志分析系统可以详细记录系统的运行情况,方便我们定位分析系统性能瓶颈.查找定位系统问题.上一篇说明了日志的多种业务场景以及日志记录的实现方式,那么日志记录下来,相关人员就需要对日志数据进行 ...

  8. SpringCloud微服务实战——搭建企业级开发框架(四十):使用Spring Security OAuth2实现单点登录(SSO)系统

    一.单点登录SSO介绍   目前每家企业或者平台都存在不止一套系统,由于历史原因每套系统采购于不同厂商,所以系统间都是相互独立的,都有自己的用户鉴权认证体系,当用户进行登录系统时,不得不记住每套系统的 ...

  9. SpringCloud微服务实战——搭建企业级开发框架(四十五):【微服务监控告警实现方式二】使用Actuator(Micrometer)+Prometheus+Grafana实现完整的微服务监控

      无论是使用SpringBootAdmin还是使用Prometheus+Grafana都离不开SpringBoot提供的核心组件Actuator.提到Actuator,又不得不提Micrometer ...

  10. SpringCloud微服务实战——搭建企业级开发框架(二):环境准备

    这里简单说明一下在Windows系统下开发SpringCloud项目所需要的的基本环境,这里只说明开发过程中基础必须的软件,其他扩展功能(Docker,k8s,MinIO,XXL-JOB,EKL,Ke ...

随机推荐

  1. 统计学习:线性支持向量机(SVM)

    学习策略 软间隔最大化 上一章我们所定义的"线性可分支持向量机"要求训练数据是线性可分的.然而在实际中,训练数据往往包括异常值(outlier),故而常是线性不可分的.这就要求我们 ...

  2. 题解 Weak in the Middle

    题目传送门 Description 有一个长度为 \(n\) 的序列 \(a_{1,2,...,n}\) ,每次可以删掉 \(a_i\),当 \(\min(a_{i-1},a_{i+1})>a_ ...

  3. hdu3001(三进制状压)

    题目大意: 现在给你一个有n个点和m条边的图,每一条边都有一个费用,每个点不能经过超过两次,求所有点至少遍历一次的最小费用 其中n<=10 m没有明确限制(肯定不会超过1e5) 一看到这个数据范 ...

  4. NX屏蔽窗口的按钮

    有时候在激活一个命令按钮的时候,需要同时禁止掉另外一个或多个命令按钮 ''' <summary> ''' 取按钮是否敏感 ''' </summary> ''' <para ...

  5. NX CAM 区域轮廓铣的切削步长

    从NX3.0到NX9.0,默认都是5%.可是实际计算的精确度是不一样的.到NX8.0上发现计算速度特别慢,后来东找西找,设置这个参数可以解决.PS:请慎用!请后后面的官方解释. 官方的解释是: &qu ...

  6. AgileConfig 轻量级配置中心 1.5 发布 - 支持多环境配置

    AgileConfig 从发布到现在,收到不同学的 issue 说需要多环境的支持.也就是一个应用在不同的环境下可以配置不同的配置项.这是一个非常有用的功能,就跟我们开发的时候会设置多个 appset ...

  7. Java字符串转数字和数字转字符串

    int转String有3种方式 (1)num + "" (2)String.valueOf(num) (3)Integer.toString(num) String转int有2种方 ...

  8. 基于Apache Zookeeper手写实现动态配置中心(纯代码实践)

    相信大家都知道,每个项目中会有一些配置信息放在一个独立的properties文件中,比如application.properties.这个文件中会放一些常量的配置,比如数据库连接信息.线程池大小.限流 ...

  9. 4个实验,彻底搞懂TCP连接的断开

    前言 看到这个标题你可能会说,TCP 连接的建立与断开,这个我熟,不就是三次握手与四次挥手嘛.且慢,脑海中可以先尝试回答这几个问题: 四次挥手是谁发起的? 如果断电/断网了连接会断开吗? 什么情况下没 ...

  10. mybatis中的#和$的区别 以及 防止sql注入

    声明:这是转载的. mybatis中的#和$的区别 1. #将传入的数据都当成一个字符串,会对自动传入的数据加一个双引号.如:order by #user_id#,如果传入的值是111,那么解析成sq ...