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

来源:互联网 发布:java开源网盘系统 编辑:程序博客网 时间:2024/06/06 05:58

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

1. 前言:

在开发阶段中发现app时常会出现这样的一种问题:如果对一次请求在很短的时间多次重复提交,则会引起一系列的问题,对此,本人自己琢磨后写成博客,希望能对大家有所帮助!

2. 准备阶段

1.java开发环境2.redis3.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("/**");  //对来自/** 这个链接来的请求进行拦截    }}
原创粉丝点击