防止系统重复提交基于Session的实现
-
定义一个注解
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface SameUrlData {
}
该注解作为一个标识,通过HandlerInterceptorAdapter(基于springMvc实现的Filter)
主要方法
preHandle在业务处理器处理请求之前被调用。预处理,可以进行编码、安全控制等处理;
postHandle在业务处理器处理请求执行完成后,生成视图之前执行。后处理(调用了Service并返回ModelAndView,但未进行页面渲染),有机会修改ModelAndView;
afterCompletion在DispatcherServlet完全处理完请求后被调用,可用于清理资源等。返回处理(已经渲染了页面),可以根据ex是否为null判断是否发生了异常,进行日志记录; -
实现HandlerInterceptorAdapter重写preHandle方法
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
if (handler instanceof HandlerMethod) {
HandlerMethod handlerMethod = (HandlerMethod) handler;
Method method = handlerMethod.getMethod();
SameUrlData annotation = method.getAnnotation(SameUrlData.class);
if (annotation != null) {
// 验证同一个url数据是否相同重复提交,相同则返回true
return !repeatDataValidator(request);
}
try {
Session session = ShiroUtil.getSession();
session.removeAttribute("repeatData");
}catch (Exception e){
}
return true;
} else {
return super.preHandle(request, response, handler);
}
}
/**
* 验证同一个url数据是否相同提交 ,相同返回true
*
* @param httpServletRequest
* request
* @return 是否执行
*/
public boolean repeatDataValidator(HttpServletRequest httpServletRequest) {
ServletInputStream inputStream = null;
String str = "";
try {
inputStream = httpServletRequest.getInputStream();
str = IOUtils.toString(inputStream, Charset.forName("UTF-8"));
log.error(str);
log.error("=======================================");
} catch (IOException e) {
throw new MyException(e.toString());
}
String params = JSON.toJSONString(str);
String url = httpServletRequest.getRequestURI();
Map<String, String> map = new HashMap<String, String>();
map.put(url, params);
String nowUrlParams = JSON.toJSONString(map);
Session session = ShiroUtil.getSession();
Object preUrlParams = session.getAttribute("repeatData");
//如果上一个数据为null,表示还没有访问页面
if (preUrlParams == null) {
session.setAttribute("repeatData", nowUrlParams);
return false;
} else {
//否则,已经访问过页面
//如果上次url+数据和本次url+数据相同,则表示重复添加数据
if (preUrlParams.toString().equals(nowUrlParams)) {
return true;
} else {
//如果上次 url+数据 和本次url加数据不同,则不是重复提交
session.setAttribute("repeatData", nowUrlParams);
return false;
}
}
}