| package com.ruoyi.framework.interceptor.impl; | 
|   | 
| import java.util.HashMap; | 
| import java.util.Map; | 
| import java.util.concurrent.TimeUnit; | 
| import javax.servlet.http.HttpServletRequest; | 
| import org.springframework.beans.factory.annotation.Autowired; | 
| import org.springframework.beans.factory.annotation.Value; | 
| import org.springframework.stereotype.Component; | 
| import com.alibaba.fastjson2.JSON; | 
| import com.ruoyi.common.annotation.RepeatSubmit; | 
| import com.ruoyi.common.constant.CacheConstants; | 
| import com.ruoyi.common.core.redis.RedisCache; | 
| import com.ruoyi.common.filter.RepeatedlyRequestWrapper; | 
| import com.ruoyi.common.utils.StringUtils; | 
| import com.ruoyi.common.utils.http.HttpHelper; | 
| import com.ruoyi.framework.interceptor.RepeatSubmitInterceptor; | 
|   | 
| /** | 
|  * 判断请求url和数据是否和上一次相同, | 
|  * 如果和上次相同,则是重复提交表单。 有效时间为10秒内。 | 
|  *  | 
|  * @author ruoyi | 
|  */ | 
| @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 RedisCache redisCache; | 
|   | 
|     @SuppressWarnings("unchecked") | 
|     @Override | 
|     public boolean isRepeatSubmit(HttpServletRequest request, RepeatSubmit annotation) | 
|     { | 
|         String nowParams = ""; | 
|         if (request instanceof RepeatedlyRequestWrapper) | 
|         { | 
|             RepeatedlyRequestWrapper repeatedlyRequest = (RepeatedlyRequestWrapper) request; | 
|             nowParams = HttpHelper.getBodyString(repeatedlyRequest); | 
|         } | 
|   | 
|         // body参数为空,获取Parameter的数据 | 
|         if (StringUtils.isEmpty(nowParams)) | 
|         { | 
|             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(); | 
|   | 
|         // 唯一值(没有消息头则使用请求地址) | 
|         String submitKey = StringUtils.trimToEmpty(request.getHeader(header)); | 
|   | 
|         // 唯一标识(指定key + url + 消息头) | 
|         String cacheRepeatKey = CacheConstants.REPEAT_SUBMIT_KEY + url + submitKey; | 
|   | 
|         Object sessionObj = redisCache.getCacheObject(cacheRepeatKey); | 
|         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, annotation.interval())) | 
|                 { | 
|                     return true; | 
|                 } | 
|             } | 
|         } | 
|         Map<String, Object> cacheMap = new HashMap<String, Object>(); | 
|         cacheMap.put(url, nowDataMap); | 
|         redisCache.setCacheObject(cacheRepeatKey, cacheMap, annotation.interval(), TimeUnit.MILLISECONDS); | 
|         return false; | 
|     } | 
|   | 
|     /** | 
|      * 判断参数是否相同 | 
|      */ | 
|     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); | 
|     } | 
|   | 
|     /** | 
|      * 判断两次间隔时间 | 
|      */ | 
|     private boolean compareTime(Map<String, Object> nowMap, Map<String, Object> preMap, int interval) | 
|     { | 
|         long time1 = (Long) nowMap.get(REPEAT_TIME); | 
|         long time2 = (Long) preMap.get(REPEAT_TIME); | 
|         if ((time1 - time2) < interval) | 
|         { | 
|             return true; | 
|         } | 
|         return false; | 
|     } | 
| } |