1. 生成UUID,放Cache中
class CaptchaUtil
public static String getUUID() {
String uuid = UUID.randomUUID().toString();
Cache.set(uuid, uuid, Constants.CACHE_TIME);
return uuid;
}
2. /* 防重复提交 */
if(!CaptchaUtil.checkUUID(uuid)){
flash.error("请求已提交或请求超时!");
applyNow(productId, -100, status);
}
3.检查uuid
class CaptchaUtil
//true为正常提交,false为重复提交
//第一次提交时来做检验。会执行到 Cache.delete(key);
//所以之后的提交只需检验Cache中是否含有以key为键的值
public static boolean checkUUID(String key) {
if(StringUtils.isBlank(key))
return false; //非法请求
//第二次过来,由于key被删除,所以,obj==null
Object obj = Cache.get(key);
try {
Cache.delete(key);
} catch (Exception e) {
return false;
}
if(null == obj)
return false;
return true;
}
另外一种方案
基于客户端token验证的防重复提交
=====================================================================================================
package com.zunhao.util;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.log4j.Logger;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
/**
* @author 程昭斌
* @Date:2015年12月4日 上午9:45:52
* 防止操作频繁
*/
public class AvoidSubmit extends HandlerInterceptorAdapter{
private Logger log=Logger.getLogger(AvoidSubmit.class);
/**
* 处理之前
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
//500毫秒内 不允许重复提交
if(invokeNum(request,1,0.5,"czbAvoidTime","czbAvoidCount")){
log.error("重复提交");
return false;
}
return true;
}
/**
* 处理之后
* request请求处理完成,或已返回响应(即页面已跳转)
此时便不再有重复提交的问题了,可以把session清除,以免浪费缓存
*/
@Override
public void afterCompletion(
HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
throws Exception {
super.afterCompletion(request, response, handler, ex);
request.getSession().removeAttribute("czbAvoidTime");
request.getSession().removeAttribute("czbAvoidCount");
log.error("请求完成,清除session");
}
/**
*
* @param request
* @param num 表示规定周期内访问次数
* @param count 表示多少秒
* @return true 表示拦截成功,没通过 false 表示通过拦截 可以往下走
*/
public static boolean invokeNum(HttpServletRequest request,int num,double count,String sessionKeyTime,String sessionKeyCount){
//有时间限制
Object obj=request.getSession().getAttribute(sessionKeyTime);
if(obj==null){
request.getSession().setAttribute(sessionKeyTime,System.currentTimeMillis());
return false;
}else{
long time=(Long)obj;
if(System.currentTimeMillis()-time>1000*count){
//超过规定时间 就更新 开始 调用的时间点和调用次数
request.getSession().setAttribute(sessionKeyTime,System.currentTimeMillis());
request.getSession().setAttribute(sessionKeyCount,0);
return false;
}
return num(request,num,sessionKeyCount);
}
}
//次数限制 num 次数
public static boolean num(HttpServletRequest request,int number,String sessionKeyCount){
int num=1;
Object obj=request.getSession().getAttribute(sessionKeyCount);
if(obj!=null){
num=(Integer) obj;
num++;
request.getSession().setAttribute(sessionKeyCount,num);
}else{
request.getSession().setAttribute(sessionKeyCount,num);
}
return num>=number;
}
}