|  | @@ -1,15 +1,18 @@
 | 
	
		
			
				|  |  |  package com.fs.core.interceptor.impl;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -import java.util.HashMap;
 | 
	
		
			
				|  |  | -import java.util.Map;
 | 
	
		
			
				|  |  | -import java.util.concurrent.TimeUnit;
 | 
	
		
			
				|  |  | +import java.util.Arrays;
 | 
	
		
			
				|  |  | +import java.util.List;
 | 
	
		
			
				|  |  |  import javax.servlet.http.HttpServletRequest;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +import com.alibaba.fastjson.JSON;
 | 
	
		
			
				|  |  | +import lombok.extern.slf4j.Slf4j;
 | 
	
		
			
				|  |  |  import org.springframework.beans.factory.annotation.Autowired;
 | 
	
		
			
				|  |  | +import org.springframework.beans.factory.annotation.Qualifier;
 | 
	
		
			
				|  |  |  import org.springframework.beans.factory.annotation.Value;
 | 
	
		
			
				|  |  | +import org.springframework.data.redis.core.RedisTemplate;
 | 
	
		
			
				|  |  | +import org.springframework.data.redis.core.script.DefaultRedisScript;
 | 
	
		
			
				|  |  |  import org.springframework.stereotype.Component;
 | 
	
		
			
				|  |  | -import com.alibaba.fastjson.JSONObject;
 | 
	
		
			
				|  |  |  import com.fs.common.constant.Constants;
 | 
	
		
			
				|  |  | -import com.fs.common.core.redis.RedisCache;
 | 
	
		
			
				|  |  |  import com.fs.common.filter.RepeatedlyRequestWrapper;
 | 
	
		
			
				|  |  |  import com.fs.common.utils.StringUtils;
 | 
	
		
			
				|  |  |  import com.fs.common.utils.http.HttpHelper;
 | 
	
	
		
			
				|  | @@ -18,38 +21,39 @@ import com.fs.core.interceptor.RepeatSubmitInterceptor;
 | 
	
		
			
				|  |  |  /**
 | 
	
		
			
				|  |  |   * 判断请求url和数据是否和上一次相同,
 | 
	
		
			
				|  |  |   * 如果和上次相同,则是重复提交表单。 有效时间为10秒内。
 | 
	
		
			
				|  |  | - * 
 | 
	
		
			
				|  |  |   */
 | 
	
		
			
				|  |  | +@Slf4j
 | 
	
		
			
				|  |  |  @Component
 | 
	
		
			
				|  |  |  public class SameUrlDataInterceptor extends RepeatSubmitInterceptor
 | 
	
		
			
				|  |  |  {
 | 
	
		
			
				|  |  | -    public final String REPEAT_PARAMS = "repeatParams";
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    public final String REPEAT_TIME = "repeatTime";
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      // 令牌自定义标识
 | 
	
		
			
				|  |  |      @Value("${token.header}")
 | 
	
		
			
				|  |  |      private String header;
 | 
	
		
			
				|  |  | +    @Autowired
 | 
	
		
			
				|  |  | +    private RedisTemplate redisTemplate;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      @Autowired
 | 
	
		
			
				|  |  | -    private RedisCache redisCache;
 | 
	
		
			
				|  |  | +    @Qualifier("prevent-resubmit")
 | 
	
		
			
				|  |  | +    private DefaultRedisScript<Boolean> preventResubmitScript;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      /**
 | 
	
		
			
				|  |  |       * 间隔时间,单位:秒 默认10秒
 | 
	
		
			
				|  |  | -     * 
 | 
	
		
			
				|  |  | +     *
 | 
	
		
			
				|  |  |       * 两次相同参数的请求,如果间隔时间大于该参数,系统不会认定为重复提交的数据
 | 
	
		
			
				|  |  |       */
 | 
	
		
			
				|  |  |      private int intervalTime = 10;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    public void setIntervalTime(int intervalTime)
 | 
	
		
			
				|  |  | -    {
 | 
	
		
			
				|  |  | -        this.intervalTime = intervalTime;
 | 
	
		
			
				|  |  | -    }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      @SuppressWarnings("unchecked")
 | 
	
		
			
				|  |  |      @Override
 | 
	
		
			
				|  |  |      public boolean isRepeatSubmit(HttpServletRequest request)
 | 
	
		
			
				|  |  |      {
 | 
	
		
			
				|  |  | +       return this.isRepeatSubmit(request,this.intervalTime);
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    @Override
 | 
	
		
			
				|  |  | +    public boolean isRepeatSubmit(HttpServletRequest request, Integer intervalTime) {
 | 
	
		
			
				|  |  |          String nowParams = "";
 | 
	
		
			
				|  |  |          if (request instanceof RepeatedlyRequestWrapper)
 | 
	
		
			
				|  |  |          {
 | 
	
	
		
			
				|  | @@ -60,12 +64,8 @@ public class SameUrlDataInterceptor extends RepeatSubmitInterceptor
 | 
	
		
			
				|  |  |          // body参数为空,获取Parameter的数据
 | 
	
		
			
				|  |  |          if (StringUtils.isEmpty(nowParams))
 | 
	
		
			
				|  |  |          {
 | 
	
		
			
				|  |  | -            nowParams = JSONObject.toJSONString(request.getParameterMap());
 | 
	
		
			
				|  |  | +            nowParams = JSON.toJSONString(request.getParameterMap());
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  | -        Map<String, Object> nowDataMap = new HashMap<String, Object>();
 | 
	
		
			
				|  |  | -        nowDataMap.put(REPEAT_PARAMS, nowParams);
 | 
	
		
			
				|  |  | -        nowDataMap.put(REPEAT_TIME, System.currentTimeMillis());
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  |          // 请求地址(作为存放cache的key值)
 | 
	
		
			
				|  |  |          String url = request.getRequestURI();
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -78,47 +78,22 @@ public class SameUrlDataInterceptor extends RepeatSubmitInterceptor
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          // 唯一标识(指定key + 消息头)
 | 
	
		
			
				|  |  |          String cache_repeat_key = Constants.REPEAT_SUBMIT_KEY + submitKey;
 | 
	
		
			
				|  |  | +        // 当前时间戳
 | 
	
		
			
				|  |  | +        long currentTimeMillis = System.currentTimeMillis();
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -        Object sessionObj = redisCache.getCacheObject(cache_repeat_key);
 | 
	
		
			
				|  |  | -        if (sessionObj != null)
 | 
	
		
			
				|  |  | -        {
 | 
	
		
			
				|  |  | -            Map<String, Object> sessionMap = (Map<String, Object>) sessionObj;
 | 
	
		
			
				|  |  | -            if (sessionMap.containsKey(url))
 | 
	
		
			
				|  |  | -            {
 | 
	
		
			
				|  |  | -                Map<String, Object> preDataMap = (Map<String, Object>) sessionMap.get(url);
 | 
	
		
			
				|  |  | -                if (compareParams(nowDataMap, preDataMap) && compareTime(nowDataMap, preDataMap))
 | 
	
		
			
				|  |  | -                {
 | 
	
		
			
				|  |  | -                    return true;
 | 
	
		
			
				|  |  | -                }
 | 
	
		
			
				|  |  | -            }
 | 
	
		
			
				|  |  | -        }
 | 
	
		
			
				|  |  | -        Map<String, Object> cacheMap = new HashMap<String, Object>();
 | 
	
		
			
				|  |  | -        cacheMap.put(url, nowDataMap);
 | 
	
		
			
				|  |  | -        redisCache.setCacheObject(cache_repeat_key, cacheMap, intervalTime, TimeUnit.SECONDS);
 | 
	
		
			
				|  |  | -        return false;
 | 
	
		
			
				|  |  | -    }
 | 
	
		
			
				|  |  | +        // 执行Lua脚本
 | 
	
		
			
				|  |  | +        List<String> keys = Arrays.asList(cache_repeat_key, url);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    /**
 | 
	
		
			
				|  |  | -     * 判断参数是否相同
 | 
	
		
			
				|  |  | -     */
 | 
	
		
			
				|  |  | -    private boolean compareParams(Map<String, Object> nowMap, Map<String, Object> preMap)
 | 
	
		
			
				|  |  | -    {
 | 
	
		
			
				|  |  | -        String nowParams = (String) nowMap.get(REPEAT_PARAMS);
 | 
	
		
			
				|  |  | -        String preParams = (String) preMap.get(REPEAT_PARAMS);
 | 
	
		
			
				|  |  | -        return nowParams.equals(preParams);
 | 
	
		
			
				|  |  | -    }
 | 
	
		
			
				|  |  | +        log.info("调用lua参数: {} {} {} {} {}",preventResubmitScript,keys,nowParams,currentTimeMillis,intervalTime);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    /**
 | 
	
		
			
				|  |  | -     * 判断两次间隔时间
 | 
	
		
			
				|  |  | -     */
 | 
	
		
			
				|  |  | -    private boolean compareTime(Map<String, Object> nowMap, Map<String, Object> preMap)
 | 
	
		
			
				|  |  | -    {
 | 
	
		
			
				|  |  | -        long time1 = (Long) nowMap.get(REPEAT_TIME);
 | 
	
		
			
				|  |  | -        long time2 = (Long) preMap.get(REPEAT_TIME);
 | 
	
		
			
				|  |  | -        if ((time1 - time2) < (this.intervalTime * 1000))
 | 
	
		
			
				|  |  | -        {
 | 
	
		
			
				|  |  | -            return true;
 | 
	
		
			
				|  |  | -        }
 | 
	
		
			
				|  |  | -        return false;
 | 
	
		
			
				|  |  | +        Boolean result = (Boolean) redisTemplate.execute(
 | 
	
		
			
				|  |  | +                preventResubmitScript,
 | 
	
		
			
				|  |  | +                keys,
 | 
	
		
			
				|  |  | +                nowParams,
 | 
	
		
			
				|  |  | +                currentTimeMillis,
 | 
	
		
			
				|  |  | +                intervalTime
 | 
	
		
			
				|  |  | +        );
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        return result != null && result;
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  }
 |