当前位置: 首页 > news >正文

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";
    }

相关文章:

  • deepseek帮我设计物理量采集单片机口保护电路方案
  • 什么是Baklib云内容中台?
  • chrome V3插件开发,调用 chrome.action.setIcon,提示路径找不到
  • 操作系统2.4
  • 虚拟环境下Python调用C++开发的dll如何联调?一文解答!(Python开发环境PyCharm,C++开发环境Visual Studio)
  • Python JSON的深度解析:从基础到应用
  • 【用deepseek实现快递查询】快递物流查询-快递查询-快递查询-快递物流查询-快递物流轨迹查询-快递物流查询接口-快递查询-快递物流查询
  • Flask实现高效日志记录模块
  • DeepSeek与ChatGPT:AI语言模型的全面技术解析与对比
  • linux进程间通信的posix消息队列应用记录
  • Go日期时间处理工具Carbon
  • python 如何获取文件的keys
  • 【C语言】C语言 哈夫曼编码传输(源码+数据文件)【独一无二】
  • 2025年人工智能与教育系统国际学术会议(ICAIES 2025)
  • postgres源码学习之简单sql查询
  • Java开发实习面试笔试题(含答案)
  • 【信息系统项目管理师】专业英语重点词汇大汇总
  • 数字电路中的焊接技术
  • MyBatis XML映射文件中的批量插入和更新
  • 模电知识点总结(2)
  • 人民日报钟声:通过平等对话协商解决分歧的重要一步
  • 时隔近4年再出征!长三丙成功发射通信技术试验卫星十九号
  • 专访|日本驻华大使金杉宪治:对美、对华外交必须在保持平衡的基础上稳步推进
  • 牛市早报|中美经贸高层会谈达成重要共识,取得实质性进展
  • “影像上海”中的自媒体影像特展:无论何时,影像都需要空间
  • 本周看啥|喜欢二次元的观众,去电影院吧