基于spring gateway 的静态资源缓存实现
由于子项目比较多,子项目都是通过嵌套的方式实现的。就会导致子页面加载比较慢,影响客户体验
实现思路(AI搜的--!):
1、通过spring boot缓存实现静态资源缓存
2、在gateway过滤器,对静态资源进行缓存
直接上代码:
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-cache</artifactId>
</dependency>
package com.xxx.filter;import lombok.extern.slf4j.Slf4j;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
import org.springframework.cache.support.SimpleValueWrapper;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.client.WebClient;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;import java.net.URI;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;/*** @author Wang* 创建时间: 2023/11/15 10:19* 功能描述:静态资源缓存*/
@Slf4j
@Component
public class StaticResourceFilter implements GlobalFilter, Ordered {private static final String STATIC_RESOURCE_PATTERN = "\\.(html|css|js|png|jpg|jpeg|gif|woff2|woff)$";private final WebClient webClient;private final CacheManager cacheManager;List<String> synchronizedList = Collections.synchronizedList(new ArrayList<>());public StaticResourceFilter(WebClient webClient, CacheManager cacheManager) {this.webClient = webClient;this.cacheManager = cacheManager;}@Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {ServerHttpRequest request = exchange.getRequest();URI uriInfo = request.getURI();String staticResourcePath = getUrl(uriInfo);if (isStaticResource(staticResourcePath) && !synchronizedList.contains(staticResourcePath)) {//Route route = exchange.getAttribute(ServerWebExchangeUtils.GATEWAY_ROUTE_ATTR);String cacheKey = request.getURI().toString();Cache cache = cacheManager.getCache("staticResources");// 尝试从缓存中获取静态资源Object cachedResource = cache.get(cacheKey);if (cachedResource != null) {if (cachedResource instanceof SimpleValueWrapper) {cachedResource = ((SimpleValueWrapper) cachedResource).get();}// 如果缓存中存在,直接返回缓存的资源ServerHttpResponse response = exchange.getResponse();HttpHeaders headers = response.getHeaders();String fileSuffix = staticResourcePath.replaceAll(".*(\\.[a-zA-Z0-9]+)$", "$1");// 根据文件后缀设置MIME类型switch (fileSuffix) {case ".html":headers.setContentType(MediaType.TEXT_HTML);break;case ".js":headers.set(HttpHeaders.CONTENT_TYPE, "application/javascript");break;case ".css":headers.set(HttpHeaders.CONTENT_TYPE, "text/css");break;case ".png":headers.setContentType(MediaType.IMAGE_PNG);break;case ".jpg":case ".jpeg":headers.setContentType(MediaType.IMAGE_JPEG);break;case ".woff":headers.set(HttpHeaders.CONTENT_TYPE, "application/font-woff");break;case ".woff2":headers.set(HttpHeaders.CONTENT_TYPE, "application/font-woff2");break;case ".ttf":headers.set(HttpHeaders.CONTENT_TYPE, "application/x-font-ttf");break;case ".eot":headers.set(HttpHeaders.CONTENT_TYPE, "application/vnd.ms-fontobject");break;default:headers.setContentType(MediaType.ALL);break;}// 这里假设缓存的内容是字节数组,您可以根据实际情况进行调整DataBuffer dataBuffer = response.bufferFactory().wrap((byte[]) cachedResource);return response.writeWith(Mono.just(dataBuffer));}// 如果缓存不存在,则继续请求下游服务获取资源,并将其缓存起来return chain.filter(exchange).then(Mono.fromRunnable(() -> {getResourceFromDownstream(staticResourcePath, cacheKey, cache);}));}// 继续处理其他过滤器或请求return chain.filter(exchange);}@Overridepublic int getOrder() {return Ordered.HIGHEST_PRECEDENCE;}/*** 根据请求路径判断是否为静态资源请求** @param staticResourcePath 请求路径*/private boolean isStaticResource(String staticResourcePath) {Pattern pattern = Pattern.compile(STATIC_RESOURCE_PATTERN);Matcher matcher = pattern.matcher(staticResourcePath);return matcher.find();}/*** 请求下游服务静态资源的方法,这里只是一个示例,您需要根据实际情况实现此方法** @param cache 缓存* @param staticResourcePath URL* @param cacheKey 缓存Key*/private void getResourceFromDownstream(String staticResourcePath, String cacheKey, Cache cache) {synchronizedList.add(staticResourcePath);Mono<byte[]> mono = webClient.get().uri(staticResourcePath).retrieve().bodyToMono(byte[].class);// 处理响应数据mono.subscribe(res -> {synchronizedList.remove(staticResourcePath);cache.put(cacheKey, res);}, error -> {log.error("请求下游服务静态资源失败:{},\n错误详情:{}", staticResourcePath, error.toString());});}/*** 获取静态资源地址** @param uri uri* @return 静态资源地址*/private String getUrl(URI uri) {String path = uri.getPath();String host = uri.getHost();int port = uri.getPort();// 下游服务的地址是String downstreamUrl = String.format("http://%s:%s%s", host, port, path);return downstreamUrl;}
}
相关文章:
基于spring gateway 的静态资源缓存实现
由于子项目比较多,子项目都是通过嵌套的方式实现的。就会导致子页面加载比较慢,影响客户体验 实现思路(AI搜的--!): 1、通过spring boot缓存实现静态资源缓存 2、在gateway过滤器,对静态资源进行缓存 直接上代码&a…...
SDUT OJ《算法分析与设计》搜索算法
A - 子集和问题 Description 子集和问题的一个实例为〈S,t〉。其中,S{ x1 , x2 ,…,xn }是一个正整数的集合,c是一个正整数。子集和问题判定是否存在S的一个子集S1,使得: 。 试设计一个解子…...
【NI-DAQmx入门】校准
1.设备定期校准的理由 随着时间的推移电子器件的特性会发生自然漂移,可能会导致测量结果的不准确性。防止出现良品和差品筛选出错的情况满足行业国际标准降低设备出现故障的风险使测量结果更具备参考性 2.查找NI设备的校准间隔。 定期校准会使DAQ设备的精度保持在…...
C语言链表
head.h typedef struct Node_s{int data; //数据域struct Node_s *pNext; //指针域 } Node_t, *pNode_t;void headInsert(pNode_t *ppHead, pNode_t *ppTail, int data); void print(pNode_t pHead); void tailInsert(pNode_t *ppHead, pNode_t *ppTail, int data); void sort…...
LabVIEW进行MQTT通信及数据解析
需求:一般通过串口的方式进行数据的解析,但有时候硬件的限制,没法预留串口,那么如何通过网络的方式特别是MQTT数据的通信及解析 解决方式: 1.MQTT通信控件: 参考开源的mqtt-LabVIEW https://github.com…...
基于DOTween插件实现金币飞行到指定位置功能
文章目录 前言一、DOTween是什么?二、使用步骤1.导入DOTween插件在Unity官方插件商店找到DOTween插件导入DOTween插件启用DOTween插件 2.代码逻辑金币飞行代码控制飞行效果代码 3.物体配置1.物体上装配CoinEffect脚本2.在金币预制体上装配FlyControl脚本 三、效果展…...
python-opencv 培训课程作业
python-opencv 培训课程作业 作业一: 第一步:读取 res 下面的 flower.jpg,读取彩图,并用 opencv 展示 第二步:彩图 -> 灰度图 第三步:反转图像:最大图像灰度值减去原图像,即可得…...
【Go入门】并发
【Go入门】并发 有人把Go比作21世纪的C语言,第一是因为Go语言设计简单,第二,21世纪最重要的就是并行程序设计,而Go从语言层面就支持了并行。 goroutine goroutine是Go并行设计的核心。goroutine说到底其实就是协程,…...
Java虚拟机运行时数据区结构详解
Java虚拟机运行时数据区结构如图所示 程序计数器 程序计数器(Program Counter Register)是一块较小的内存空间,它可以看作是当前线程所执行的字节码的行号指示器。 多线程切换时,为了能恢复到正确的执行位置,每条线程…...
华为OD机试 - 转盘寿司(Java JS Python C)
目录 题目描述 输入描述 输出描述 用例 题目解析 JS算法源码 Java算法源码...
【ATTCK】MITRE Caldera-emu插件
CALDERA是一个由python语言编写的红蓝对抗工具(攻击模拟工具)。它是MITRE公司发起的一个研究项目,该工具的攻击流程是建立在ATT&CK攻击行为模型和知识库之上的,能够较真实地APT攻击行为模式。 通过CALDERA工具,安全…...
23111709[含文档+PPT+源码等]计算机毕业设计基于Spring Boot智能无人仓库管理-进销存储
文章目录 **软件开发环境及开发工具:****功能介绍:****论文截图:****数据库:****实现:****代码片段:** 编程技术交流、源码分享、模板分享、网课教程 🐧裙:776871563 软件开发环境及…...
SDUT OJ《算法分析与设计》贪心算法
A - 汽车加油问题 Description 一辆汽车加满油后可行驶n公里。旅途中有若干个加油站。设计一个有效算法,指出应在哪些加油站停靠加油,使沿途加油次数最少。并证明算法能产生一个最优解。 对于给定的n和k个加油站位置,计算最少加油次数。 I…...
金融业务系统: Service Mesh用于安全微服务集成
随着云计算的不断演进,微服务架构变得日益复杂。为了有效地管理这种复杂性,人们开始采用服务网格。在本文中,我们将解释什么是Service Mesh,为什么它对现代云架构至关重要,以及它是如何解决开发人员今天面临的一些最紧…...
Linux下快速确定目标服务器支持哪些协议和密码套件
实现原理是利用TLS协议的特点和握手过程来进行测试和解析响应来确定目标服务器支持哪些TLS协议和密码套件。 在TLS握手过程中,客户端和服务器会协商并使用相同的TLS协议版本和密码套件来进行通信。通过发送特定的握手请求并分析响应,可以确定目标服务器…...
LeetCode100122. Separate Black and White Balls
文章目录 一、题目二、题解 一、题目 There are n balls on a table, each ball has a color black or white. You are given a 0-indexed binary string s of length n, where 1 and 0 represent black and white balls, respectively. In each step, you can choose two a…...
系列二十六、idea安装javap -c
一、概述 javap -c是一个能够将.java文件反编译为.class文件的指令,例如我在idea中编写了一个Car.java文件,我想看看这个类被编译后长什么样的,就可以使用该指令进行查看。 二、配置 2.1、 Java Bytecode Decompiler File>Settings>Pl…...
nginx 如何根据IP做限流,以及 nginx 直接返回 json 格式数据
Nginx 限流配置 Nginx是如何限流的。随着业务的扩散,系统并发越来越高时,有三样利器用来保护系统,分别是缓存、降级和限流。 随着业务的扩散,系统并发越来越高时,有三样利器用来保护系统,分别是缓存、降…...
C语言链式栈
stack.h typedef struct Node_s {int data;struct Node_s *pNext; } Node_t, *pNode_t;typedef struct Stack_s {pNode_t pHead;//栈顶指针,指向了链表的第一个结点int size;//栈的元素个数 } Stack_t, *pStack_t;void init(pStack_t pStack); void push(pStack_t …...
【Go入门】 Go的http包详解
【Go入门】 Go的http包详解 前面小节介绍了Go怎么样实现了Web工作模式的一个流程,这一小节,我们将详细地解剖一下http包,看它到底是怎样实现整个过程的。 Go的http有两个核心功能:Conn、ServeMux Conn的goroutine 与我们一般编…...
3PEAK思瑞浦 TPA6532-VS1R MSOP8 运算放大器
特性 供电电压:1.75伏至5.5伏 偏移电压:土1.5mV(最大) 通用峰值电压:300kHz,斜率:0.15V/us 轨到轨输入和输出 0.1Hz至10Hz电压噪声:1Vpp 开机和关机电流期间无明显输出抖动 低功耗:每通道最大25安培工作温度范围:-40C至125C...
2026 最新版网络安全全岗位详解,入行择业一看就懂
全网最全!网络安全全岗位解析(2026版) 摘要:随着数字化转型加速,网络安全已成为企业、政务、互联网大厂的核心刚需,人才缺口持续扩大,2026年国内网络安全人才缺口已突破327万,全球缺…...
AMD Ryzen隐藏性能调优利器:SMUDebugTool硬件调试工具完全指南
AMD Ryzen隐藏性能调优利器:SMUDebugTool硬件调试工具完全指南 【免费下载链接】SMUDebugTool A dedicated tool to help write/read various parameters of Ryzen-based systems, such as manual overclock, SMU, PCI, CPUID, MSR and Power Table. 项目地址: ht…...
git--github
解决github无法访问的问题。...
量子机器学习实战:遥感图像分割的混合模型构建与硬件噪声影响分析
1. 项目概述与核心挑战量子机器学习(QML)这个领域,听起来像是科幻小说里的概念,但过去几年,它已经从理论物理的殿堂,逐渐走进了我们这些做工程和算法应用的人的视野。简单来说,它试图用量子计算…...
Burp Suite实战配置指南:HTTPS抓包与Proxy深度调优
1. 这不是又一篇“点开就关”的Burp教程——为什么你总在重复安装、配置、抓不到包? “Burp Suite 保姆级指南”——看到这标题,你可能已经下意识划走:又是一篇打开后三分钟就关掉的“安装截图菜单翻译‘点击Proxy→Intercept→On’”式流水账…...
显示what failed:VMMR0.r0--已解决
VirtualBox版本5.2.44 win11家庭中文版 以下是已经尝试内核隔离无用的情况下,所写出的解决方案。 winR,输入services.msc 禁用该服务后 管理员身份打开cmd,输入bcdedit /set hypervisorlaunchtype off 重启后确认查看方式 ①管理员身…...
LLM应用开发之向量数据库详解
摘要随着大语言模型(LLM)应用的快速发展,向量数据库作为AI时代的关键基础设施,正在成为RAG(检索增强生成)、语义搜索、智能推荐等场景的核心组件。本文将从向量嵌入的原理出发,深入讲解向量相似…...
ComfyUI-Custom-Scripts自动完成功能完整指南:提升AI绘画效率的终极解决方案
ComfyUI-Custom-Scripts自动完成功能完整指南:提升AI绘画效率的终极解决方案 【免费下载链接】ComfyUI-Custom-Scripts Enhancements & experiments for ComfyUI, mostly focusing on UI features 项目地址: https://gitcode.com/gh_mirrors/co/ComfyUI-Custo…...
保姆级教程:用再生龙Clonezilla Live给Ubuntu系统做全盘备份与恢复(含BIOS设置避坑)
从零掌握Clonezilla:Ubuntu系统全盘备份与恢复实战指南当你的Ubuntu系统突然崩溃,或是需要快速部署多台相同配置的机器时,一个可靠的系统备份方案能让你从容应对。Clonezilla作为开源备份神器,其强大功能不输商业软件,…...
