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

网友投稿 338 2022-08-14


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;

imhttp://port 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.reqhttp://uest.ServletRequestAttributes;

import java.util.concurrent.TimeUnit;

/**

* @Author Minco

* @Date 16:02 2020-08-13

* @Description aop解析注解

*/

@Aspect

@Component

public class NoRepeatSubmitAop {

private Log logger = LogFactory.getLog(getClass());

@Autowired

private 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 = {"unchecked", "rawtypes"})

public class RedisService {

@Autowired

public 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 boolean haskey(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 = "新增仓库调整单", notes = "")

public R insert(@RequestBody Cktzd cktzd) {

System.out.println(jsON.toJSONString(cktzd));

return R.error("测试阶段!");

}

测试结果:

第一次提交

在不间隔15就继续点

不间断的点,只要2次点击之间没有超过15秒,都会抛出请勿重复请求。直到2次点击之间间隔足够才能正常请求!


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:Springboot+Mybatis实现分页加条件查询功能
下一篇:Java负载均衡算法实现之轮询和加权轮询
相关文章

 发表评论

暂时没有评论,来抢沙发吧~