本章介绍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. 关于docker复现vulhub环境的搭建

    原本想用docker复现一下vul的漏洞. 装docker过程中遇到了很多问题, 昨天熬夜到凌晨三点都没弄完. 中午又找了找原因,终于全部解决了, 小结一下. 0x01 镜像 去官方下载了centos ...

  2. Ubuntu18.04安装MySQL教程

    Ubuntu18.04下安装MySQL 提示:以下操作均在root权限下进行. # 查看有没有安装MySQL: dpkg -l | grep mysql # 安装MySQL: apt install ...

  3. java 从零开始手写 RPC (07)-timeout 超时处理

    <过时不候> 最漫长的莫过于等待 我们不可能永远等一个人 就像请求 永远等待响应 超时处理 java 从零开始手写 RPC (01) 基于 socket 实现 java 从零开始手写 RP ...

  4. 题解 [CTSC2006]歌唱王国

    题目传送门 Desctiption 见题面. Solution 人类智慧... 考虑这样一个赌博游戏,现在有一个猴子,它随机从 \(1\sim n\) 中选一个打出来.现在有若干个赌徒,他们一开始都有 ...

  5. uoj167 元旦老人与汉诺塔(记忆化搜索)

    QwQ太懒了,题目直接复制uoj的了 QwQ这个题可以说是十分玄学的一道题了 首先可以暴搜,就是\(dfs\)然后模拟每个过程是哪个柱子向哪个柱子移动 不多解释了,不过实现起来还是有一点点难度的 直接 ...

  6. k8s学习笔记(1)- 简单部署springboot应用

    前言:k8s全称kubernetes,k8s是为容器服务而生的一个可移植容器的编排管理工具,越来越多的公司正在拥抱k8s,并且当前k8s已经主导了云业务流程,关于更多的k8s知识,可自行学习 1.k8 ...

  7. 浅尝装饰器-@staticmethod 和@classmethod

    [写在前面] 本帖归属于装饰器单元的学习,可以点击关键词'装饰器'查看其他博文讲解 [正文部分] 说到装饰器一开始我觉得很陌生,看了一下别人的博客讲解,原来以前学习遇到的静态方法@staticmeth ...

  8. 【UE4 C++】UKismetSystemLibrary 源代码

    // Copyright Epic Games, Inc. All Rights Reserved. #pragma once #include "CoreMinimal.h" # ...

  9. 【二食堂】Alpha - Scrum Meeting 10

    Scrum Meeting 10 例会时间:4.20 18:00~18:20 进度情况 组员 昨日进度 今日任务 李健 1. 与柴博合作完成登录注册页面issue 继续完成登录注册页面issue 柴博 ...

  10. OKR与影响地图,别再傻傻分不清

    摘要:OKR和影响地图虽然都是为了一个目标去进行规划的方法,但是两者侧重的内容却不一致. 本文分享自华为云社区<一分钟读懂OKR与影响地图>,作者: 敏捷的小智. 什么是OKR及影响地图 ...