IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> SpringBoot防止表单重复提交+token+表单内容 -> 正文阅读

[Java知识库]SpringBoot防止表单重复提交+token+表单内容

作者:recommend-item-box type_blog clearfix

第一步: 编写自定义注解.

编写自定义注解.
/**
 * @功能描述 防止重复提交标记注解
 */
@Inherited
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface NoRepeatSubmit {
    /**
     * 重复统计时长
     * @return
     */
    long time() default 5L;
}

第二步:接口防重复切面实现.

接口防重复切面实现.
/**
 * 接口防重复切面
 */
@Aspect
@Component
public class NoRepeatSubmitAop {
    @Resource
    private RedisService redisCache;

    private static final String JWT_TOKEN_KEY = "authorization";  // 这里是 token 的前缀
    
    @Pointcut("@annotation(com.SpringBoot.annotation.NoRepeatSubmit)") // 这里是自定义注解的位置 如: 我自定义注解的位置在 com.SpringBoot.annotation
    public void serviceNoRepeat() {
    }
    @Around("serviceNoRepeat()")
    public Object around(ProceedingJoinPoint pjp) throws Throwable {
        HttpServletRequest request = ServletUtils.getRequest();
        String jwtToken = request.getHeader(JWT_TOKEN_KEY);
        Map<String, Object> map = new HashMap<String, Object>();
        Object[] values = pjp.getArgs();
        String[] names = ((CodeSignature) pjp.getSignature()).getParameterNames();
        for (int i = 0; i < names.length; i++) {
            map.put(names[i], values[i]);
        }
        String body = JSONObject.toJSONString(map);
        String key = Md5Util.md5(jwtToken+request.getMethod()+request.getRequestURI()+body);
        if (redisCache.getCacheObject(key) == null) {
            try {
                Object o = pjp.proceed();
                MethodSignature signature = (MethodSignature) pjp.getSignature();
                NoRepeatSubmit noRepeatSubmit = signature.getMethod().getAnnotation(NoRepeatSubmit.class);
                // 默认1秒内统一用户同一个地址同一个参数,视为重复提交
                //redisCache.setCacheObject(key,jwtToken, noRepeatSubmit.time(),TimeUnit.SECONDS);
                redisCache.setCacheObject(key,body,noRepeatSubmit.time(),TimeUnit.SECONDS);
                return o;
            }catch (Exception e){
                throw new ServiceException(e.getMessage());
            }
        } else {
            throw new ServiceException("重复提交,请稍后再试");
        }
    }

}

md5 工具类
public class Md5Util {

    private static final Logger log = LoggerFactory.getLogger(Md5Util.class);

    /***
     * MD5加盐加密
     * @param string
     * @param salt
     * @return
     */
    public static String MD5Util(String string, String salt) {
        return getMD5_32(string + salt);
    }

    /***
     * this is getMD5_32 加密后英文是大写
     * @param src
     * @return
     */
    public static String getMD5_32(String src) {
        try {
            StringBuffer stringBuffer = new StringBuffer();
            char[] chars = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'};
            MessageDigest md = MessageDigest.getInstance("MD5");
            byte[] data = md.digest(src.getBytes());
            //遍历字节数组,取出高四位和低四位对应的字符,最终会得到长度为32的字符串
            for (byte b : data) {
                //高4位
                stringBuffer.append(chars[(b >> 4) & 0x0F]);
                //低4位
                stringBuffer.append(chars[b & 0x0F]);
            }
            return stringBuffer.toString();
        } catch (Exception e) {
            // TODO: handle exception
            log.error("[大写MD5生成error]");
        }
        return null;
    }

    /***
     * this is md5 加密后英文是小写 加密与getMD5_32算法一样
     * @param str
     * @return
     */
    public static String md5(String str) {
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            md.update(str.getBytes());
            byte b[] = md.digest();

            int i;

            StringBuffer buf = new StringBuffer("");
            for (int offset = 0; offset < b.length; offset++) {
                i = b[offset];
                if (i < 0) {
                    i += 256;
                }
                if (i < 16) {
                    buf.append("0");
                }
                buf.append(Integer.toHexString(i));
            }
            str = buf.toString();
        } catch (Exception e) {
            log.error("[小写MD5生成error]");

        }
        return str;
    }

redis 这块代码比较简单…这里就省略了

接口防重复切面的代码中: ‘authorization’

在这里插入图片描述
请个各位大佬多指教

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-05-21 18:48:02  更:2022-05-21 18:51:06 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年4日历 -2024/4/17 3:05:18-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码