微服务下网关聚合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…...
Vim 调用外部命令学习笔记
Vim 外部命令集成完全指南 文章目录 Vim 外部命令集成完全指南核心概念理解命令语法解析语法对比 常用外部命令详解文本排序与去重文本筛选与搜索高级 grep 搜索技巧文本替换与编辑字符处理高级文本处理编程语言处理其他实用命令 范围操作示例指定行范围处理复合命令示例 实用技…...
生成xcframework
打包 XCFramework 的方法 XCFramework 是苹果推出的一种多平台二进制分发格式,可以包含多个架构和平台的代码。打包 XCFramework 通常用于分发库或框架。 使用 Xcode 命令行工具打包 通过 xcodebuild 命令可以打包 XCFramework。确保项目已经配置好需要支持的平台…...
Linux 文件类型,目录与路径,文件与目录管理
文件类型 后面的字符表示文件类型标志 普通文件:-(纯文本文件,二进制文件,数据格式文件) 如文本文件、图片、程序文件等。 目录文件:d(directory) 用来存放其他文件或子目录。 设备…...
RocketMQ延迟消息机制
两种延迟消息 RocketMQ中提供了两种延迟消息机制 指定固定的延迟级别 通过在Message中设定一个MessageDelayLevel参数,对应18个预设的延迟级别指定时间点的延迟级别 通过在Message中设定一个DeliverTimeMS指定一个Long类型表示的具体时间点。到了时间点后…...
简易版抽奖活动的设计技术方案
1.前言 本技术方案旨在设计一套完整且可靠的抽奖活动逻辑,确保抽奖活动能够公平、公正、公开地进行,同时满足高并发访问、数据安全存储与高效处理等需求,为用户提供流畅的抽奖体验,助力业务顺利开展。本方案将涵盖抽奖活动的整体架构设计、核心流程逻辑、关键功能实现以及…...
从零实现富文本编辑器#5-编辑器选区模型的状态结构表达
先前我们总结了浏览器选区模型的交互策略,并且实现了基本的选区操作,还调研了自绘选区的实现。那么相对的,我们还需要设计编辑器的选区表达,也可以称为模型选区。编辑器中应用变更时的操作范围,就是以模型选区为基准来…...
SCAU期末笔记 - 数据分析与数据挖掘题库解析
这门怎么题库答案不全啊日 来简单学一下子来 一、选择题(可多选) 将原始数据进行集成、变换、维度规约、数值规约是在以下哪个步骤的任务?(C) A. 频繁模式挖掘 B.分类和预测 C.数据预处理 D.数据流挖掘 A. 频繁模式挖掘:专注于发现数据中…...
蓝牙 BLE 扫描面试题大全(2):进阶面试题与实战演练
前文覆盖了 BLE 扫描的基础概念与经典问题蓝牙 BLE 扫描面试题大全(1):从基础到实战的深度解析-CSDN博客,但实际面试中,企业更关注候选人对复杂场景的应对能力(如多设备并发扫描、低功耗与高发现率的平衡)和前沿技术的…...
【服务器压力测试】本地PC电脑作为服务器运行时出现卡顿和资源紧张(Windows/Linux)
要让本地PC电脑作为服务器运行时出现卡顿和资源紧张的情况,可以通过以下几种方式模拟或触发: 1. 增加CPU负载 运行大量计算密集型任务,例如: 使用多线程循环执行复杂计算(如数学运算、加密解密等)。运行图…...
【碎碎念】宝可梦 Mesh GO : 基于MESH网络的口袋妖怪 宝可梦GO游戏自组网系统
目录 游戏说明《宝可梦 Mesh GO》 —— 局域宝可梦探索Pokmon GO 类游戏核心理念应用场景Mesh 特性 宝可梦玩法融合设计游戏构想要素1. 地图探索(基于物理空间 广播范围)2. 野生宝可梦生成与广播3. 对战系统4. 道具与通信5. 延伸玩法 安全性设计 技术选…...
