写点什么

Springboot 实现防重复提交和防重复点击(附源码),java 高级编程实验一

用户头像
极客good
关注
发布于: 刚刚

测试用例 #


=========


Copypackage com.dalelyzou.preventrepeatsubmit.controller;


import com.dalelyzou.preventrepeatsubmit.PreventrepeatsubmitApplicationTests;


import com.dalelyzou.preventrepeatsubmit.service.AsyncFeginService;


import com.dalelyzou.preventrepeatsubmit.vo.RequestVo;


import org.junit.jupiter.api.Test;


import org.springframework.beans.factory.annotation.Autowired;


import java.io.IOException;


import java.util.concurrent.ExecutorService;


import java.util.concurrent.Executors;


/**


  • TestControllerTest

  • @description 防重复点击测试类

  • @author daleyzou

  • @date 2020 年 09 月 28 日 17:13

  • @version 1.3.1


*/


class TestControllerTest extends PreventrepeatsubmitApplicationTests {


@Autowired


AsyncFeginService asyncFeginService; @Test


public void thisIsTestLocation() throws IOException {


RequestVo requestVo = new RequestVo();


requestVo.setParam5("random");


ExecutorService executorService = Executors.newFixedThreadPool(4);


for (int i = 0; i <= 3; i++) {


executorService.execute(() -> { String kl = asyncFeginService.thisIsTestLocation(requestVo); System.err.println("收到响应:" + kl);


}); } System.in.read(); } @Test


public void thisIsTestBody() throws IOException {


RequestVo requestVo = new RequestVo();


requestVo.setParam5("special");


ExecutorService executorService = Executors.newFixedThreadPool(4);


for (int i = 0; i <= 3; i++) {


executorService.execute(() -> { String kl = asyncFeginService.thisIsTestBody(requestVo); System.err.println("收到响应:" + kl);


}); } System.in.read(); }}


定义一个注解 #


===========


Copypackage com.dalelyzou.preventrepeatsubmit.aspect;


import java.lang.annotation.ElementType;


import java.lang.annotation.Retention;


import java.lang.annotation.RetentionPolicy;


import java.lang.annotation.Target;


/**


  • NoRepeatSubmit

  • @description 重复点击的切面

  • @author daleyzou

  • @date 2020 年 09 月 23 日 14:35

  • @version 1.4.8


*/


@Target(ElementType.METHOD)


@Retention(RetentionPolicy.RUNTIME)


public @interface NoRepeatSubmit {


/**


  • 锁过期的时间

  • */


int seconds() default 5;


/**


  • 锁的位置

  • */


String location() default "NoRepeatSubmit";


/**


  • 要扫描的参数位置

  • */


int argIndex() default 0;


/**


  • 参数名称

  • */


String name() default "";


}


根据指定的注解定义一个切面,根据参数中的指定值来判断请求是否重复 #


=================================


Copypackage com.dalelyzou.preventrepeatsubmit.aspect;


import com.dalelyzou.preventrepeatsubmit.constant.RedisKey;


import com.dalelyzou.preventrepeatsubmit.service.LockService;


import com.dalelyzou.preventrepeatsubmit.vo.RsVo;


import com.google.common.collect.Maps;


import com.google.gson.Gson;


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.slf4j.Logger;


import org.slf4j.LoggerFactory;


import org.springframework.beans.factory.annotation.Autowired;


import org.springframework.stereotype.Component;


import org.springframework.util.StringUtils;


import java.lang.reflect.Field;


import java.util.Map;


@Aspect


@Component


public class NoRepeatSubmitAspect {


private static final Logger logger = LoggerFactory.getLogger(NoRepeatSubmitAspect.class);


private static Gson gson = new Gson();


private static final String SUFFIX = "SUFFIX";


@Autow


【一线大厂Java面试题解析+核心总结学习笔记+最新架构讲解视频+实战项目源码讲义】
浏览器打开:qq.cn.hn/FTf 免费领取
复制代码


ired


LockService lockService; /**


  • 横切点


*/


@Pointcut("@annotation(noRepeatSubmit)")


public void repeatPoint(NoRepeatSubmit noRepeatSubmit) {


} /**


  • 接收请求,并记录数据


*/


@Around(value = "repeatPoint(noRepeatSubmit)")


public Object doBefore(ProceedingJoinPoint joinPoint, NoRepeatSubmit noRepeatSubmit) {


String key = RedisKey.NO_REPEAT_LOCK_PREFIX + noRepeatSubmit.location();


Object[] args = joinPoint.getArgs();


String name = noRepeatSubmit.name();


int argIndex = noRepeatSubmit.argIndex(); String suffix;


if (StringUtils.isEmpty(name)) {


suffix = String.valueOf(args[argIndex]);


} else {


Map<String, Object> keyAndValue = getKeyAndValue(args[argIndex]);


Object valueObj = keyAndValue.get(name);


if (valueObj == null) {


suffix = SUFFIX; } else {


suffix = String.valueOf(valueObj);


} } key = key + ":" + suffix;


logger.info("==================================================");


for (Object arg : args) {


logger.info(gson.toJson(arg)); } logger.info("==================================================");


int seconds = noRepeatSubmit.seconds(); logger.info("lock key : " + key);


if (!lockService.isLock(key, seconds)) {


return RsVo.fail("操作过于频繁,请稍后重试");


} try {


Object proceed = joinPoint.proceed();


return proceed;


} catch (Throwable throwable) {


logger.error("运行业务代码出错", throwable);


throw new RuntimeException(throwable.getMessage());


} finally {


lockService.unLock(key); } } public static Map<String, Object> getKeyAndValue(Object obj) {


Map<String, Object> map = Maps.newHashMap();


// 得到类对象


Class userCla = (Class) obj.getClass();


/* 得到类中的所有属性集合 */


Field[] fs = userCla.getDeclaredFields();


for (int i = 0; i < fs.length; i++) {


Field f = fs[i];


// 设置些属性是可以访问的


f.setAccessible(true);


Object val = new Object();

用户头像

极客good

关注

还未添加个人签名 2021.03.18 加入

还未添加个人简介

评论

发布
暂无评论
Springboot实现防重复提交和防重复点击(附源码),java高级编程实验一