Java后端限制频繁请求和重复提交的实现

目录

  • 步骤一、写限制注解
  • 步骤二、解析注解
  • 步骤三、控制层注解使用
当前端按连续请求多次,请求过于频繁或者是多次重复提交数据,对系统或者是数据造成了一点的损害。
为了解决这个问题,下面介绍了一种简易的解决方法:

步骤一、写限制注解
import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * @Author Minco * @Date 16:04 2020-08-13 * @Description 不重复提交注解 */ @Target(ElementType.METHOD) // 作用到方法上@Retention(RetentionPolicy.RUNTIME) // 运行时有效public @interface NoRepeatSubmit { String name() default "name:"; }


步骤二、解析注解
import javax.servlet.http.HttpServletRequest; import com.hieasy.comm.core.domain.R; import com.hieasy.comm.redis.service.RedisService; import com.hieasy.system.util.TermUtil; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; import java.util.concurrent.TimeUnit; /** * @Author Minco * @Date 16:02 2020-08-13 * @Description aop解析注解 */ @Aspect@Componentpublic class NoRepeatSubmitAop { private Log logger = LogFactory.getLog(getClass()); @Autowiredprivate RedisService redisService; @Around("execution(* com.hieasy.*.controller.*.*Ctrl.*(..)) && @annotation(nrs)")public Object arround(ProceedingJoinPoint pjp, NoRepeatSubmit nrs) throws Throwable {ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); HttpServletRequest request = attributes.getRequest(); String key = TermUtil.getUserId() + "-" + request.getServletPath(); if ( !redisService.haskey(key) ) {// 如果缓存中有这个url视为重复提交Object o = pjp.proceed(); redisService.setCacheObject(key, 0, 15, TimeUnit.SECONDS); return o; } else {redisService.setCacheObject(key, 0, 15, TimeUnit.SECONDS); //点了同样的URL继续限制,直到2次点击中间间隔超过了限制return R.error("请勿重复提交或者操作过于频繁!"); }} }

import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.*; import org.springframework.stereotype.Component; import java.util.*; import java.util.concurrent.TimeUnit; /** * @Author Minco * @Date 13:55 2020-06-23 * @Description RedisService */@Component@SuppressWarnings(value = https://www.it610.com/article/{"unchecked", "rawtypes"})public class RedisService { @Autowiredpublic RedisTemplate redisTemplate; /*** 缓存基本的对象,Integer、String、实体类等** @param key缓存的键值* @param value 缓存的值* @return 缓存的对象*/public ValueOperations setCacheObject(String key, T value) {ValueOperations operation = redisTemplate.opsForValue(); operation.set(key, value); return operation; } /*** 缓存基本的对象,Integer、String、实体类等** @param key缓存的键值* @param value缓存的值* @param timeout时间* @param timeUnit 时间颗粒度* @return 缓存的对象*/public ValueOperations setCacheObject(String key, T value, Integer timeout, TimeUnit timeUnit) {ValueOperations operation = redisTemplate.opsForValue(); operation.set(key, value, timeout, timeUnit); return operation; } /*** 获得缓存的基本对象。** @param key 缓存键值* @return 缓存键值对应的数据*/public T getCacheObject(String key) {ValueOperations operation = redisTemplate.opsForValue(); return operation.get(key); } /*** 删除单个对象** @param key*/public void deleteObject(String key) {redisTemplate.delete(key); } /*** 删除集合对象** @param collection*/public void deleteObject(Collection collection) {redisTemplate.delete(collection); } /*** 缓存List数据** @param key缓存的键值* @param dataList 待缓存的List数据* @return 缓存的对象*/public ListOperations setCacheList(String key, List dataList) {ListOperations listOperation = redisTemplate.opsForList(); if (null != dataList) {int size = dataList.size(); for (int i = 0; i < size; i++) {listOperation.leftPush(key, dataList.get(i)); }}return listOperation; } /*** 获得缓存的list对象** @param key 缓存的键值* @return 缓存键值对应的数据*/public List getCacheList(String key) {List dataList = new ArrayList(); ListOperations listOperation = redisTemplate.opsForList(); Long size = listOperation.size(key); for (int i = 0; i < size; i++) {dataList.add(listOperation.index(key, i)); }return dataList; } /*** 缓存Set** @param key缓存键值* @param dataSet 缓存的数据* @return 缓存数据的对象*/public BoundSetOperations setCacheSet(String key, Set dataSet) {BoundSetOperations setOperation = redisTemplate.boundSetOps(key); Iterator it = dataSet.iterator(); while (it.hasNext()) {setOperation.add(it.next()); }return setOperation; } /*** 获得缓存的set** @param key* @return*/public Set getCacheSet(String key) {Set dataSet = new HashSet(); BoundSetOperations operation = redisTemplate.boundSetOps(key); dataSet = operation.members(); return dataSet; } /*** 缓存Map** @param key* @param dataMap* @return*/public HashOperations setCacheMap(String key, Map dataMap) {HashOperations hashOperations = redisTemplate.opsForHash(); if (null != dataMap) {for (Map.Entry entry : dataMap.entrySet()) {hashOperations.put(key, entry.getKey(), entry.getValue()); }}return hashOperations; } /*** 获得缓存的Map** @param key* @return*/public Map getCacheMap(String key) {Map map = redisTemplate.opsForHash().entries(key); return map; } /*** 获得缓存的基本对象列表** @param pattern 字符串前缀* @return 对象列表*/public Collection keys(String pattern) {return redisTemplate.keys(pattern); } /**** @param key* @return*/public booleanhaskey(String key){return redisTemplate.hasKey(key); } public Long getExpire(String key){return redisTemplate.getExpire(key); } public ValueOperations setBillObject(String key, List value) {ValueOperations operation = redisTemplate.opsForValue(); operation.set(key, (T) value); return operation; }/*** 缓存list** @param key缓存的键值* @param value缓存的值* @param timeout时间* @param timeUnit 时间颗粒度* @return 缓存的对象*/public ValueOperations setBillObject(String key, List value, Integer timeout, TimeUnit timeUnit) {ValueOperations operation = redisTemplate.opsForValue(); operation.set(key,(T)value, timeout, timeUnit); return operation; }/*** 缓存Map** @param key* @param dataMap* @return*/public HashOperations setCKdBillMap(String key, Map dataMap) {HashOperations hashOperations = redisTemplate.opsForHash(); if (null != dataMap) {for (Map.Entry entry : dataMap.entrySet()) {hashOperations.put(key, entry.getKey(), entry.getValue()); }}return hashOperations; }}


步骤三、控制层注解使用
@NoRepeatSubmit@PostMapping("insert")@OperLog(title = "仓库调整", businessType = BusinessType.INSERT)@ApiOperation(value = "https://www.it610.com/article/新增仓库调整单", notes = "")public R insert(@RequestBody Cktzd cktzd) {System.out.println(JSON.toJSONString(cktzd)); return R.error("测试阶段!"); }

测试结果:
第一次提交
Java后端限制频繁请求和重复提交的实现
文章图片

在不间隔15就继续点
Java后端限制频繁请求和重复提交的实现
文章图片

不间断的点,只要2次点击之间没有超过15秒,都会抛出请勿重复请求。直到2次点击之间间隔足够才能正常请求!
【Java后端限制频繁请求和重复提交的实现】到此这篇关于Java后端限制频繁请求和重复提交的实现的文章就介绍到这了,更多相关Java后端限制频繁请求内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

    推荐阅读