java防抖,防止表单重复提交,aop注解形式
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 防抖注解
*/
@Target(ElementType.METHOD) // 作用到方法上
@Retention(RetentionPolicy.RUNTIME) // 运行时有效
public @interface AntiShake {
// 默认过期时间3秒
int expire() default 3;
}
防抖切面
import jakarta.annotation.Resource;
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.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.lang.reflect.Method;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.concurrent.TimeUnit;
/**
* 防抖
*/
@Aspect
@Component
public class AntiShakeAop {
@Autowired
private RedisUtil redisUtil;
/**
* 切入点
*/
@Pointcut("@annotation(xx.xx.xx.xx.xx.AntiShake)")
public void pt() {
}
@Around("pt()")
public Object arround(ProceedingJoinPoint joinPoint) throws Throwable {
StringBuilder sb = new StringBuilder();
for (Object arg : joinPoint.getArgs()) {
if (arg != null) {
sb.append(arg.toString());
}
}
String paramHash = md5(sb.toString());
String key = "anti-shake:"+ joinPoint.getSignature().getName() + ":" + paramHash;
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod();
int expire = method.getAnnotation(AntiShake.class).expire();
// 如果缓存中有这个url视为重复提交
if (!redisUtil.hasKey(key)) {
//然后存入redis 并且设置倒计时
redisUtil.set(key, 0, expire, TimeUnit.SECONDS);
//返回结果
return joinPoint.proceed();
} else {
throw new RuntimeException("请勿重复提交或者操作过于频繁!");
}
}
private String md5(String input) {
try {
MessageDigest md = MessageDigest.getInstance("MD5");
byte[] messageDigest = md.digest(input.getBytes());
StringBuilder hexString = new StringBuilder();
for (byte b : messageDigest) {
String hex = Integer.toHexString(0xFF & b);
if (hex.length() == 1) hexString.append('0');
hexString.append(hex);
}
return hexString.toString();
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
}
}
}
用法
@AntiShake
@GetMapping("/test")
public String test(@RequestParam String name ) throws Exception {
log.info("防抖测试:{}", name);
Thread.sleep(10000);
return "success";
}