SpringCloudGateway集成SpringDoc CORS问题
SpringCloudGateway集成SpringDoc CORS问题
集成SpringDoc后,在gateway在线文档界面,请求具体的服务接口,报CORS问题
Failed to fetch.
Possible Reasons:
CORS
Network Failure
URL scheme must be “http” or “https” for CORS request.
分析
其实是网关直接请求具体服务/v3/api-docs接口(默认),获取文档数据,里面包含该服务注册上来的地址,gateway swagger-ui解析该接口数据,根据里面的地址直接请求。可是网关地址,跟具体的服务地址肯定不同源,在gateway集成界面请求,肯定报跨的问题。
或者是该微服务群,只能通过网关访问,直接请求具体的服务地址,网络不通。
{"openapi": "3.0.1","info": {"title": "XX服务","description": "XX服务开发接口文档","version": "1.0.0"},"servers": [{"url": "http://[2408:8456:601:9f52:225d:8f68:5e14:6ff4]:8201","description": "Generated server url"}]
}
思路
通过在gateway编写全局GatewayFilter,拦截集成时请求的 /xx/v3/api-docs接口(默认)接口,修改返回的数据,在servers写入通过网关直接访问的地址,就能解决在线文档请求接口,存在的跨域问题和网络不通问题。
实现
/*** 处理服务 /v3/api-docs接口返回的数据,在servers里添加可以通过网关直接访问的地址*/
@Slf4j
@Component
@ConditionalOnProperty(name = SPRINGDOC_ENABLED, matchIfMissing = true)
public class DocServiceUrlModifyGatewayFilter implements GlobalFilter, Ordered {@Autowiredprivate SpringDocConfigProperties springDocConfigProperties;@Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {//直接用配置类的值,默认值是 /v3/api-docsString apiPath = springDocConfigProperties.getApiDocs().getPath();ServerHttpRequest request = exchange.getRequest();ServerHttpResponse response = exchange.getResponse();URI uri = request.getURI();//非正常状态跳过if (response.getStatusCode().value() != HttpStatus.OK.value()) {return chain.filter(exchange);}//非springdoc文档不拦截if (!(StringUtils.isNotBlank(uri.getPath()) && uri.getPath().endsWith(apiPath))) {return chain.filter(exchange);}String uriString = uri.toString();String gatewayUrl = uriString.substring(0, uriString.lastIndexOf(apiPath));DataBufferFactory bufferFactory = response.bufferFactory();ServerHttpResponseDecorator decoratedResponse = new ServerHttpResponseDecorator(response) {@Overridepublic Mono<Void> writeWith(Publisher<? extends DataBuffer> body) {//不处理if (!(body instanceof Flux)) {return super.writeWith(body);}//处理SpringDoc-OpenAPIFlux<? extends DataBuffer> fluxBody = (Flux<? extends DataBuffer>) body;return super.writeWith(fluxBody.buffer().map(dataBuffers -> {DataBufferFactory dataBufferFactory = new DefaultDataBufferFactory();DataBuffer join = dataBufferFactory.join(dataBuffers);byte[] content = new byte[join.readableByteCount()];join.read(content);DataBufferUtils.release(join);try {// 流转为字符串String responseData = new String(content, StandardCharsets.UTF_8);Map<String, Object> map = JsonUtils.json2Object(responseData, Map.class);//处理返回的数据Object serversObject = map.get("servers");if (null != serversObject) {List<Map<String, Object>> servers = (List<Map<String, Object>>) serversObject;Map<String, Object> gatewayServer = new HashMap<>();//网关地址gatewayServer.put("url", gatewayUrl);gatewayServer.put("description", "Gateway server url");//添加到第1个servers.add(0, gatewayServer);map.put("servers", servers);responseData = JsonUtils.object2Json(map);byte[] uppedContent = responseData.getBytes(StandardCharsets.UTF_8);response.getHeaders().setContentLength(uppedContent.length);return bufferFactory.wrap(uppedContent);}} catch (Exception e) {log.error(e.getMessage(), e);}return bufferFactory.wrap(content);}));}};// replace response with decoratorreturn chain.filter(exchange.mutate().response(decoratedResponse).build());}@Overridepublic int getOrder() {return -2;}class JsonUtils {public static final ObjectMapper OBJECT_MAPPER = createObjectMapper();/*** 初始化ObjectMapper** @return*/private static ObjectMapper createObjectMapper() {ObjectMapper objectMapper = new ObjectMapper();objectMapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);objectMapper.configure(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT, true);objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
// objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, true);// objectMapper.registerModule(new Hibernate4Module().enable(Hibernate4Module.Feature.FORCE_LAZY_LOADING));objectMapper.registerModule(new JavaTimeModule());return objectMapper;}public static String object2Json(Object o) {StringWriter sw = new StringWriter();JsonGenerator gen = null;try {gen = new JsonFactory().createGenerator(sw);OBJECT_MAPPER.writeValue(gen, o);} catch (IOException e) {throw new RuntimeException("不能序列化对象为Json", e);} finally {if (null != gen) {try {gen.close();} catch (IOException e) {throw new RuntimeException("不能序列化对象为Json", e);}}}return sw.toString();}/*** 将 json 字段串转换为 对象.** @param json 字符串* @param clazz 需要转换为的类* @return*/public static <T> T json2Object(String json, Class<T> clazz) {try {return OBJECT_MAPPER.readValue(json, clazz);} catch (IOException e) {throw new RuntimeException("将 Json 转换为对象时异常,数据是:" + json, e);}}}
}
相关文章:
SpringCloudGateway集成SpringDoc CORS问题
SpringCloudGateway集成SpringDoc CORS问题 集成SpringDoc后,在gateway在线文档界面,请求具体的服务接口,报CORS问题 Failed to fetch. Possible Reasons: CORS Network Failure URL scheme must be “http” or “https” for CORS reques…...
国际版阿里云/腾讯云:弹性高性能计算E-HPC入门概述
入门概述 本文介绍E-HPC的运用流程,帮助您快速上手运用弹性高性能核算。 下文以创立集群,在集群中安装GROMACS软件并运转水分子算例进行高性能核算为例,介绍弹性高性能核算的运用流程,帮助您快速上手运用弹性高性能核算。运用流程…...
【博客702】shell flock实现单例模式执行任务
shell flock实现单例模式执行任务 场景 我们需要定时执行一个任务,并且保证每次执行时都需要上一次已经执行完了,即保证同一时间只有一个在运行 示例 假设需要执行的脚本是:ping_and_mtr.sh 创建一个新的脚本来运行你的逻辑脚本࿱…...
数据分析基础-数据可视化07-用数据分析讲故事
如何构建⼀个引⼈⼊胜的故事? ⾸先:要想象什么? 可视化什么⽐如何可视化更重要 统计分析:GIGO(垃圾输⼊,垃圾输出) 在可视化分析环境中: 吉⾼ → 您⽆法从可视化的不适当数据中获…...
策略模式简介
概念: 策略模式(Strategy Pattern)是一种行为型设计模式,它定义了一系列算法,并将每个算法封装到独立的类中,使得它们可以互相替换。通过使用策略模式,客户端可以在运行时选择不同的算法来解决…...
学术加油站|基于端到端性能的学习型基数估计器综合测评
编者按 本文系东北大学李俊虎所著,也是「 OceanBase 学术加油站」系列第 11 篇内容。 「李俊虎:东北大学计算机科学与工程学院在读硕士生,课题方向为数据库查询优化,致力于应用 AI 技术改进传统基数估计器,令数据库选…...
MySQL 使用规范 —— 如何建好字段和索引
一、案例背景 二、库表规范 1. 建表相关规范 2. 字段相关规范 3. 索引相关规范 4. 使用相关规范 三、建表语句 三、语句操作 1. 插入操作 2. 查询操作 四、其他配置 1. 监控活动和性能: 2. 连接数查询和配置 本文的宗旨在于通过简单干净实践的方式教会读…...
Relation Extraction as Open-book Examination: Retrieval-enhanced Prompt Tuning
本文是LLM系列文章,针对《Relation Extraction as Open-book Examination: Retrieval 关系提取作为开卷测试:检索增强提示调整 摘要1 引言2 方法3 实验4 相关工作5 结论 摘要 经过预训练的语言模型通过表现出显著的小样本学习能力,对关系提取…...
FFmpeg报错:Connection to tcp://XXX?timeout=XXX failed: Connection timed out
一、现象 通过FFmpeg(FFmpeg的版本是5.0.3)拉摄像机的rtsp流获取音视频数据,执行命令: ./ffmpeg -timeout 3000000 -i "rtsp://172.16.17.156/stream/video5" 报错:Connection to tcp://XXX?timeoutXXX …...
iOS开发Swift-7-得分,问题序号,约束对象,提示框,类方法与静态方法-趣味问答App
1.根据用户回答计算得分 ViewController.swift: import UIKitclass ViewController: UIViewController {var questionIndex 0var score 0IBOutlet weak var questionLabel: UILabel!IBOutlet weak var scoreLabel: UILabel!override func viewDidLoad() {super.viewDidLoad()…...
AUTOSAR规范与ECU软件开发(实践篇)7.10MCAL模块配置方法及常用接口函数介绍之Base与Resource的配置
目录 1、前言 2 、Base与Resource模块 1、前言 本例程的硬件平台为MPC5744P开发板,主要配置MPC5744P的mcal的每个模块的配置,如要配置NXP的MCU之S32k324的例程请参考: 2 、Base与Resource模块 Base与Resource这两个模块与具体功能无关&…...
Android11编译第二弹:USB连接MTP模式+USB调试+USB信任
一、为什么需要开启USB信任和ADB调试 问题1:原始的AOSP,如果通过USB连接设备以后,会弹窗提示用户选择连接模式:MTP,大容量磁盘,照片等模式; 问题2:USB连接设备以后,需要…...
Unity ShaderGraph教程——基础shader
1.基本贴图shader: 基础贴图实现:主贴图、自发光贴图、光滑度贴图、自发光贴图(自发光还加入了颜色影响和按 钮开关). 步骤:最左侧操作组——新建texture2D——新建sample texture 2D承…...
第 3 章 栈和队列(单链队列)
1. 背景说明 队列(queue)是一种先进先出(first in first out,缩为 FIFO)的线性表。它只允许在表的一端进行插入,而在另一端删除元素。 2. 示例代码 1)status.h /* DataStructure 预定义常量和类型头文件 */#ifndef STATUS_H #define STATUS_H/* 函数结果…...
【DFS】1254. 统计封闭岛屿的数目
1254. 统计封闭岛屿的数目 解题思路 封闭岛屿就是上下左右全部被1包围的0 也就是靠边的0不算做封闭岛屿首先将上下左右的边界上的岛屿全部变成海洋然后在对剩下的岛屿进行DFS遍历 class Solution {public int closedIsland(int[][] grid) {// 封闭岛屿就是上下左右全部被1包…...
C#--sugarClient使用之ColumnName
使用Sugar ORM框架可以很方便地实现表名和实体名的映射,可以按照以下步骤进行操作: 创建一个实体类,定义实体的属性及其他信息。 [SugarTable("user_info")] // 指定实体对应的表名 public class User {public int Id { get; set…...
深度学习-4-二维目标检测-YOLOv5源码测试与训练
本文采用的YOLOv5源码是ultralytics发行版3.1 YOLOv5源码测试与训练 1.Anaconda环境配置 1.1安装Anaconda Anaconda 是一个用于科学计算的 Python 发行版,支持 Linux, Mac, Windows, 包含了众多流行的科学计算、数据分析的 Python 包。 官方网址下载安装包&…...
找不到msvcp140.dll的解决方法【msvcp140.dll修复工具下载】
今天,我将为大家分享一个与我们日常工作息息相关的话题——msvcp140.dll重新安装的5种解决方法。在接下来的时间里,我将向大家介绍什么是msvcp140.dll,为什么会丢失,以及它的用途。最后,我将为大家提供5种解决方法,帮助…...
内网隧道代理技术(二十)之 CS使用HTTP代理上线不出网机器
CS使用HTTP代理上线不出网机器 CS工具自带上线不出网机器 如图A区域存在一台中转机器,这台机器可以出网,这种是最常见的情况。我们在渗透测试的过程中经常是拿下一台边缘机器,其有多块网卡,边缘机器可以访问内网机器,内网机器都不出网。这种情况下拿这个边缘机器做中转,…...
安卓 tcp 客户端
安卓 tcp 客户端 Server:8888 是Qt 写的Tcp 服务器 ip 是 192.168.2.103 port是8888 安卓手机运行 kotlin 语法的Tcp Client ,连接,收发数据 效果如下图 Tcpclient package com.example.myapplicationimport android.os.Handler import android.os.Loo…...
[特殊字符] 智能合约中的数据是如何在区块链中保持一致的?
🧠 智能合约中的数据是如何在区块链中保持一致的? 为什么所有区块链节点都能得出相同结果?合约调用这么复杂,状态真能保持一致吗?本篇带你从底层视角理解“状态一致性”的真相。 一、智能合约的数据存储在哪里…...
龙虎榜——20250610
上证指数放量收阴线,个股多数下跌,盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型,指数短线有调整的需求,大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的:御银股份、雄帝科技 驱动…...
【入坑系列】TiDB 强制索引在不同库下不生效问题
文章目录 背景SQL 优化情况线上SQL运行情况分析怀疑1:执行计划绑定问题?尝试:SHOW WARNINGS 查看警告探索 TiDB 的 USE_INDEX 写法Hint 不生效问题排查解决参考背景 项目中使用 TiDB 数据库,并对 SQL 进行优化了,添加了强制索引。 UAT 环境已经生效,但 PROD 环境强制索…...
《Playwright:微软的自动化测试工具详解》
Playwright 简介:声明内容来自网络,将内容拼接整理出来的文档 Playwright 是微软开发的自动化测试工具,支持 Chrome、Firefox、Safari 等主流浏览器,提供多语言 API(Python、JavaScript、Java、.NET)。它的特点包括&a…...
解决Ubuntu22.04 VMware失败的问题 ubuntu入门之二十八
现象1 打开VMware失败 Ubuntu升级之后打开VMware上报需要安装vmmon和vmnet,点击确认后如下提示 最终上报fail 解决方法 内核升级导致,需要在新内核下重新下载编译安装 查看版本 $ vmware -v VMware Workstation 17.5.1 build-23298084$ lsb_release…...
从零开始打造 OpenSTLinux 6.6 Yocto 系统(基于STM32CubeMX)(九)
设备树移植 和uboot设备树修改的内容同步到kernel将设备树stm32mp157d-stm32mp157daa1-mx.dts复制到内核源码目录下 源码修改及编译 修改arch/arm/boot/dts/st/Makefile,新增设备树编译 stm32mp157f-ev1-m4-examples.dtb \stm32mp157d-stm32mp157daa1-mx.dtb修改…...
2025盘古石杯决赛【手机取证】
前言 第三届盘古石杯国际电子数据取证大赛决赛 最后一题没有解出来,实在找不到,希望有大佬教一下我。 还有就会议时间,我感觉不是图片时间,因为在电脑看到是其他时间用老会议系统开的会。 手机取证 1、分析鸿蒙手机检材&#x…...
土地利用/土地覆盖遥感解译与基于CLUE模型未来变化情景预测;从基础到高级,涵盖ArcGIS数据处理、ENVI遥感解译与CLUE模型情景模拟等
🔍 土地利用/土地覆盖数据是生态、环境和气象等诸多领域模型的关键输入参数。通过遥感影像解译技术,可以精准获取历史或当前任何一个区域的土地利用/土地覆盖情况。这些数据不仅能够用于评估区域生态环境的变化趋势,还能有效评价重大生态工程…...
学习STC51单片机32(芯片为STC89C52RCRC)OLED显示屏2
每日一言 今天的每一份坚持,都是在为未来积攒底气。 案例:OLED显示一个A 这边观察到一个点,怎么雪花了就是都是乱七八糟的占满了屏幕。。 解释 : 如果代码里信号切换太快(比如 SDA 刚变,SCL 立刻变&#…...
AspectJ 在 Android 中的完整使用指南
一、环境配置(Gradle 7.0 适配) 1. 项目级 build.gradle // 注意:沪江插件已停更,推荐官方兼容方案 buildscript {dependencies {classpath org.aspectj:aspectjtools:1.9.9.1 // AspectJ 工具} } 2. 模块级 build.gradle plu…...
