| 
					
				 | 
			
			
				@@ -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; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 |