Java使用Interceptor+redis去实现请求重复频繁提交问题

Java使用Interceptor+redis去实现请求重复频繁提交问题

1. 前言:
在开发阶段中发现app时常会出现这样的一种问题:如果对一次请求在很短的时间多次重复提交,则会引起一系列的问题,对此,本人自己琢磨后写成博客,希望能对大家有所帮助!
2. 准备阶段
1.java开发环境
2.redis
3.jar包依赖
    <dependency><groupId>redis.clients</groupId>
        <artifactId>jedis</artifactId>
        <version>2.1.0</version>
    </dependency>

4.redis安装就不用讲了 
    这个比较详细 http://www.runoob.com/redis/redis-install.html
3. 实例

RedisUtils

public class RedisUtils {
    private static Logger logger = LoggerFactory.getLogger(RedisUtils.class); 
        public final static String VIRTUAL_COURSE_PREX = "vc_";  

    private Jedis jedis;//非切片额客户端连接
    private static JedisPool jedisPool;//非切片连接池
    private ShardedJedis shardedJedis;//切片额客户端连接
    private ShardedJedisPool shardedJedisPool;//切片连接池

    public RedisUtils() 
    { 
        initialPool(); 
        initialShardedPool(); 
        shardedJedis = shardedJedisPool.getResource(); 
        jedis = jedisPool.getResource(); 

    } 

    /**
     * 初始化非切片池
     */
    private static void initialPool() 
    { 
        // 池基本配置 
        JedisPoolConfig config = new JedisPoolConfig(); 
        config.setMaxIdle(20); 
        config.setMaxIdle(5); 
        config.setMaxWait(1000l); 
        config.setTestOnBorrow(false); 

        jedisPool = new JedisPool(config,"127.0.0.1",6379);
    }

    /** 
     * 初始化切片池 
     */ 
    private void initialShardedPool() 
    { 
        // 池基本配置 
        JedisPoolConfig config = new JedisPoolConfig(); 
        config.setMaxIdle(20); 
        config.setMaxIdle(5); 
        config.setMaxWait(1000l); 
        config.setTestOnBorrow(false); 
        // slave链接 
        List<JedisShardInfo> shards = new ArrayList<JedisShardInfo>(); 
        shards.add(new JedisShardInfo("127.0.0.1", 6379)); 

        // 构造池 
        shardedJedisPool = new ShardedJedisPool(config, shards); 
    } 

    public void show() {     
        KeyOperate(); 
        StringOperate(); 
        ListOperate(); 
        SetOperate();
        SortedSetOperate();
        HashOperate(); 
        jedisPool.returnResource(jedis);
        shardedJedisPool.returnResource(shardedJedis);
    }
    /** 
     * 在多线程环境同步初始化 
     */  
    private synchronized static void poolInit() {  
        if (jedisPool == null) {    
            initialPool();  
        }  
    }  


    /** 
     * 同步获取Jedis实例 
     * @return Jedis 
     */  
    public synchronized static Jedis getJedis() {  
        if (jedisPool == null) { 
            poolInit();  
        }  
        Jedis jedis = null;  
        try {  
            if (jedisPool != null) {  
                jedis = jedisPool.getResource();  
                jedis.auth("xxxxxxx");  //设置密码
               // jedis.auth(redisCacheConfig.getAuth());  
            }  
        } catch (Exception e) {  
            logger.error("Get jedis error : "+e);  
            e.printStackTrace();  
        }finally{  
            returnResource(jedis);  
        }  
        return jedis;  
    }  

    /** 
     * 释放jedis资源 
     * @param jedis 
     */  
    public static void returnResource(final Jedis jedis) {  
        if (jedis != null && jedisPool !=null) {  
            jedisPool.returnResource(jedis);  
        }  
    }  

    /** 
     * 得到Key 
     * @param key 
     * @return 
     */  
    public static String buildKey(String key){  
        return  key;  
    }  
    /** 
     * 设置 String 
     * @param key 
     * @param value 
     */  
    public static void setString(String key ,String value){  
        try {  
            value = StringUtils.isNotEmpty(value) ? "" : value;  
            getJedis().set(buildKey(key),value);  
        } catch (Exception e) {  
            logger.error("Set keyex error : "+e);  
        }  
    }  

    /** 
     * 设置 过期时间 
     * @param key 
     * @param seconds 以秒为单位 
     * @param value 
     */  
    public static void setString(String key ,int seconds,String value){  
        try {  
            value = StringUtils.isNotEmpty(value) ? "" : value;  
            getJedis().setex(buildKey(key), seconds, value);  
        } catch (Exception e) {  
            logger.error("Set keyex error : "+e);  
        }  
    }  

    /** 
     * 获取String值 
     * @param key 
     * @return value 
     */  
    public  static String getString(String key){  
        String bKey = buildKey(key);  
        if(getJedis() == null || !getJedis().exists(bKey)){  
            return null;  
        }  
        return getJedis().get(bKey);  
    }  
    /** 
     * 设置 list 
     * @param <T> 
     * @param key 
     * @param value 
     */  
    public static <T> void setList(String key ,List<T> list){  
        try {  
            getJedis().set(key.getBytes(),ObjectTranscoder.serialize(list));  
        } catch (Exception e) {  
            logger.error("Set key error : "+e);  
        }  
    }  
    /** 
     * 获取list 
     * @param <T> 
     * @param key 
     * @return list 
     */  
    public  static <T> List<T> getList(String key){  
        String bKey = buildKey(key);  
        if(getJedis() == null || !getJedis().exists(key.getBytes())){  
            return null;  
        }  
        byte[] in = getJedis().get(key.getBytes());    
        List<T> list = (List<T>) ObjectTranscoder.deserialize(in);    
        return list;  
    }  
    /** 
     * 设置 map 
     * @param <T> 
     * @param key 
     * @param value 
     */  
    public static <T> void setMap(String key ,Map<String,T> map){  
        try {  
            getJedis().set(key.getBytes(),ObjectTranscoder.serialize(map));  
        } catch (Exception e) {  
            logger.warn("Set key error : "+e);  
        }  
    }  
    /** 
     * 获取list 
     * @param <T> 
     * @param key 
     * @return list 
     */  
    public static <T> Map<String,T> getMap(String key){  
        String bKey = buildKey(key);  
        if(getJedis() == null || !getJedis().exists(key.getBytes())){  
            return null;  
        }  
        byte[] in = getJedis().get(key.getBytes());    
        Map<String,T> map = (Map<String, T>) ObjectTranscoder.deserialize(in);    
        return map;  
    }  


    public static void main(String[] args) {

        RedisUtils redisCli=new RedisUtils();
        //redisCli.KeyOperate();
        redisCli.SetOperate();
    }
}

配置拦截器

public class TokenInterceptor extends HandlerInterceptorAdapter {
    //日志文件
    public Log logger = LogFactory.getLog(this.getClass());

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {
        Long value = System.currentTimeMillis(); //获取当前时间的毫秒数
        String nowRequestName = request.getServletPath().substring(1,request.getServletPath().length());//获取当前请求的名称view
        String umerId = request.getParameter("umerId"); //获取点击的人 
        String key = null; //组合Key
        String reidsValue = null; //根据key去取值
        String userType = null; //用户类型

        if(StringUtils.isEmpty(umerId)){
            //umerId 为空
            String userId = request.getParameter("userId");
            if(StringUtils.isEmpty(userId)){
                //如果userId为空
                String openId = request.getParameter("openId");
                if(StringUtils.isEmpty(openId)){
                    //如果openId也为空
                    //则不拦截
                    return super.preHandle(request, response, handler);
                }else {
                    //openId
                    userType = "openId";
                    umerId = openId;
                    key =  openId  + nowRequestName; //组合Key
                }
            }else {
                //userId不为空
                userType = "userId";
                umerId = userId;
                key =  userId  + nowRequestName; //组合Key
            }
        }else {
            //umerId不为空
            userType = "umerId";
            key = umerId  + nowRequestName; //组合Key
        }

        //获取值
        reidsValue =  RedisUtils.getJedis().get(key); //根据key去取值

        if(StringUtils.isEmpty(reidsValue)){
            //说明为空
            RedisUtils.getJedis().set(key,String.valueOf(value)); //设置值进去,并且过期时间为2秒
            RedisUtils.getJedis().expire(key, 2);
        }else{
            //不为空
            //开始判断
            Long time = Long.parseLong(reidsValue);
            if(value - time > 2000){
                //如果相隔大于2秒
                RedisUtils.getJedis().set(key,String.valueOf(value)); //设置值进去,并且过期时间为2秒
                RedisUtils.getJedis().expire(key,2);
            }else{
                //如果相隔小于2秒
                RedisUtils.getJedis().set(key,String.valueOf(value)); //设置值进去,并且过期时间为2秒
                RedisUtils.getJedis().expire(key, 2);
                PrintWriter out = response.getWriter();
                out.print("interceptor | TokenInterceptor | " + userType + ":" + umerId + " | error : 请求间隔低于2s,频率过快!");
                //logger.error("interceptor | TokenInterceptor | umerId :" + userName + " | error : 请求间隔低于2s,频率过快!");
                return false;
            }
        }
        return super.preHandle(request, response, handler);
    }
}

最后加载拦截器【spring-boot】

@Configuration   //标注此文件为一个配置项,spring boot才会扫描到该配置。该注解类似于之前使用xml进行配置
public class ServletContextConfig extends WebMvcConfigurerAdapter {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new TokenInterceptor()).addPathPatterns("/**");  //对来自/** 这个链接来的请求进行拦截
    }
}
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值