自定义spring拦截器
说明:
一些版本比较老的spring框架的,是通过继承HandlerInterceptorAdapter并重写preHandle()方法,和继承WebMvcConfigurerAdapter并重写 addInterceptors()方法来实现拦截器的,但是这两个类很久前就已经过时了,不推荐使用,推荐使用下面两个接口。
以接口接口限流进行具体的操作,自定义拦截器主要步骤就是两个:
1、实现HandlerInterceptor,并实现rpreHandle()前置处理方法
2、实现WebMvcConfigurer,并实现addInterceptors()增加拦截器方法,把自定义的拦截器增加到spring容器中
HandlerInterceptor拦截器处理器接口有三个接口
● preHandle:在业务处理器处理请求之前被调用。预处理,可以进行编码、安全控制、权限校验等处理;
● postHandle:在业务处理器处理请求执行完成后,生成视图之前执行。后处理(调用了Service并返回ModelAndView,但未进行页面渲染),有机会修改ModelAndView ;
● afterCompletion:在DispatcherServlet完全处理完请求后被调用,可用于清理资源等。返回处理(已经渲染了页面);
实操:
1、引入依赖
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<!--Redis依赖-->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
2、自定义接口访问注解
/**
* 接口访问限制枚举
* @author ppp
* @date 2023/2/14
*/
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface AccessLimit {/*** @return 访问最大次数*/int accessMaxTimes() default 60;/*** @return 时间*/long timeOut() default 1;/*** @return 时间单位*/TimeUnit timeUnit() default TimeUnit.MINUTES;
}
3、自定义拦截器配置
同时实现HandlerInterceptor,WebMvcConfigurer,实现preHandle()和addInterceptors()方法
/**
* 接口访问限制拦截器配置
* @author ppp
* @date 2023/2/14
*/
@Component
public class AccessLimitInterceptorConfig implements HandlerInterceptor, WebMvcConfigurer {private final static String KEY = "Redis_accessLimit_key";@AutowiredRedisTemplate redisTemplate;@AutowiredAccessLimitInterceptorConfig accessLimitInterceptorConfig;@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {//判断请求是否属于方法的请求if(handler instanceof HandlerMethod){HandlerMethod hm = (HandlerMethod) handler;//获取方法中的注解,看是否有该注解AccessLimit accessLimit = hm.getMethodAnnotation(AccessLimit.class);if(accessLimit == null){return true;}int accessMaxTimes = accessLimit.accessMaxTimes();long timeOut = accessLimit.timeOut();TimeUnit timeUnit = accessLimit.timeUnit();// 如果redis不存在或已经过期Long expire =redisTemplate.opsForValue().getOperations().getExpire(KEY);if (!redisTemplate.hasKey(KEY) || Objects.requireNonNull(expire).intValue() < 0) {redisTemplate.opsForValue().set(KEY, 1, timeOut, timeUnit);} else {long increment = redisTemplate.opsForValue().increment(KEY).intValue();if (increment > accessMaxTimes) {throw new RuntimeException("访问已经超过最大值: " + accessMaxTimes);}}}return true;}@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(accessLimitInterceptorConfig);}
}
4、配置redis
/*** Redis管理配置*/
@Configuration
public class RedisConfigurer {/*** 设置 redisTemplate 的序列化设置** @param redisConnectionFactory* @return*/@Beanpublic RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {RedisTemplate<Object, Object> template = new RedisTemplate<>();template.setConnectionFactory(redisConnectionFactory);GenericToStringSerializer genericToStringSerializer = new GenericToStringSerializer(Object.class);template.setValueSerializer(genericToStringSerializer);template.setKeySerializer(new StringRedisSerializer());template.setHashKeySerializer(new StringRedisSerializer(Charset.forName("UTF-8")));template.setHashValueSerializer(new StringRedisSerializer(Charset.forName("UTF-8")));template.afterPropertiesSet();return template;}@Beanpublic CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {return new RedisCacheManager(RedisCacheWriter.nonLockingRedisCacheWriter(redisConnectionFactory),this.getRedisCacheConfigurationWithTtl(24 * 60 * 60), // 默认策略,未配置的 key 会使用这个this.getRedisCacheConfigurationMap() // 指定 key 策略);}private Map<String, RedisCacheConfiguration> getRedisCacheConfigurationMap() {Map<String, RedisCacheConfiguration> redisCacheConfigurationMap = new HashMap<>();return redisCacheConfigurationMap;}private RedisCacheConfiguration getRedisCacheConfigurationWithTtl(Integer seconds) {RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofSeconds(seconds));return redisCacheConfiguration;}
}
5、使用
/*** 一分钟内最多请求10次* @param content*/
@AccessLimit(accessMaxTimes = 10, timeOut = 1, timeUnit = TimeUnit.MINUTES)
@GetMapping("/sendEvent")
public void sendEvent(@RequestParam String content) {testService.send(content);
}
相关文章:
自定义spring拦截器
说明: 一些版本比较老的spring框架的,是通过继承HandlerInterceptorAdapter并重写preHandle()方法,和继承WebMvcConfigurerAdapter并重写 addInterceptors()方法来实现拦截器的,但是这两个类很久前就已经过时了,不推荐…...
今天正式上线!虹科汽车免拆诊断云展厅:感受精准修车魅力,畅享汽修领先技术
『虹科汽车免拆诊断云展厅』 2月15日正式上线! 在这里,您可以参观了解: 虹科Pico汽车示波器产品模型 全流程专业讲解的视频资料 产品功能和应用场景 全面详细的产品手册 还有虹科首席技术工程师在线连麦答疑!!…...
4.数据类型-字符串【Python】
文章目录字符串索引切片转义字符格式化符号f-string字符串操作判断&检测转换剪切&填充拼接统计格式转化练习字符串 字符串是 Python 中最常用的数据类型。可以使用单引号,双引号,3对双引号创建一个字符串。Python 中没有单独的字符类型 char…...
搞量化先搞数(上):A股股票列表免费抓取实战
到了这一步,我们学习了基础的爬虫请求库urllib和requests,尤其是后者,强大且易用,极其适合新手使用。那么今天我们就找一个相对简单的案例,来看一下如何在实战中应用爬虫技能。 相信很多朋友都对股票感兴趣,甚至有些朋友想要通过量化研究来获得超额收益。然而,想要进行…...
SpringCloud-负载均衡Ribbon
一、配置使用1、添加依赖(该依赖包含在eureka-client依赖中)<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-ribbon</artifactId></dependency>2、在RestTemp…...
Linux入门篇(二)
Linux前言链接文件符号链接(软链接)硬链接shellshell 的类型shell的父子关系理解外部命令和内建命令外部命令内建命令Linux环境变量PATH环境变量前言 在这一章,我对Linux中有关shell较为深入的理解和环境变量方面知识的一个记录。同时&#x…...
第四部分:特殊用途的句子——第三章:虚拟
虚拟语气 1、什么是虚拟? 虚拟就是非真实。换句话说,这事不是真的,这事不太可能成真,非真实,就是虚拟 2、怎么表示虚拟? 英语是一个典型的形式来补充内容的语言,若要表达虚拟,只…...
Java中如何获取泛型类型信息
文章目录声明侧泛型使用侧泛型获取泛型类型相关方法1. Class类的泛型方法2. Field类的泛型方法3. Method类的泛型方法4. ParameterizedType类获取声明侧的泛型类型信息获取使用侧的泛型类型信息匿名内部类实现获取使用侧的泛型类型根据使用泛型位置的不同可以分为:声…...
【云原生】centos7搭建安装k8s集群 v1.25版本详细教程实战
文章目录前言一. 实验环境二. k8s 的介绍三 . k8s的安装3.1 搭建实验环境3.1.1 硬件层面的要求3.1.2 软件层面环境配置3.2 docker的安装3.2.1 搭建docker3.2.2 部署 cri-dockerd3.3 部署k8s3.3.1 配置添加阿里云的yum源3.3.2 安装kubeadm kubelet kubectl3.3.3 k8s-master节点初…...
c语言指针
指针 指针是存放地址的变量,也可以说指针地址。 对于定义p(这里的话,只是定义,说明p是指针),p作为一个指针去指向存放数据的位置,而p意思是取(p指向的内存位置的数据)&…...
5.33 综合案例2.0 -ESP32拍照上传阿里云OSS
综合案例2.0 - ESP32拍照上传阿里云OSS案例说明连线功能实现1.阿里云平台连接2.OSS对象存储服务3.ESP32-CAM开发环境4.代码ESP32-CAM开发板代码HaaS506开发板代码测试数据转图片方法案例说明 使用ESP32拍照,将照片数据上传阿里云OSS(通过4G网络上传)。 …...
java无重复字符的最长子串
给定一个字符串 s ,请你找出其中不含有重复字符的 最长子串 的长度。 示例 1: 输入: s “abcabcbb” 输出: 3 解释: 因为无重复字符的最长子串是 “abc”,所以其长度为 3。 示例 2: 输入: s “bbbbb” 输出: 1 解释: 因为无重复字符的最长子串是 “…...
测试用例设计工作中的应用
1. 等价类划分 常见的软件测试面试题划分等价类: 等价类是指某个输入域的子集合.在该子集合中,各个输入数据对于揭露程序中的错误都是等效的.并合理地假定:测试某等价类的代表值就等于对这一类其它值的测试.因此,可以把全部输入数据合理划分为假设干等价类,在每一个等价类中取一…...
leetcode 困难 —— 数字 1 的个数(简单逻辑题)
(害,做题是真的慢,这面试给我这题我估计就傻了) 题目: 给定一个整数 n,计算所有小于等于 n 的非负整数中数字 1 出现的个数。 题解: 首先看看整数范围 0 < n < 10^9 不能遍历࿰…...
关于JSON
<!DOCTYPE html> <html> <head> <meta charset"utf-8"> <title></title> </head> <body> <script> /* 1、JSON的英文全称:Java…...
Apifox-接口调用、自动化测试工具
Apifox简介 Apifox 的定位是Postman Swagger Mock JMeter,具有API文档管理、API调试、API Mock、API 自动化测试等功能。可以通过一种工具解决之前使用多种工具的数据同步问题。高效、及时、准确! 安装 Apifox的安装非常方便,直接下载安…...
Vue一个项目兼容每个省份的个性化需求
开发环境及打包指令 后拼上省份区划"serve:henan": "yarn && vue-cli-service serve -o --encryptSM2 --zone41","serve:hunan": "yarn && vue-cli-service serve -o --encryptSM2 --zone43","serve:guizhou&quo…...
npm install报错 npm ERR! 的解决办法
以下是四种常见的npm ERR及解决方式错误一、npm ERR! A complete log of this run can be found in:npm ERR!C:\Users\nanyi\AppData\Roaming\npm-cache_logs\2021-09-17T08_58_23_413Z-debug.l查看错误日志,错误日志就在上面展示的C:\Users…这里如果发现错误日志里…...
echarts修改饼图,环形图的圆环宽度,大小
echarts修改环形图的圆环宽度,大小 环形图圆环的大小需要通过series-pie. radius属性来修改 radius 饼图的半径。 Array.<number|string>:数组的第一项是内半径,第二项是外半径。每一项遵从上述 number string 的描述。 把数组的第…...
小白系列Vite-Vue3-TypeScript:010-封装svg
上一篇我们介绍了ViteVue3TypeScript项目中mockjs的安装和配置i。本篇我们来介绍封装SVG图标组件。svg特征Preloading所有图标都是在项目运行时生成的,只需要操作一次dom即可。高性能内置缓存,仅在文件被修改时才会重新生成。安装插件vite-plugin-svg-ic…...
卷严重、难度高、激励少,如何适应空投市场新变化
自从空投交互从2020年开始之后,不少人都开始加入到空投交互的行列中,一些项目也因为“格局”的因素,在项目正式上线前都会给早期参与者空投代币,以此吸引大家的关注。但是在越来越多的人加入到撸空投行列之中后,现在整…...
基于Java与JSP的文件上传和下载
概念 当用户在前端页面点击文件上传后,用户上传的文件数据提交给服务器端,实现保存。 文件上传步骤 提交方式: 提供form表单,method必须是post。因为post请求无数据限制。 <form method"post"></form>…...
Gromacs中的g_mmpbsa计算带电底物与蛋白的结合能不准确
g_mmpbsa计算带电底物与蛋白的结合能总是不准确 TOC 在做的两个项目中,利用g_mmpbsa计算带电底物与蛋白的结合能结果非常不可靠,底物带两个硫酸根离子,g_mmpbsa在计算带电的底物与酶的结合能时总是不准确,因此后续若底物带电&…...
【mmrotate】旋转目标检测之训练DOTA数据集
every blog every motto: You can do more than you think. https://blog.csdn.net/weixin_39190382?typeblog 0. 前言 mmrotate训练DOTA数据集记录 1. 正文 1.1 数据准备 数据介绍部分,参考DOTA数据介绍,官方提供了裁剪工具development kit。这里…...
图基本概念
图:顶点和边的集合。无向图:每条边都是无方向的有向图:每条边都是有方向的完全图:任意两个点都有一条边相连稀疏图:有很少边或弧的图稠密图:有较多边或弧的图网:边/弧带权的图邻接:有…...
机器学习基础
一、基本概念 1 学习的概念 1975年图灵奖获得者、1978年诺贝尔经济学奖获得者、著名学者赫伯特.西蒙 (Herbert Simon) 曾下过一个定义: 如果一个系统,能够通过执行某个过程,就此改进了它的性能,那么这个过程就是学习.由此可看出,…...
FreeRTOS-Tickless低功耗模式 | FreeRTOS十四
目录 说明: 一、低功耗模式简介 1.1、STM32低功耗模式 二、Tickless模式 2.1、Tickless模式如何功耗 2.2、Tickless模式设计思想 2.3、为了降低功耗,又不影响系统运行,怎么能做到呢? 三、Tickless模式修改配置 3.1、配置…...
实现了统一消息中心的微服务基础框架 JVS,快点赞收藏
一、开源项目简介基于JVS(基于spring cloud封装)的基础开源框架,实现了基于多对多租户能力的管理系统。二、基础框架实现功能支持数据管理支持分布式定时任务支持分布式日志采集支持系统监控支持动态配置中心支持模板消息支持链路跟踪支持邮件…...
VMware 安装 OpenWrt 旁路由并配置 PassWall
1、准备 OpenWrt 镜像包 我已经转好了 vmdk 格式的,更多的可以去恩山论坛下载 OpenWrtvmdk格式-虚拟化文档类资源-CSDN下载 也可以在这个平台在线定制 OpenWrt固件下载与在线定制编译 2、网络选择 NAT 模式 3、创建虚拟机,选择自定义方式 4、一直下…...
R语言GD包地理探测器分析时报错、得不到结果等情况的解决方案
本文介绍在利用R语言的GD包,实现自变量最优离散化方法选取与执行、地理探测器(Geodetector)操作时,出现各类报错信息、长时间得不到结果等情况的解决方案。 在之前的文章R语言GD包基于栅格图像实现地理探测器与连续参数的自动离散…...
行业网站怎么推广/留号码的广告网站不需要验证码
假期 # 生活 # 水文 咱们继续假期第三天的日常更文,没看上篇的铁子们我把地址贴在下面。 点我 虽然是假期,但我规划已久的睡懒觉流程却是一直执行不下去。这不今天早上八点我就起床了,当然起的早不是为了“卷”,而是吃早餐。说出…...
b2b电子商务网站分类/seo是哪个英文的简写
引言概率密度期望和协方差 Expectations and covariances1加权平均值2 多变量权重3 条件期望4 函数方差5 协方差 Bayesian Probability5高斯分布重回多项式拟合1理解误差函数2 理解规则化 贝叶斯曲线拟合 主要讲解了贝叶斯概率与统计派概率的不同。概率论,决策论&am…...
企业网站建设与推广范文/广州seo排名外包
关于月亮的十大未解之谜至今仍然无法解开,月亮未解之谜是人类科学的一大探索,古往今来,为了探索月亮的奥秘,人类付出了巨大的努力。月亮的十大未解之谜你都有了解过吗?今天小编给大家准备了月亮的十大未解之谜。Ten qu…...
ppt做的比较好的网站/网页制作的软件
我们常见的执行js代码都是放入到HTML引入后然后通过HTML文件来执行胡查看代码,显然这是比较麻烦的事情, 如果你的电脑里面安装了node.js,你可以使用node来直接使用node来运行你想要运行的js文件, 具体的操作如图所示:…...
怎么做没有后台程序的网站/企业如何做网站
Collection:是集合的顶层接口,它的子体系有重复的,有唯一的,有有序的,有无序的。 Collection的功能概述: 1.添加功能:boolean add(Object obj):添加一个元素boolean addAll(Collection c):添加…...
环境设计排版素材网站/百度网站怎样优化排名
转载自:http://www.cocoachina.com/gamedev/misc/2011/0627/2981.html 游戏一直是 App Store 应用里最热门、最赚钱的一大分类,iOS 游戏强调创意和趣味性的特点也让国内开发团队有更多一鸣惊人的机会。针对市场、玩家、开发商、成功案例等游戏开发要素&a…...