Aop实现后端数据重复提交

一、思路

用户每次发送请求都有一个标记,这个标记设置成5s有效存到redis中。每次请求检查该标记是否有效,还有效就说明请求太频繁了。无效就说明请求之间时间间隔够了,可以继续请求了。
gitee地址:添加链接描述

二、实现

  1. 自定义注解
import java.lang.annotation.*;
@Documented
@Target({ElementType.TYPE,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface NoRepeatSubmit {
    int lockTime() default 5;
}
  1. 注解+aop前置通知检查redis。将请求路径和当前用户token拼接存到redis中,并设置过期时间
import com.qcby.aop_cftj.myannotation.NoRepeatSubmit;
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.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

@Component
@Aspect
public class NoRepeatSubmitAspect {
    @Autowired
    private  RedisTemplate<String,Object> redisTemplate;
    @Pointcut("@annotation(repeatSubmit)")
    public void pointcutNoRepeat(NoRepeatSubmit repeatSubmit){};
    @Around("pointcutNoRepeat(noRepeatSubmit)")
    public  Object doNoRepeat(ProceedingJoinPoint point, NoRepeatSubmit noRepeatSubmit) throws Throwable {
        int i=noRepeatSubmit.lockTime();
        HttpServletRequest httpServletRequest = HttpServletRequest();
        Cookie[] cookies = httpServletRequest.getCookies();
        String token="";
        if(cookies!=null){
            for (Cookie cookie : cookies) {
               if(cookie.getName().equals("token")){
                   token=cookie.getValue().toString();
               }
            }
        }
        String url = httpServletRequest.getRequestURL().toString();
        String sign = url+"/"+token;
        Boolean key=redisTemplate.hasKey(sign);
        if (key){
            System.out.println("请勿重复提交!!");
            return null;
//            throw new Exception("请勿重复提交");

        }
        redisTemplate.opsForValue().set(sign,sign,i, TimeUnit.SECONDS);
        return  point.proceed();
    }
    public static HttpServletRequest HttpServletRequest(){
        return ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest();
    }
  1. 请求时根据用户信息生成token并存到cookie中
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;
import java.util.Date;
import java.util.UUID;
@Service
public class LoginService {
    @Resource
    RedisTemplate<String, String> redisTemplate;
    public String login(String phone, String password, HttpServletResponse response){
        //签名密钥
        String signature = "hello";
        JwtBuilder builder = Jwts.builder();
        //使用JWT生成器创建一个JWT
        String jwtToken = builder
                //Header
                .setHeaderParam("typ", "JWT")
                //类型
                .setHeaderParam("alg", "HS256")
                //使用的算法
                //Payload
                .claim("phone", phone)
                .setSubject("admin-test")
                .setExpiration(new Date(System.currentTimeMillis() + 1000*60*60*24))
                //失效日期:当前时间+24小时
                .setId(UUID.randomUUID().toString())
                //signature
                .signWith(SignatureAlgorithm.HS256, signature)
                //使用的算法+签名密钥
                //调用compact()方法将三部分拼接起来并用'.'分隔
                .compact();
        Cookie cookie=new Cookie("token",jwtToken.substring(0,5));
        response.addCookie(cookie);
        return "登录成功!!";
    }
}

相关推荐

  1. Aop实现数据重复提交

    2024-07-13 23:26:03       23 阅读
  2. 怎样防止重复提交订单?

    2024-07-13 23:26:03       52 阅读
  3. 如何防重复提交?(前端验证、验证)

    2024-07-13 23:26:03       39 阅读
  4. Spring自定义注解+AOP实现接口防重复提交

    2024-07-13 23:26:03       37 阅读
  5. uniapp 防止重复提交数据

    2024-07-13 23:26:03       21 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-13 23:26:03       66 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-13 23:26:03       70 阅读
  3. 在Django里面运行非项目文件

    2024-07-13 23:26:03       57 阅读
  4. Python语言-面向对象

    2024-07-13 23:26:03       68 阅读

热门阅读

  1. Android C++系列:Linux进程间关系

    2024-07-13 23:26:03       20 阅读
  2. thinkphp5多层with关联查询错误问题

    2024-07-13 23:26:03       25 阅读
  3. Understanding EtherCAT Device Serial Number Checking

    2024-07-13 23:26:03       19 阅读
  4. 1.1 Android启动概览

    2024-07-13 23:26:03       21 阅读
  5. HttpUtils工具类

    2024-07-13 23:26:03       18 阅读
  6. 风景区服务热线系统:智能化时代的旅游新选择

    2024-07-13 23:26:03       21 阅读
  7. acnconda虚拟环境管理笔记

    2024-07-13 23:26:03       21 阅读
  8. Spring基础知识

    2024-07-13 23:26:03       18 阅读
  9. 计算机课程名,汇总

    2024-07-13 23:26:03       16 阅读
  10. Python的基础语法——持续更新版

    2024-07-13 23:26:03       18 阅读