微服务下网关聚合Swagger文档、starter统一配置Swagger
一、starter实现统一配置微服务文档
- 把Swagger配置中的公共部分抽取出来
- Swagger与SpringBoot整合中,可能会由于版本问题出现各种问题
1、制作starter
参考:
- 【SpringBoot】自定义启动器 Starter【保姆级教程】
- 用starter实现Oauth2中资源服务的统一配置
- 用starter实现api接口的加密与日志功能
- 用spring-boot-starter实现事务的统一配置
1> 总体结构图
2> 外部引用模块
tuwer-swagger-spring-boot-starter
- pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.tuwer</groupId><artifactId>tuwer-swagger-spring-boot-starter</artifactId><version>1.0-SNAPSHOT</version><description>swagger配置starter</description><properties><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target></properties><dependencies><!-- 自动配置模块 --><dependency><groupId>com.tuwer</groupId><artifactId>tuwer-swagger-spring-boot-starter-autoconfigure</artifactId><version>1.0-SNAPSHOT</version></dependency></dependencies>
</project>
3> 自动配置模块
- pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.6.7</version></parent><modelVersion>4.0.0</modelVersion><groupId>com.tuwer</groupId><artifactId>tuwer-swagger-spring-boot-starter-autoconfigure</artifactId><version>1.0-SNAPSHOT</version><description>swagger自动配置模块</description><properties><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target></properties><dependencies><!-- 基础启动器 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId></dependency><!-- web --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- Swagger --><dependency><groupId>io.springfox</groupId><artifactId>springfox-boot-starter</artifactId><version>3.0.0</version></dependency><!-- actuator完善监控信息 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId></dependency><!-- lombok --><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.22</version></dependency></dependencies>
</project>
- 自动配置类
不要加
@EnableWebMvc
package com.tuwer.config;import org.springframework.boot.actuate.autoconfigure.endpoint.web.CorsEndpointProperties;
import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointProperties;
import org.springframework.boot.actuate.autoconfigure.web.server.ManagementPortType;
import org.springframework.boot.actuate.endpoint.ExposableEndpoint;
import org.springframework.boot.actuate.endpoint.web.*;
import org.springframework.boot.actuate.endpoint.web.annotation.ControllerEndpointsSupplier;
import org.springframework.boot.actuate.endpoint.web.annotation.ServletEndpointsSupplier;
import org.springframework.boot.actuate.endpoint.web.servlet.WebMvcEndpointHandlerMapping;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.util.StringUtils;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;/*** @author 土味儿* Date 2023/4/21* @version 1.0* 这里不要加EnableWebMvc注解;否则响应数据会出现乱码*/
@Configuration
//@EnableWebMvc
@EnableConfigurationProperties(SwaggerProperty.class)
public class SwaggerConfig {@ResourceSwaggerProperty swaggerProperty;/*** 配置Swagger具体参数** @return*/@Beanpublic Docket docket(Environment environment) {// 允许启用Swagger的环境//Profiles profile = Profiles.of("dev","test");// 判断当前环境与指定环境是否一致//boolean b = environment.acceptsProfiles(profile);//return new Docket(DocumentationType.OAS_30)return new Docket(DocumentationType.SWAGGER_2)//.apiInfo(apiInfo("tuwer", "搜索服务", "v3.0")).apiInfo(apiInfo(swaggerProperty.getAuthor(), swaggerProperty.getTitle(), swaggerProperty.getVersion()))// 根据当前环境判断是否启用Swagger//.enable(b)//.enable(true)//.groupName("A")// 通过.select()方法,去配置扫描接口,RequestHandlerSelectors配置如何扫描接口.select()// 只扫描特定包下的接口.apis(RequestHandlerSelectors.basePackage(swaggerProperty.getBasePackage()))//.apis(RequestHandlerSelectors.any())//.apis(RequestHandlerSelectors.none())//.apis(RequestHandlerSelectors.withClassAnnotation(RestController.class))//.apis(RequestHandlerSelectors.withMethodAnnotation(GetMapping.class))//.paths(PathSelectors.).build();}/*** 自定义API文档信息** @return*/private ApiInfo apiInfo(String author, String title, String version) {// 作者信息Contact contact = new Contact(author, "", "");return new ApiInfo(title + " API 文档","",version,"",contact,"","",new ArrayList());}/*** 增加如下配置可解决Spring Boot 2.6.x 与 Swagger 3.0.0 不兼容问题* ------------------------------------------* 还需要在yml中作如下配置* mvc:* pathmatch:* matching-strategy: ant_path_matcher**/@Beanpublic WebMvcEndpointHandlerMapping webEndpointServletHandlerMapping(WebEndpointsSupplier webEndpointsSupplier,ServletEndpointsSupplier servletEndpointsSupplier,ControllerEndpointsSupplier controllerEndpointsSupplier,EndpointMediaTypes endpointMediaTypes,CorsEndpointProperties corsProperties,WebEndpointProperties webEndpointProperties,Environment environment) {List<ExposableEndpoint<?>> allEndpoints = new ArrayList();Collection<ExposableWebEndpoint> webEndpoints = webEndpointsSupplier.getEndpoints();allEndpoints.addAll(webEndpoints);allEndpoints.addAll(servletEndpointsSupplier.getEndpoints());allEndpoints.addAll(controllerEndpointsSupplier.getEndpoints());String basePath = webEndpointProperties.getBasePath();EndpointMapping endpointMapping = new EndpointMapping(basePath);boolean shouldRegisterLinksMapping = this.shouldRegisterLinksMapping(webEndpointProperties, environment, basePath);return new WebMvcEndpointHandlerMapping(endpointMapping, webEndpoints, endpointMediaTypes, corsProperties.toCorsConfiguration(), new EndpointLinksResolver(allEndpoints, basePath), shouldRegisterLinksMapping, null);}private boolean shouldRegisterLinksMapping(WebEndpointProperties webEndpointProperties, Environment environment, String basePath) {return webEndpointProperties.getDiscovery().isEnabled() && (StringUtils.hasText(basePath) || ManagementPortType.get(environment).equals(ManagementPortType.DIFFERENT));}}
- 配置属性类
package com.tuwer.config;import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;/*** <p>配置属性类</p>** @author 土味儿* @version 1.0* @Date 2023/4/22*/
@Data
@ConfigurationProperties(prefix = "tuwer-swagger")
public class SwaggerProperty {String author;String title;String version;String basePackage;
}
2、微服务使用starter
1> 注入依赖
需要使用swagger的服务注入
<!-- Swagger -->
<dependency><groupId>com.tuwer</groupId><artifactId>tuwer-swagger-spring-boot-starter</artifactId><version>1.0-SNAPSHOT</version>
</dependency>
2> 添加配置
spring:mvc:pathmatch:# swagger3.0需要:ant_path_matcher# springboot2.6后默认为:path_pattern_parsermatching-strategy: ant_path_matcher# swagger配置
tuwer-swagger:author: 作者title: 服务名称version: 版本base-package: 基础包
3> 接口中添加API文档信息
API接口中添加
// 示例
@RestController
@Api(tags = "接口类描述")
public class TestApi {@PostMapping("/...")@ApiOperation("接口方法描述")public String test(@ApiParam("参数描述")@RequestParam("id") Long id) {// ...}
}
至此,用starter实现微服务的swagger配置完成!
二、网关聚合文档
使用
spring-cloud-gateway
网关把各个微服务的文档聚合起来,通过网关统一访问。参考:聚合微服务中的 Swagger API 文档
1、注入依赖
在网关服务中加入Swagger依赖
更加细致的设计思路:(网上有介绍)微服务中不需要Swagger的ui包,只要能生成api的json数据包,供网关抓取就可以。同时网关中也不用自已成生api的json数据包,也可以去掉一些相关的依赖包。
<!-- Swagger -->
<dependency><groupId>io.springfox</groupId><artifactId>springfox-boot-starter</artifactId><version>3.0.0</version>
</dependency>
2、配置网关
不是所有的服务都通过网关转发。有些内部服务可以通过docker的内部网络直接访问,可以单独配置这类内部服务的API文档。
spring:# 配置 Spring Cloud 相关属性cloud:# 配置 Spring Cloud Gateway 相关属性gateway:# 配置网关发现机制discovery:# 配置处理机制locator:enabled: false# 开启服务名称小写转换(默认为false)lower-case-service-id: true# 路由配置routes:# 正常服务1- id: server-1uri: 转发地址predicates:- Path=/server_1/**- Method=GET,POSTfilters:- name: StripPrefixargs:# 过滤掉前1节parts: 1# 正常服务2- id: server-2uri: 转发地址predicates:- Path=/server_2/**- Method=GET,POSTfilters:- name: StripPrefixargs:# 过滤掉前1节parts: 1# swagger文档1- id: swagger-docs-1uri: 转发地址predicates:- Path=/swagger_1/**- Method=GET,POSTfilters:- name: StripPrefixargs:# 过滤掉前1节parts: 1# swagger文档2- id: swagger-docs-2uri: 转发地址predicates:- Path=/swagger_2/**- Method=GET,POSTfilters:- name: StripPrefixargs:# 过滤掉前1节parts: 1
3、Swagger资源抓取类
从网关配置中过滤出Swagger的API文档配置信息
package com.tuwer.config;import lombok.AllArgsConstructor;
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;
import java.util.Locale;
import java.util.Objects;/*** <p>Swagger资源类</p>** @author 土味儿* @version 1.0* @Date 2023/4/22*/
@Component
@Primary
@AllArgsConstructor
@SuppressWarnings("all")
public class SwaggerResourceConfig implements SwaggerResourcesProvider {private final RouteLocator routeLocator;private final GatewayProperties gatewayProperties;@Overridepublic List<SwaggerResource> get() {List<SwaggerResource> resources = new ArrayList<>();List<String> routes = new ArrayList<>();// 获取所有swagger文档路由的IDrouteLocator.getRoutes().subscribe(route -> {String routeId = route.getId().toLowerCase(Locale.ROOT);// swagger文档的路由ID中包含有:swagger-docsif (routeId.contains("swagger-docs")) {routes.add(route.getId());}});//过滤出配置文件中定义的路由->过滤出Path Route Predicate->根据路径拼接成api-docs路径->生成SwaggerResourcegatewayProperties.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")// 把路径中后面的 ** 替换成文档地址:v2/api-docs.replace("**", "v2/api-docs"))));});return resources;}private SwaggerResource swaggerResource(String name, String location) {//log.info("name:{},location:{}", name, location);SwaggerResource swaggerResource = new SwaggerResource();swaggerResource.setName(SwaggerModel.getByName(name).cnName);swaggerResource.setLocation(location);swaggerResource.setSwaggerVersion("2.0");return swaggerResource;}/*** 枚举类:中英文映射*/enum SwaggerModel {DEFAULT("default", "默认"),S_1("swagger-docs-1", "文档1"),S_2("swagger-docs-2", "文档2");private String name;private String cnName;SwaggerModel(String name, String cnName) {this.name = name;this.cnName = cnName;}public static SwaggerModel getByName(String name) {for (SwaggerModel m : SwaggerModel.values()) {if (Objects.equals(m.name, name)) {//if(m.code == code){return m;}}return DEFAULT;}}
}
相关文章:

微服务下网关聚合Swagger文档、starter统一配置Swagger
一、starter实现统一配置微服务文档 把Swagger配置中的公共部分抽取出来Swagger与SpringBoot整合中,可能会由于版本问题出现各种问题 1、制作starter 参考: 【SpringBoot】自定义启动器 Starter【保姆级教程】用starter实现Oauth2中资源服务的统一配置用…...

剑指 Offer第二版:机器人的运动范围、正则表达式匹配、表示数值的字符串
剑指 Offer第二版 13. 机器人的运动范围19. 正则表达式匹配20. 表示数值的字符串 13. 机器人的运动范围 题目:地上有一个m行n列的方格,从坐标 [0,0] 到坐标 [m-1,n-1] 。一个机器人从坐标 [0, 0] 的格子开始移动,它每次可以向左、右、上、下移…...

Delaunay三角网生成算法
目录 一、分而治之算法二、三角网生长算法三、逐点插入算法四、约束Delaunay三角网1、方法一1、原始点云2、构网结果 1、方法二1、原始点云2、普通Delaunay3、约束Delaunay Delaunay三角剖分分为直接三角剖分和间接三角剖分。间接三角剖分首先计算为Voronoi图,然后由Voronoi图产…...

hashcode是什么?有什么作用?
文章目录 (1)hashcode()方法的作用(2)equals和hashcode的关系(3)百度百科(4)小白解释 Java中Object有一个方法: public native int hashcode(); (1࿰…...

【人体姿态估计】(一)原理介绍
【人体姿态估计】(一)原理介绍 一、背景 人体姿态估计本质上是一个关键点检测的项目; 关键点检测在生活中的应用十分广泛,包括人脸识别、手势识别,而人体姿态估计则是对身体的关键点进行检测; 本文将介…...

一种新的流:为 Java 加入生成器(Generator)特性
作者:文镭(依来) 前言 这篇文章不是工具推荐,也不是应用案例分享。其主题思想,是介绍一种全新的设计模式。它既拥有抽象的数学美感,仅仅从一个简单接口出发,就能推演出庞大的特性集合,引出许多全新概念。…...

《数据结构C++版》实验一:线性表的顺序存储结构
实验目的 1、实现线性表的顺序存储结构 2、熟悉C++程序的基本结构,掌握程序中的头文件、实现文件和主文件之间的相互关系及各自的作用 3、熟悉顺序表的基本操作方式,掌握顺序表相关操作的具体实现 实验内容 对顺序存储的线性表进行一些基本操作。主要包括: (1)插入:操作…...

ChatGPT的开源平替,终于来了!
最近这段时间,一个号称全球最大ChatGPT开源平替项目Open Assistant引起了大家的注意。 这不最近还登上了GitHub的Trending热榜。 https://github.com/LAION-AI/Open-Assistant 根据官方的介绍,Open Assistant也是一个对话式的大型语言模型项目ÿ…...

Redis基础
Redis6 1. NoSQL数据库简介 1.1 技术发展 技术的分类 1、解决功能性的问题:Java、Jsp、RDBMS、Tomcat、HTML、Linux、JDBC、SVN。 2、解决扩展性的问题:Struts、Spring、SpringMVC、Hibernate、Mybatis。 3、解决性能的问题:NoSQL、Jav…...

为什么重视安全的公司都在用SSL安全证书?
我们今天来讲一讲为什么重视安全的公司都在用SSL证书 SSL证书是什么? SSL安全证书是由权威认证机构颁发的,是CA机构将公钥和相关信息写入一个文件,CA机构用他们的私钥对我们的公钥和相关信息进行签名后,将签名信息也写入这个文件…...

嵌入式QT (使用 Qt Designer 开发)
一、使用 UI 设计器开发程序 1.1、 在 UI 文件添加一个按钮 1.2、在 UI 文件里连接信号与槽 所谓信号即是一个对象发出的信号,槽即是当这个对象发出这个信号时,对应连接的槽就发被执行或者触发。 UI 设计器里信号与槽的连接方法一: 在主窗…...

每日一个小技巧:今天告诉你拍照识别文字的软件有哪些
在现代社会里,手机已经成为了人们生活中必不可少的工具。它的功能众多,比如通讯、上网、拍照以及导航等,为我们的生活带来了许多便利。除此之外,手机还能帮助我们解决一些实际的问题,例如,当你需要识别图片…...

多版本VersionARXDBG
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、一级标题二级标题三级标题四级标题五级标题六级标题总结前言 提示:这里可以添加本文要记录的大概内容: VersionARXDBG,多版本,2023.4.22-4.23两天时间,分别研究了在多版本编译ARXDB…...

# 生成器
生成器 生成器是什么? 生成器(generator)是一种用来生成数据的对象。它们是普通函数的一种特殊形式,可以用来控制数据的生成过程。 生成器有什么优势? 使用生成器的优势在于它们可以在生成数据的同时控制数据的生成过程…...

Netty 源码解析(上)
序 Netty的影响力以及使用场景就不用多说了, 去年10月份后,就着手研究Netty源码,之前研究过Spring源码,MyBatis源码,java.util.concurrent源码,tomcat源码,发现一个特点,之前的源码都…...

Vue 消息订阅与发布
消息订阅与发布,也可以实现任意组件之间的通信。 订阅者:就相当于是我们,用于接收数据。 发布者:就相当于是媒体,用于传递数据。 安装消息订阅与发布插件: 在原生 JS 中 不太容易实现消息订阅与发布&…...

如何在你的云服务器/云主机上更新并使用最新版本的python(python3.11)
更新并使用最新版本的python3.11 第一步,登录云服务器,并更新系统包 打开您的终端(Terminal)或使用任意SSH客户端,输入如下命令来登录云主机: ssh 用户名IP地址 在输入密码后,您将成功登录到云…...

python学习——【第八弹】
前言 上篇文章 python学习——【第七弹】学习了python中的可变序列集合,自此python中的序列的学习就完成啦,这篇文章开始学习python中的函数。 函数 在学习其他编程语言的时候我们就了解过函数:函数就是执行特定任何以完成特定功能的一段代…...

铁路应答器传输系统介绍
应答器传输系统 应答器传输系统是安全点式信息传输系统,通过应答器实现地面设备向车载设备传输信息。 应答器可根据应用需求向车载设备传输固定的(通过无源应答器)或可变的(通过有源应答器)上行链路数据。 当天线单…...

Baumer工业相机堡盟工业相机如何通过BGAPI SDK直接实现Mono16位深度的图像保存(C#)
Baumer工业相机堡盟工业相机如何通过BGAPI SDK直接实现Mono16位深度的图像保存(C#) Baumer工业相机Baumer工业相机保存位深度12/16位图像的技术背景代码案例分享1:引用合适的类文件2:通过BGAPI SDK直接保存Mono12/16图像3…...

C语言入门篇——介绍篇
目录 1、什么是C语言 1、C语言的优点 3、语言标准 4、使用C语言的步骤 5、第一个C语言程序 6、关键字 1、什么是C语言 1972年,贝尔实验室的丹尼斯里奇和肯汤普逊在开发UNIX操作系统时设计了C语言,C语言是在B语言的基础上进行设计。C语言设计的初衷…...

Latex数学公式排版
文章目录 Latex使用最佳方式:读官方文档Latex中的字符数学公式排版1.引入宏包:2.公式排版基础3.数学符号(1).希腊字母(2).指数,上下标,导数(3).分式和根式(4).关系符(5).算符(6).巨算符(7).箭头 Latex使用 最佳方式:读官方文档 The not so short intro…...

【Linux】-关于Linux的指令(上)
作者:小树苗渴望变成参天大树 作者宣言:认真写好每一篇博客 作者gitee:gitee 如 果 你 喜 欢 作 者 的 文 章 ,就 给 作 者 点 点 关 注 吧! TOC 前言 今天我们来讲关于Linux的基本指令,博主讲的指令会对应着Windows…...

【论文写作】引言写作的四个重要的语言点之时态!!!
在本篇文章当中,我们将着重介绍四个重要的写作语言要点之一的时态,其他语言点如下: 1. 时态 2. 标志性的衔接词 3. 主动、被动语态 4. 段落 1. 简单现在时和现在进行时 时态主要有现在时和现在进行时,看以下两个句子 I live in…...

Super Yolo论文翻译
论文:SuperYOLO: Super Resolution Assisted Object Detection in Multimodal Remote Sensing Imagery【IEEE】 论文地址: IEEE Xplore Full-Text PDF:https://ieeexplore.ieee.org/stamp/stamp.jsp?tp&arnumber10075555项目地址:icey…...

【CocosCreator入门】CocosCreator组件 | ProgressBar(进度条)组件
Cocos Creator 是一款流行的游戏开发引擎,具有丰富的组件和工具,其中的ProgressBar组件是一种用于实现进度条效果的重要组件。它可以让我们在游戏中展示各种进度条效果,例如加载进度条、血条等。 目录 一、组件介绍 二、组件属性 三、脚本…...

大数据数仓维度建模
目录 维度建模分为三种: 1、星型模型: 2、雪花模型: 3、星座模型: 模型的选择: 维度表和事实表: 维度表: 维度表特性 : 事实表: 事实表特性: 事务型…...

ESP32设备驱动-BH1745NUC 亮度和颜色传感器驱动
BH1745NUC 亮度和颜色传感器驱动 文章目录 BH1745NUC 亮度和颜色传感器驱动2、硬件准备3、软件准备4、驱动实现BH1745NUC 是具有 IC 总线接口的数字颜色传感器 IC。 该 IC 感应红光、绿光和蓝光 (RGB) 并将它们转换为数字值。 高灵敏度、宽动态范围和出色的 Ircut 特性使该 IC …...

通达信VCP形态选股公式,憋了好几天才写出来
VCP形态的英文”Volatility Contraction Pattern”的缩写,意思是“波动收缩形态”。VCP形态是全美交易冠军马克米勒维尼的核心交易模式之一,在其著作《股票魔法师》中有详细介绍。 马克米勒维尼把VCP形态比喻为湿毛巾,拧过一次后仍含水&…...

vue 知识储备
vue2 和 vue3 的区别 模块拆分:vue3采用 compnent API 更注重模块上的拆分,而vue2中则需要使用完整的vuejs,无法使用单独的模块重写API:vue2组件方法挂载到实例中未使用也会被打包,vue3通过 tree-shaking机制,实现按需引入,减少用户打包后体积数据双向绑定:vue2使用 Ob…...