注解
@Documented
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface RepeatSubmitAnno {
/**
* 鎖定時間
* @return 鎖定時間击费,默認(rèn)是3 TimeUnit 默認(rèn)是秒
*/
long lockedTime() default 3;
/**
* 時間單位(時分秒等)
* @return 單位
*/
TimeUnit timeUnit() default TimeUnit.SECONDS;
}
AOP
/**
* 防重復(fù)提交切面類
*
* @author xy
* @date 2024-06-05
*/
@Aspect
@Component
public class RepeatSubmitAspect {
private Logger logger = LoggerFactory.getLogger(RepeatSubmitAspect.class);
@Resource
private RedisUtil redisUtil;
/**
* 切入點定義:指明要在什么樣的條件下才能被觸發(fā)
*
* @ Pointcut注解表達(dá)式, 通過特定的規(guī)則來篩選連接點, 就是Pointcut讹开,選中那幾個你想要的方法
* @ annotation:條件:當(dāng)執(zhí)行的方法上擁有指定的注解時生效
*/
@Pointcut("@annotation(com.zqcy.commons.anno.RepeatSubmitAnno)")
public void pointCut() {
}
/**
* 環(huán)繞通知猪狈,圍繞著方法執(zhí)行
*
* @ param pjp
* @ return
*/
@Around("pointCut()")
public Object around(ProceedingJoinPoint pjp) {
try {
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
assert attributes != null;
MethodSignature signature = (MethodSignature) pjp.getSignature();
// 被攔截的方法
Method method = signature.getMethod();
// 注解信息
RepeatSubmitAnno repeatSubmit = method.getAnnotation(RepeatSubmitAnno.class);
HttpServletRequest request = attributes.getRequest();
String key = "repeat_submit_";
String url = request.getRequestURI();
String ipAddress = request.getRemoteAddr();
String className = method.getDeclaringClass().getName();
String methodName = method.getName();
//基于IP 類名 方法名 和URL 生成唯一key
key = key + String.format("%s_%s_%s_%s", ipAddress, url, className, methodName);
// 如果緩存中有這個url視為重復(fù)提交
if (!redisUtil.hasKey(key) ) {
Object o = pjp.proceed();
redisUtil.setCacheSet(key,"",repeatSubmit.lockedTime(),repeatSubmit.timeUnit());
return o;
} else {
// logger.error("重復(fù)提交");
return "請勿短時間內(nèi)重復(fù)操作" ;
}
} catch (Throwable e) {
// e.printStackTrace();
logger.error("驗證重復(fù)提交時出現(xiàn)未知異常!");
return "驗證重復(fù)提交時出現(xiàn)未知異常!";
}
}
}
使用 :在需要的方法上添加
@RepeatSubmitAnno(lockedTime = 500,timeUnit = TimeUnit.MILLISECONDS)