SpringBoot项目中接口防刷怎么实现
发表于:2025-02-06 作者:千家信息网编辑
千家信息网最后更新 2025年02月06日,本篇内容主要讲解"SpringBoot项目中接口防刷怎么实现",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"SpringBoot项目中接口防刷怎么实现"吧!
千家信息网最后更新 2025年02月06日SpringBoot项目中接口防刷怎么实现
本篇内容主要讲解"SpringBoot项目中接口防刷怎么实现",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"SpringBoot项目中接口防刷怎么实现"吧!
一、自定义注解
import java.lang.annotation.Retention;import java.lang.annotation.Target;import static java.lang.annotation.ElementType.METHOD;import static java.lang.annotation.RetentionPolicy.RUNTIME;/** * @author Yang * @version 1.0 * @date 2021/2/22 10:28 */@Retention(RUNTIME)@Target(METHOD)public @interface AccessLimit { int seconds(); int maxCount(); boolean needLogin() default true;}
二、定义拦截器
import com.alibaba.fastjson.JSON;import com.mengxiangnongfu.payment.annotation.AccessLimit;import com.mengxiangnongfu.payment.commons.RedisUtil;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.context.annotation.Configuration;import org.springframework.stereotype.Component;import org.springframework.web.method.HandlerMethod;import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.OutputStream;/** * @author Yang * @version 1.0 * @date 2021/2/22 10:29 */@Componentpublic class FangshuaInterceptor extends HandlerInterceptorAdapter { @Autowired private RedisUtil redisUtil; @Override public 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 seconds = accessLimit.seconds(); int maxCount = accessLimit.maxCount(); boolean login = accessLimit.needLogin(); String key = "1"; //如果需要登录 if (login) { //获取登录的session进行判断 //..... key += "" + "1"; //这里假设用户是1,项目中是动态获取的userId } //从redis中获取用户访问的次数 Integer count = (Integer) redisUtil.get(key); if (count == null) { //第一次访问 redisUtil.set(key, 1, seconds); } else if (count < maxCount) { //加1 redisUtil.incr(key, 1); } else { //超出访问次数 render(response, "请求过于频繁~请稍后再试~"); //这里的CodeMsg是一个返回参数 return false; } } return true; } private void render(HttpServletResponse response, String cm) throws Exception { response.setContentType("application/json;charset=UTF-8"); OutputStream out = response.getOutputStream(); String str = JSON.toJSONString(cm); out.write(str.getBytes("UTF-8")); out.flush(); out.close(); }}
三、Redis工具类
import lombok.extern.slf4j.Slf4j;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.data.redis.core.RedisTemplate;import org.springframework.stereotype.Component;import org.springframework.util.CollectionUtils;import java.util.List;import java.util.Map;import java.util.Set;import java.util.concurrent.TimeUnit;/** * @author Yang * @version 1.0 * @date 2020/11/29 17:06 */@Component@Slf4jpublic class RedisUtil { @Autowired RedisTemplate redisTemplate; // =============================common============================ /** * 指定缓存失效时间 * * @param key 键 * @param time 时间(秒) * @return */ public boolean expire(String key, long time) { try { if (time > 0) { redisTemplate.expire(key, time, TimeUnit.SECONDS); } return true; } catch (Exception e) { log.error(key, e); return false; } } /** * 根据key 获取过期时间 * * @param key 键 不能为null * @return 时间(秒) 返回0代表为永久有效 */ public long getExpire(String key) { return redisTemplate.getExpire(key, TimeUnit.SECONDS); } /** * 判断key是否存在 * * @param key 键 * @return true 存在 false不存在 */ public boolean hasKey(String key) { try { return redisTemplate.hasKey(key); } catch (Exception e) { log.error(key, e); return false; } } /** * 删除缓存 * * @param key 可以传一个值 或多个 */ @SuppressWarnings("unchecked") public void del(String... key) { if (key != null && key.length > 0) { if (key.length == 1) { redisTemplate.delete(key[0]); } else { redisTemplate.delete(CollectionUtils.arrayToList(key)); } } } // ============================String============================= /** * 普通缓存获取 * * @param key 键 * @return 值 */ public Object get(String key) { return key == null ? null : redisTemplate.opsForValue().get(key); } /** * 普通缓存放入 * * @param key 键 * @param value 值 * @return true成功 false失败 */ public boolean set(String key, Object value) { try { redisTemplate.opsForValue().set(key, value); return true; } catch (Exception e) { log.error(key, e); return false; } } /** * 普通缓存放入并设置时间 * * @param key 键 * @param value 值 * @param time 时间(秒) time要大于0 如果time小于等于0 将设置无限期 * @return true成功 false 失败 */ public boolean set(String key, Object value, long time) { try { if (time > 0) { redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS); } else { set(key, value); } return true; } catch (Exception e) { log.error(key, e); return false; } } /** * 递增 适用场景: https://blog.csdn.net/y_y_y_k_k_k_k/article/details/79218254 高并发生成订单号,秒杀类的业务逻辑等。。 * * @param key 键 * @param delta 要增加几(大于0) * @return */ public long incr(String key, long delta) { if (delta < 0) { throw new RuntimeException("递增因子必须大于0"); } return redisTemplate.opsForValue().increment(key, delta); } /** * 递减 * * @param key 键 * @param delta 要减少几(小于0) * @return */ public long decr(String key, long delta) { if (delta < 0) { throw new RuntimeException("递减因子必须大于0"); } return redisTemplate.opsForValue().increment(key, -delta); } // ================================Map================================= /** * HashGet * * @param key 键 不能为null * @param item 项 不能为null * @return 值 */ public Object hget(String key, String item) { return redisTemplate.opsForHash().get(key, item); } /** * 获取hashKey对应的所有键值 * * @param key 键 * @return 对应的多个键值 */ public Map
四、POM文件
org.springframework.boot spring-boot-starter-aop org.springframework.boot spring-boot-starter-data-redis
记得配置redis的连接
在需要拦截的地方加入注解即可@AccessLimit(seconds = 5, maxCount = 1, needLogin = false) seconds重置访问频率时间 maxCount 最多请求次数
到此,相信大家对"SpringBoot项目中接口防刷怎么实现"有了更深的了解,不妨来实际操作一番吧!这里是网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!
时间
缓存
多个
成功
个数
数据
项目
注解
索引
接口
普通
元素
内容
方法
次数
长度
查询
中放
代表
因子
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
信息网络安全考研选择学校
中学网络安全主题班会图片
红黑人口数据库2021绥化市
数据库没找到防火墙
北京赛伟网络技术有限公司
格尔木手机软件开发
网络安全意见建议征求书
天津现代化软件开发诚信服务
成都软件开发c语言的作用
重庆定制软件开发哪家好
早期的服务器系统
道尔道主机服务器
河流绘画软件开发
信息网络安全保密工作方案
广州软件开发公司被抓
来安县软件开发技术项目实训中心
网络安全怎么进大厂
上海信息软件开发定制要多少钱
嵌入式软件开发学啥
软件开发北京工资标准
服务器系统无法操作
网络安全审计日记
网络安全专业要先学吗
邻居网络技术
阿里云如何开启服务器安全组
北京自动化软件开发销售公司
软件开发电脑笔记本推荐
数据库 关系中的行称为
新吴区先进网络技术创造辉煌
网络技术公司营销策略