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

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

        <dependency>
<groupid>io.springfox</groupid>
<artifactid>springfox-swagger2</artifactid>
</dependency>
<dependency>
<groupid>com.github.xiaoymin</groupid>
<artifactid>knife4j-spring-ui</artifactid>
</dependency>

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

server:
port: 80
spring:
application:
name: gitegg-service-gateway
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
config:
server-addr: 127.0.0.1:8848
file-extension: yaml
group: DEFAULT_GROUP
enabled: true
gateway:
discovery:
locator:
enabled: true
routes:
- id: gitegg-service-system
uri: lb://gitegg-service-system
predicates:
- Path=/gitegg-system/**
filters:
- SwaggerHeaderFilter
- StripPrefix=1
- id: gitegg-service-base
uri: lb://gitegg-service-base
predicates:
- Path=/gitegg-base/**
filters:
- SwaggerHeaderFilter
- StripPrefix=1
文档聚合业务编码

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

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

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

package com.gitegg.gateway.config;

import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.config.GatewayProperties;
import org.springframework.cloud.gateway.route.RouteLocator;
import org.springframework.cloud.gateway.support.NameUtils;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Component;
import springfox.documentation.swagger.web.SwaggerResource;
import springfox.documentation.swagger.web.SwaggerResourcesProvider; import java.util.ArrayList;
import java.util.List; @Slf4j
@Component
@Primary
@AllArgsConstructor
public class SwaggerResourceConfig implements SwaggerResourcesProvider { private final RouteLocator routeLocator;
private final GatewayProperties gatewayProperties; @Override
public List<swaggerresource> get() {
List<swaggerresource> resources = new ArrayList<>();
List<string> routes = new ArrayList<>();
routeLocator.getRoutes().subscribe(route -> routes.add(route.getId()));
gatewayProperties.getRoutes().stream().filter(routeDefinition -> routes.contains(routeDefinition.getId())).forEach(route -> {
route.getPredicates().stream()
.filter(predicateDefinition -> ("Path").equalsIgnoreCase(predicateDefinition.getName()))
.forEach(predicateDefinition -> resources.add(swaggerResource(route.getId(),
predicateDefinition.getArgs().get(NameUtils.GENERATED_NAME_PREFIX + "0")
.replace("**", "v2/api-docs?group=1.X版本"))));
}); return resources;
} private SwaggerResource swaggerResource(String name, String location) {
log.info("name:{},location:{}",name,location);
SwaggerResource swaggerResource = new SwaggerResource();
swaggerResource.setName(name);
swaggerResource.setLocation(location);
swaggerResource.setSwaggerVersion("1.0.0");
return swaggerResource;
}
}
package com.gitegg.gateway.filter;

import org.apache.commons.lang.StringUtils;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange; @Component
public class SwaggerHeaderFilter extends AbstractGatewayFilterFactory {
private static final String HEADER_NAME = "X-Forwarded-Prefix"; private static final String URI = "/v2/api-docs"; @Override
public GatewayFilter apply(Object config) {
return (exchange, chain) -> {
ServerHttpRequest request = exchange.getRequest();
String path = request.getURI().getPath();
if (!StringUtils.endsWithIgnoreCase(path,URI )) {
return chain.filter(exchange);
}
String basePath = path.substring(0, path.lastIndexOf(URI));
ServerHttpRequest newRequest = request.mutate().header(HEADER_NAME, basePath).build();
ServerWebExchange newExchange = exchange.mutate().request(newRequest).build();
return chain.filter(newExchange);
};
}
}
package com.gitegg.gateway.handler;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Mono;
import springfox.documentation.swagger.web.*; import java.util.Optional; @RestController
public class SwaggerHandler { @Autowired(required = false)
private SecurityConfiguration securityConfiguration; @Autowired(required = false)
private UiConfiguration uiConfiguration; private final SwaggerResourcesProvider swaggerResources; @Autowired
public SwaggerHandler(SwaggerResourcesProvider swaggerResources) {
this.swaggerResources = swaggerResources;
} @GetMapping("/swagger-resources/configuration/security")
public Mono<responseentity<securityconfiguration>> securityConfiguration() {
return Mono.just(new ResponseEntity<>(
Optional.ofNullable(securityConfiguration).orElse(SecurityConfigurationBuilder.builder().build()), HttpStatus.OK));
} @GetMapping("/swagger-resources/configuration/ui")
public Mono<responseentity<uiconfiguration>> uiConfiguration() {
return Mono.just(new ResponseEntity<>(
Optional.ofNullable(uiConfiguration).orElse(UiConfigurationBuilder.builder().build()), HttpStatus.OK));
} @GetMapping("/swagger-resources")
public Mono<responseentity> swaggerResources() {
return Mono.just((new ResponseEntity<>(swaggerResources.get(), HttpStatus.OK)));
}
}

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. 数据结构与算法——弗洛伊德(Floyd)算法

    介绍 和 Dijkstra 算法一样,弗洛伊德(Floyd)算法 也是一种用于寻找给定的加权图中顶点间最短路径的算法.该算法名称以创始人之一.1978 年图灵奖获得者.斯坦福大学计算机科学系教授罗伯特 ...

  2. 关于突破 SESSION 0 隔离场景发现的一些问题

    0x00 Tricks 0x01 用ZwCreateThreadEx 在 Windows 10 下直接通过管理员权限+SeDebugPrivilege启用. 0x02 用CreateRemoteThr ...

  3. ls命令剖析

    目录 ls命令剖析 资料翻译 SYNOPSIS 使用方式 DESCRIPTION 说明 参数的说明 -l 参数字符的解释 文件权限的解释 FILES 文件夹 实战演练 ls 命令 ls -l 命令 l ...

  4. 苹果应用内购 ios 开发者根据用户提供的邮件中的订单号查看该订单是否支付成功

    苹果应用内购 ios 开发者根据用户提供的邮件中的订单号查看该订单是否支付成功 这是苹果wwdc2021 推出的新功能 参考官网链接 App Store Server API | Apple Deve ...

  5. 改善深层神经网络-week2编程题(Optimization Methods)

    1. Optimization Methods Gradient descent goes "downhill" on a cost function \(J\). Think o ...

  6. [对对子队]会议记录5.18(Scrum Meeting5)

    今天已完成的工作 何瑞 ​ 工作内容:搭建第8关 ​ 相关issue:搭建关卡7.8.9 ​ 相关签入:feat:初步搭建了Lv8 吴昭邦 ​ 工作内容:搭建第8关 ​ 相关issue:搭建关卡7.8 ...

  7. 最长子序列(线性DP)学习笔记

    子序列和子串不一样.子串要求必须连续,而子序列不需要连续. 比如说\(\{a_1,a_2\dots a_n\}\),他的子串就是\(\{a_i,a_{i+1},\dots, a_j|1\leq i\l ...

  8. 如何清理history

    工作中,需要清理history 清理当前会话历史命令    history -c 清理当前用户所有历史命令     echo > .bash_history     #在用户主目录执行此操作

  9. Python课程笔记(九)

    本次课程主要学习了Excel和JSON格式的一些读写操作.课程代码 一.Excel数据读写操作 1.安装模块 pip install xlrd pip install xlwt 网不好可以采用三方库: ...

  10. 你知道怎么从jar包里获取一个文件的内容吗

    目录 背景 报错的代码 原先的写法 编写测试类 找原因 最终代码 背景 项目里需要获取一个excle文件,然后对其里的内容进行修改,这个文件在jar包里,怎么尝试都读取不成功,但是觉得肯定可以做到,因 ...