zoukankan      html  css  js  c++  java
  • redis实现禁止重复请求的切面小功能

    场景:3秒时间内禁止重复提交!

    Controller:   伪代码

    package com..aopCommit;
    
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    @RestController
    public class CommitController {
    
        @RequestMapping("/Commit")
        @CommitAop
        public String Commit() {
            System.out.println("进入方法,执行业务!");
            return "返回结果!";
        }
    }

    自定义注解类:

    package com..aopCommit;
    
    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 CommitAop {
    
    }

    切面类:

    package com..aopCommit;
    
    import com..redis.RedisPoolUtils;
    import org.apache.commons.lang3.StringUtils;
    import org.aspectj.lang.ProceedingJoinPoint;
    import org.aspectj.lang.annotation.Around;
    import org.aspectj.lang.annotation.Aspect;
    import org.springframework.stereotype.Component;
    import org.springframework.web.context.request.RequestContextHolder;
    import org.springframework.web.context.request.ServletRequestAttributes;
    import javax.servlet.http.HttpServletRequest;
    import java.util.UUID;
    
    @Aspect
    @Component
    public class CommitImpl {
    
        RedisPoolUtils redisPoolUtils =new RedisPoolUtils();
    
        @Around("@annotation(com.wondersgroup.aopCommit.CommitAop)")
        public Object doubleCommit(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
    
            ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
    
            HttpServletRequest request = servletRequestAttributes.getRequest();
            String ip = request.getRemoteAddr();
            String className = proceedingJoinPoint.getSignature().getDeclaringTypeName();
            String Mathod = proceedingJoinPoint.getSignature().getName();
            System.out.println("请求的IP :"+ip);
            System.out.println("类方法 :"+className+ "." + Mathod);
    
            String ipKey = String.format("%s#%s",className,Mathod);
            int hashCode = Math.abs(ipKey.hashCode());
            String key = String.format("%s_%d",ip,hashCode+2);
            String value =  redisPoolUtils.get(key);
            if(StringUtils.isNotBlank(value)){
                System.out.println("请勿重新提交!");
                return "请勿重新提交!";
            }
            redisPoolUtils.setex(key, UUID.randomUUID().toString(),3);
    
            Object object = proceedingJoinPoint.proceed();
    
            return object;
        }
    
    }

    redis工具类:

    package com..redis;
    
    import redis.clients.jedis.BinaryClient.LIST_POSITION;
    import redis.clients.jedis.Jedis;
    import redis.clients.jedis.JedisPool;
    import redis.clients.jedis.JedisPoolConfig;
    import redis.clients.jedis.Pipeline;
    import java.io.IOException;
    import java.io.InputStream;
    import java.util.List;
    import java.util.Map;
    import java.util.Properties;
    import java.util.Set;
    
    public class RedisPoolUtils {
    
        public RedisPoolUtils() {
            
        }
        
        private static JedisPool pool;
        private static String host;//地址
        private static String port;//端口
        private static String password;//授权密码
        private static String timeout;//超时时间:单位MS
        private static String maxIdle;//最大空闲数:空闲链接数大于maxIdle时,将进行回收
        private static String maxActive;//最大连接数:能够同时建立的"最大链接个数"
        private static String maxWait;//最大等待时间:单位ms
        private static String testOnBorrow;//在获取连接时,是否验证有效性
        
        static{
            //加载properties配置文件
            Properties properties = new Properties();
            JedisPoolConfig config = new JedisPoolConfig();
            InputStream is = RedisUtil.class.getClassLoader().getResourceAsStream("redis_config.properties");
            try {
                properties.load(is);
            } catch (IOException e) {
                e.printStackTrace();
            }
            host = properties.getProperty("redis.single.host");
            port = properties.getProperty("redis.single.port");
            password = properties.getProperty("redis.password");
            timeout = properties.getProperty("redis.timeout");
            maxIdle = properties.getProperty("redis.maxIdle");
            maxActive = properties.getProperty("redis.maxActive");
            maxWait = properties.getProperty("redis.maxWait");
            testOnBorrow = properties.getProperty("redis.testOnBorrow");
            // 得到Jedis/JedisPool实例并且设置配置
            pool = new JedisPool(config,host,Integer.parseInt(port),Integer.parseInt(timeout));
            
        }
    
        /**
         * 设置key value并制定这个键值的有效期
         * 
         * @param key
         * @param value
         * @param seconds
         *            单位:秒
         * @return 成功返回OK 失败和异常返回null
         */
        public String setex(String key, String value, int seconds) {
            Jedis jedis = null;
            String res = null;
            try {
                jedis = pool.getResource();
                res = jedis.setex(key, seconds, value);
            } catch (Exception e) {
                pool.returnBrokenResource(jedis);
                e.printStackTrace();
            } finally {
                returnResource(pool, jedis);
            }
            return res;
        }
    }

    redis_config.properties :

    redis.single.host=127.0.0.1
    redis.single.port=6379
    redis.password=
    redis.timeout=100000
    redis.maxIdle=100
    redis.maxActive=300
    redis.maxWait=1000
    redis.testOnBorrow=true

    切面jar包:

    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
    </dependency>

    测试结果  (第一次访问成功,3秒后再次成功,中间直接返回):

  • 相关阅读:
    IDEA插件和快捷设置
    漫谈虚拟内存
    漫谈进程和线程
    漫谈计算机语言
    初识Python
    数据库物理设计
    漫谈计算机体系
    数据库逻辑设计
    NLP中几种分词库的简单使用(Python)
    ML————朴素贝叶斯原理和SKlearn相关库
  • 原文地址:https://www.cnblogs.com/lifan12589/p/14283435.html
Copyright © 2011-2022 走看看