/*** 防止重复提交拦截器** @author ruoyi*/

@Component

public abstract class RepeatSubmitInterceptor extends HandlerInterceptorAdapter

{

@Override

public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception

{

if (handler instanceof HandlerMethod)

{

HandlerMethod handlerMethod = (HandlerMethod) handler;

Method method = handlerMethod.getMethod();

RepeatSubmit annotation = method.getAnnotation(RepeatSubmit.class);

if (annotation != null)

{

if (this.isRepeatSubmit(request))

{

AjaxResult ajaxResult = AjaxResult.error("不允许重复提交,请稍后再试");

ServletUtils.renderString(response, JSONObject.toJSONString(ajaxResult));

return false;

}

}

return true;

}

else

{

return super.preHandle(request, response, handler);

}

}

/*** 验证是否重复提交由子类实现具体的防重复提交的规则** @param request* @return* @throws Exception*/

public abstract boolean isRepeatSubmit(HttpServletRequest request);

}

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

/*** 间隔时间,单位:秒 默认10秒** 两次相同参数的请求,如果间隔时间大于该参数,系统不会认定为重复提交的数据*/

private int intervalTime = 10;

public void setIntervalTime(int intervalTime)

{

this.intervalTime = intervalTime;

}

@SuppressWarnings("unchecked")

@Override

public boolean isRepeatSubmit(HttpServletRequest request)

{

String nowParams = "";

if (request instanceof RepeatedlyRequestWrapper)

{

RepeatedlyRequestWrapper repeatedlyRequest = (RepeatedlyRequestWrapper) request;

nowParams = HttpHelper.getBodyString(repeatedlyRequest);

}

// body参数为空,获取Parameter的数据 if (StringUtils.isEmpty(nowParams))

{

nowParams = JSONObject.toJSONString(request.getParameterMap());

}

Map nowDataMap = new HashMap();

nowDataMap.put(REPEAT_PARAMS, nowParams);

nowDataMap.put(REPEAT_TIME, System.currentTimeMillis());

// 请求地址(作为存放cache的key值) String url = request.getRequestURI();

// 唯一值(没有消息头则使用请求地址) String submitKey = request.getHeader(header);

if (StringUtils.isEmpty(submitKey))

{

submitKey = url;

}

// 唯一标识(指定key + 消息头) String cache_repeat_key = Constants.REPEAT_SUBMIT_KEY + submitKey;

Object sessionObj = redisCache.getCacheObject(cache_repeat_key);

if (sessionObj != null)

{

Map sessionMap = (Map) sessionObj;

if (sessionMap.containsKey(url))

{

Map preDataMap = (Map) sessionMap.get(url);

if (compareParams(nowDataMap, preDataMap) && compareTime(nowDataMap, preDataMap))

{

return true;

}

}

}

Map cacheMap = new HashMap();

cacheMap.put(url, nowDataMap);

redisCache.setCacheObject(cache_repeat_key, cacheMap, intervalTime, TimeUnit.SECONDS);

return false;

}

/*** 判断参数是否相同*/

private boolean compareParams(Map nowMap, Map preMap)

{

String nowParams = (String) nowMap.get(REPEAT_PARAMS);

String preParams = (String) preMap.get(REPEAT_PARAMS);

return nowParams.equals(preParams);

}

/*** 判断两次间隔时间*/

private boolean compareTime(Map nowMap, Map 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;

}

}

Logo

快速构建 Web 应用程序

更多推荐