Spring控制重复请求
通过AOP拦截所有请求,控制在规定时间内请求次数。
1:添加maven
<dependency><groupId>net.jodah</groupId><artifactId>expiringmap</artifactId><version>0.5.10</version>
</dependency>
2:全局注解
import java.lang.annotation.*;
import java.util.concurrent.TimeUnit;/*** @Description 是否重复提交注解(在方法上,例: @IsRepeatSubmit 或者 @IsRepeatSubmit(count = 2,time = 2000),参数不写使用默认值)* @Author WangKun* @Date 2024/5/22 16:52* @Version*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface IsRepeatSubmit {/*** 限制时间单位 单位:毫秒**/TimeUnit TIME_UNIT = TimeUnit.MILLISECONDS;/*** 限制时间 单位:毫秒**/long time() default 1000;/*** 限制时间内允许请求的次数**/int count() default 1;}
3:AOP切面
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.harmonywisdom.requestaop.IsRepeatSubmit;
import com.harmonywisdom.response.ResponseResult;
import com.harmonywisdom.utils.HttpContextUtil;
import com.harmonywisdom.utils.RequestUtil;
import lombok.extern.slf4j.Slf4j;
import net.jodah.expiringmap.ExpirationPolicy;
import net.jodah.expiringmap.ExpiringMap;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.concurrent.ConcurrentHashMap;/*** @Description 重复提交切面* @Author WangKun* @Date 2024/5/22 16:57* @Version*/
@Slf4j
@Aspect
@Component
public class RepeatSubmitAspect {/*** 全局缓存**/private static final ConcurrentHashMap<String, ExpiringMap<String, Integer>> CE = new ConcurrentHashMap<>();/*** @Description 切点* @param irs* @Throws* @Return void* @Date 2024-05-28 15:41:56* @Author WangKun**/@Pointcut("@annotation(irs)")public void excludeService(IsRepeatSubmit irs) {}/*** @Description 切面* @param pjp* @param irs* @Throws* @Return java.lang.Object* @Date 2024-05-28 15:41:42* @Author WangKun**/@Around("excludeService(irs)")public Object doAround(ProceedingJoinPoint pjp, IsRepeatSubmit irs) throws Throwable {// 从上下文获取requestHttpServletRequest request = HttpContextUtil.getHttpServletRequest();MethodSignature signature = (MethodSignature) pjp.getSignature();Method method = signature.getMethod();Object[] args = pjp.getArgs();//获取request中数据(获取@RequestBody ,@RequestParam注解的参数)String data = RequestUtil.getParameter(request, method, args);JSONObject obj = JSON.parseObject(data);/** 以下根据自己的业务调整**///ipString ip = request.getRemoteAddr();//uriString uri = request.getRequestURI();//getOrDefault方法,没有该key则使用该keyExpiringMap<String, Integer> em = CE.getOrDefault(uri+"_"+ip, ExpiringMap.builder().variableExpiration().build());Integer count = em.getOrDefault(ip, 0);if (count >= irs.count()) {return ResponseResult.error(500,"请勿重复提交");} else if (count == 0) {em.put(ip, count + 1, ExpirationPolicy.CREATED, irs.time(), irs.TIME_UNIT);} else {em.put(ip, count + 1);}CE.put(uri+"_"+ip, em);return pjp.proceed();}}
RequestUtil.getParameter(request, method, args)
获取@RequestBody ,@RequestParam注解的参数-CSDN博客
HttpServletRequest request = HttpContextUtil.getHttpServletRequest();
Spring 获取http上下文-CSDN博客
相关文章:
Spring控制重复请求
通过AOP拦截所有请求,控制在规定时间内请求次数。 1:添加maven <dependency><groupId>net.jodah</groupId><artifactId>expiringmap</artifactId><version>0.5.10</version> </dependency> 2&#x…...
AWS安全性身份和合规性之Key Management Service(KMS)
AWS Key Management Service(KMS)是一项用于创建和管理加密密钥的托管服务,可帮助客户保护其数据的安全性和机密性。 比如一家医疗保健公司需要在AWS上存储敏感的病人健康数据,需要对数据进行加密以确保数据的机密性。他们使用AW…...
esp32 固件备份 固件恢复
首先是固件备份,这个在产品的工程管理中还是相当重要的。由于工具链的更新(工具版本),以及板子或其上物料的变更(硬件版本),或者新的库的导入或原有库的删除,PCBA是分分钟有可能死给…...
linux开发之设备树四、设备树中断节点
中断节点 这里是由原厂的BSP工程师写的一部分 在CPU的外部有一个GIC控制器,外设会连接在GIC控制器上 设备树是对硬件进行描述的,所以设备树会对CPU进行描述,也要对GIC 控制器进行描述,这部分的代码由原厂的BSP工程师进行编写&…...
基于STM32实现智能楼宇对讲系统
目录 引言环境准备智能楼宇对讲系统基础代码示例:实现智能楼宇对讲系统 音频输入和输出按键控制显示屏和用户界面网络通信应用场景:楼宇安防与智能家居问题解决方案与优化收尾与总结 1. 引言 本教程将详细介绍如何在STM32嵌入式系统中使用C语言实现智能…...
面试专区|【DevOps-46道DevOps高频题整理(附答案背诵版)】
简述什么是 DevOps工作流程 ? DevOps工作流程是一种将开发和运维团队紧密结合起来的方法,旨在实现软件开发和交付的高效性和可靠性。它强调自动化和持续集成,以便频繁地进行软件交付和部署。 DevOps工作流程通常包括以下阶段: …...
算法基础之台阶-Nim游戏
台阶-Nim游戏 核心思想:博弈论 可以看作第i阶台阶上有i个含有i个石子的堆这样所有台阶上一共n!个堆就变成了经典Nim优化:发现偶数阶台阶上2n堆异或 0 , 奇数阶台阶异或 原本石子数量 因此 当遍历到奇数阶时异或一下就行 #include <iostream>…...
VUE3注册指令的方法
指令注册只能全局指令和选项式页面指令,composition api没有页面指令 选项式页面指令 <template><div class"home"><h3>自定义指令</h3><div class"from"><el-input type"text" v-focus v-model"name&q…...
【Python】 Python 字典查询:‘has_key()‘ 方法与 ‘in‘ 关键字的比较
基本原理 在 Python 中,字典(dict)是一种非常常用的数据结构,用于存储键值对。字典的查询操作是编程中常见的任务之一。在 Python 2.x 版本中,has_key() 方法被用来检查字典中是否存在某个键。然而,在 Pyt…...
IDEA通过tomcat运行注意事项
配置run--》edit configurations 以下的A B部分要保持一致 A和B的路径要保持一致...
Unity Hub 添加模块报错 Validation Failed 的解决办法
提供两种方法,请自行选择其中一种。 在C:\Windows\System32\drivers\etc\hosts中添加下面的内容并保存后,完全关闭Unity Hub并重新打开,再次尝试下载刚刚失败的模块。 127.0.0.1 public-cdn.cloud.unity3d.com 127.0.0.1 public-cdn.cloud.…...
软件功能测试的类型和流程分享
在现代社会,软件已经成为人们生活中不可或缺的一部分,而在软件的开发过程中,功能测试是不可或缺的环节。软件功能测试指的是对软件系统的功能进行检查和验证,以确保软件在各种情况下能够正常运行,并且能够按照用户需求…...
【C语言】atoi函数的使用及模拟实现
atoi (ascii to integer),是把参数 str 所指向的字符串转换为一个整数(int类型)的库函数。 使用场景 引子: 有兴趣的朋友可以听我逐句翻译一下cpluscplus.com里的这段解释(要考六级了练一下): …...
Golang:使用bndr/gotabulate实现美观的打印表格数据
bndr/gotabulate 可以使用 Go 语言简单、美观的打印表格数据 文档 https://pkg.go.dev/github.com/bndr/gotabulatehttps://github.com/bndr/gotabulate 安装 go get github.com/bndr/gotabulate代码示例 package mainimport ("fmt""github.com/bndr/gotab…...
充电宝哪款好用?什么牌子充电宝耐用?充电宝选购要点总结
随着科技的飞速发展,充电宝已成为现代生活的必备之物。无论是日常通勤、旅行出差,还是在紧急情况下,充电宝都能为我们的电子设备提供可靠的电力支持。然而,面对市场上众多品牌和型号的充电宝,如何选择一款性价比高的充…...
【启程Golang之旅】基本变量与类型讲解
欢迎来到Golang的世界!在当今快节奏的软件开发领域,选择一种高效、简洁的编程语言至关重要。而在这方面,Golang(又称Go)无疑是一个备受瞩目的选择。在本文中,带领您探索Golang的世界,一步步地了…...
使用docker部署项目
一、docker私有镜像仓库 1、docker私有镜像仓库 库(Repository)是集中存放镜像的地方,又分为公共镜像和私有仓库。 当我们执行docker pull xxx的时候,它实际上是从registry.docker.com这个地址去查找,这就是Docker公…...
智慧林业云巡平台 客户端和移动端(支持语音和视频)自动定位巡护,后端离线路线监测
目前现状 无法客观、方便地掌握护林员的到位情况,因而无法有效地保证巡护人员按计划要求,按时按周期对所负责的林区开展巡护,使巡护工作的质量得不到保证。遇到火情、乱砍滥伐等灾情时无法及时上报处理,现场状况、位置等信息描述…...
【最优化方法】实验三 无约束最优化方法的MATLAB实现
实验的目的和要求:通过本次实验使学生进一步熟悉掌握使用MATLAB软件,并能利用该软件进行无约束最优化方法的计算。 实验内容: 1、最速下降法的MATLAB实现 2、牛顿法的MATLAB实现 3、共轭梯度法的MATLAB…...
kafka-偏移量图解
生产者偏移量:生产者发送消息时写入到哪个位置(主题的每个分区会存储一个 leo 即将写入消息的偏移量),每次写完消息 leo 会 1 消费者偏移量:消费者从哪个位置开始消费消息,小于等于 leo,每个组…...
变量 varablie 声明- Rust 变量 let mut 声明与 C/C++ 变量声明对比分析
一、变量声明设计:let 与 mut 的哲学解析 Rust 采用 let 声明变量并通过 mut 显式标记可变性,这种设计体现了语言的核心哲学。以下是深度解析: 1.1 设计理念剖析 安全优先原则:默认不可变强制开发者明确声明意图 let x 5; …...
C++_核心编程_多态案例二-制作饮品
#include <iostream> #include <string> using namespace std;/*制作饮品的大致流程为:煮水 - 冲泡 - 倒入杯中 - 加入辅料 利用多态技术实现本案例,提供抽象制作饮品基类,提供子类制作咖啡和茶叶*//*基类*/ class AbstractDr…...
《Qt C++ 与 OpenCV:解锁视频播放程序设计的奥秘》
引言:探索视频播放程序设计之旅 在当今数字化时代,多媒体应用已渗透到我们生活的方方面面,从日常的视频娱乐到专业的视频监控、视频会议系统,视频播放程序作为多媒体应用的核心组成部分,扮演着至关重要的角色。无论是在个人电脑、移动设备还是智能电视等平台上,用户都期望…...
Cesium1.95中高性能加载1500个点
一、基本方式: 图标使用.png比.svg性能要好 <template><div id"cesiumContainer"></div><div class"toolbar"><button id"resetButton">重新生成点</button><span id"countDisplay&qu…...
Springcloud:Eureka 高可用集群搭建实战(服务注册与发现的底层原理与避坑指南)
引言:为什么 Eureka 依然是存量系统的核心? 尽管 Nacos 等新注册中心崛起,但金融、电力等保守行业仍有大量系统运行在 Eureka 上。理解其高可用设计与自我保护机制,是保障分布式系统稳定的必修课。本文将手把手带你搭建生产级 Eur…...
pikachu靶场通关笔记22-1 SQL注入05-1-insert注入(报错法)
目录 一、SQL注入 二、insert注入 三、报错型注入 四、updatexml函数 五、源码审计 六、insert渗透实战 1、渗透准备 2、获取数据库名database 3、获取表名table 4、获取列名column 5、获取字段 本系列为通过《pikachu靶场通关笔记》的SQL注入关卡(共10关࿰…...
Map相关知识
数据结构 二叉树 二叉树,顾名思义,每个节点最多有两个“叉”,也就是两个子节点,分别是左子 节点和右子节点。不过,二叉树并不要求每个节点都有两个子节点,有的节点只 有左子节点,有的节点只有…...
CMake控制VS2022项目文件分组
我们可以通过 CMake 控制源文件的组织结构,使它们在 VS 解决方案资源管理器中以“组”(Filter)的形式进行分类展示。 🎯 目标 通过 CMake 脚本将 .cpp、.h 等源文件分组显示在 Visual Studio 2022 的解决方案资源管理器中。 ✅ 支持的方法汇总(共4种) 方法描述是否推荐…...
重启Eureka集群中的节点,对已经注册的服务有什么影响
先看答案,如果正确地操作,重启Eureka集群中的节点,对已经注册的服务影响非常小,甚至可以做到无感知。 但如果操作不当,可能会引发短暂的服务发现问题。 下面我们从Eureka的核心工作原理来详细分析这个问题。 Eureka的…...
10-Oracle 23 ai Vector Search 概述和参数
一、Oracle AI Vector Search 概述 企业和个人都在尝试各种AI,使用客户端或是内部自己搭建集成大模型的终端,加速与大型语言模型(LLM)的结合,同时使用检索增强生成(Retrieval Augmented Generation &#…...
