基于Redis 自定义注解和Aop防止form表单重复提交

7 篇文章 0 订阅

防止form表单重复提交

解决方案

1、 前端form表单加载的时候,去请求后端的生成formId的接口

2、 后端在生成formId接口将formId存储到缓存中,再返回给前端

3、 前端在form表单提交的时候在请求头中携带一个formId的参数,值为加载时获取到的formId

4、 后端基于AOP拦截请求,判断请求头是否携带formId,并通过删除操作,如果返回true表示该
formId存在,如果返回false 表示该formId不合法。(这里不使用select + delete 两步操作可能会发生并发)返回true
则执行方法 否则返回异常信息给前端。

后端实现

1、 自定义一个注解Form

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Form {
}

2、 在所有的form表单提交的方法上加上Form注解

    @RequestMapping(value = "commit")
    @Form
    public String commit() {
        return "success";
    }

3、 定义一个获取formId的接口

    @RequestMapping(value = "getFormId")
    public String getKey() {
        String key = UUID.randomUUID().toString();
        //将key存储到缓存中,有效期10分钟
        redisTools.save(key,key,10);
        return key;
    }

3、 定义一个切面,用来拦截所有被Form注解修饰的方法

这里我做的比较简单,因为是demo 这里我没有用全局异常来做,具体根据自身业务来。

    @Before("@annotation(cn.isuyu.form.repeat.commit.annotations.Form)")
    public void formBefore(){
        String formId = request.getHeader("formId");

        if (null == formId) {
            throw new RuntimeException("请在头信息中携带formId");
        //删除缓存中的formId 这里直接使用delete是避免并发情况  使用seect + delete 存在并发问题
        } else if (!redisTools.delete(formId)){
            throw new RuntimeException("非法formId,请获取后重试");
        }
    }

源码地址:https://github.com/niezhiliang/form-never-repeat-commit

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值