spring-mvc拦截器+注解 解决重复请求
来源:互联网 发布:编程熟练 编辑:程序博客网 时间:2024/06/05 20:51
在实际生产环境中,首次保存信息,点击一次保存按钮可服务器响应较慢,客户心急多次点击保存按钮,就会导致保存多分除ID外一模一样的信息,这是一个较为严重的bug
怎么解决?f不多说,这是我总结实现的代码
第一步:写一个拦截器, 验证请求内容是否完全相同
package com.thinkgem.jeesite.common.interceptor;import java.lang.reflect.Method; import java.util.HashMap; import java.util.Map; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.log4j.Logger;import org.springframework.web.context.request.RequestContextHolder;import org.springframework.web.context.request.ServletRequestAttributes;import org.springframework.web.method.HandlerMethod; import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; import com.thinkgem.jeesite.common.mapper.JsonMapper; /** 16. * 一个用户 相同url 同时提交 相同数据 验证 17. * 主要通过 session中保存到的url 和 请求参数。如果和上次相同,则是重复提交表单 18. * @author Administrator 19. * 20. */ public class SameUrlDataInterceptor extends HandlerInterceptorAdapter{ private static final Logger LOG = Logger.getLogger(SameUrlData.class); /** * 是否阻止提交 ,fasle 阻止 ,true放行 * @param httpServletRequest * @return */ @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) { if(repeatDataValidator(request)){ LOG.warn("please don't repeat submit,url:"+ request.getServletPath()); String id = request.getParameter("id"); if(id!=null&&!"".equals(id)){//如果信息表ID已经存在则不是新加信息,而是修改信息,放行 return true; } String formRequest = request.getRequestURI(); request.setAttribute("myurl", formRequest); request.getRequestDispatcher("/WEB-INF/views/modules/middle/middle.jsp").forward(request, response);//拦截之后页面跳转位置 return false; }//如果重复相同数据 else { return true; } } return true; } else { return super.preHandle(request, response, handler); } } /** * 验证同一个url数据是否相同提交 ,相同返回true * @param httpServletRequest * @return */ public boolean repeatDataValidator(HttpServletRequest httpServletRequest) { //String params=IdGen.generateShortUuid();String params=JsonMapper.toJsonString(httpServletRequest.getParameterMap()); //获取全部请求内容Object[] urlFlags = (Object[]) httpServletRequest.getParameterMap().get("urlFlag"); //获取不可变标识 System.out.println("params==========="+params); String url=httpServletRequest.getRequestURI(); Map<String,String> map=new HashMap<String,String>(); map.put(url, params); String nowUrlParams=map.toString();// Object preUrlParams=httpServletRequest.getSession().getAttribute("repeatData"); if(preUrlParams==null)//如果上一个数据为null,表示还没有访问页面 { httpServletRequest.getSession().setAttribute("repeatData", nowUrlParams); return false; } else//否则,已经访问过页面 { if(preUrlParams.toString().equals(nowUrlParams)) { //如果上次url+数据和本次url+数据相同,则表示重复添加数据 return true; } else//如果上次 url+数据 和本次url加数据不同,则不是重复提交 { httpServletRequest.getSession().setAttribute("repeatData", nowUrlParams); return false; } } } }
第二步:把拦截器写成注解
package com.thinkgem.jeesite.common.interceptor;import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** 09. * 一个用户 相同url 同时提交 相同数据 验证 10. * @author Administrator 11. * 12. */ @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface SameUrlData { }
第三步:把拦截器路径写在spring-mvc的配置文件中
<!-- 配置拦截器,防止用户重复提交数据 --><!--拦截得路径 拦截所有得URL--><!--class文件路径改成你自己写得拦截器路径!!--><mvc:interceptor> <mvc:mapping path="${adminPath}/wkst/worksheet/save"/> <mvc:mapping path="${adminPath}/cust/customer/save"/> <bean class="com.thinkgem.jeesite.common.interceptor.SameUrlDataInterceptor"/> </mvc:interceptor>
第四步:把注解写在controller的最前面
@SameUrlData@RequiresPermissions("cust:customer:edit")@RequestMapping(value = "save")public String save(Customer customer, Model model,HttpServletRequest request, RedirectAttributes redirectAttributes)
第五步:在页面写URL标识
<input type="hidden" name="urlFlag" value="${urlFlag}"> //在打开页面的时候就存一个唯一标识,UUID <form:hidden path="id"/>//信息表生成的ID
第六部:写拦截到重复请求页面跳转的位置
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%><%String path = request.getContextPath();String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";%><%@ include file="/WEB-INF/views/include/taglib.jsp"%><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html> <head> <base href="<%=basePath%>"> <title>My JSP 'middle.jsp' starting page</title> <meta http-equiv="pragma" content="no-cache"><meta http-equiv="cache-control" content="no-cache"><meta http-equiv="expires" content="0"> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"><meta http-equiv="description" content="This is my page"><!--<link rel="stylesheet" type="text/css" href="styles.css">--><script type="text/javascript">function readyLoad(){var url = "${myurl}";if(url.indexOf('/wkst/worksheet/save')>=0){setTimeout(function(){window.location.href = "${ctx}/wkst/worksheet/autosave";}, 2000 );} else if(url.indexOf('/cust/customer/save')>=0){setTimeout(function(){window.location.href = "${ctx}/cust/customer/list";}, 2000 );}}</script> </head> <body onload="readyLoad()"> </body></html>
至此,宝宝再也不担心重复提交了,吐槽一下,这编辑器有bug,我改了8遍,不能优化吗?
阅读全文
0 0
- spring-mvc拦截器+注解 解决重复请求
- 【spring mvc】Spring MVC拦截器+注解方式实现防止表单重复提交
- Spring MVC拦截器+注解方式实现防止表单重复提交
- Spring MVC拦截器+注解方式实现防止表单重复提交
- Spring MVC拦截器+注解方式实现防止表单重复提交
- Spring MVC拦截器+注解方式实现防止表单重复提交
- Spring MVC拦截器+注解方式实现防止表单重复提交
- Spring MVC拦截器+注解方式实现防止表单重复提交
- Spring MVC拦截器+注解方式实现防止表单重复提交
- Spring MVC拦截器+注解方式实现防止表单重复提交
- Spring MVC拦截器+注解方式实现防止表单重复提交
- Spring MVC拦截器+注解方式实现防止表单重复提交
- Spring MVC拦截器+注解方式实现防止表单重复提交
- Spring MVC拦截器+注解方式实现防止表单重复提交
- Spring MVC拦截器+注解方式实现防止表单重复提交
- Spring MVC拦截器+注解方式实现防止表单重复提交
- Spring MVC拦截器通过注解方式实现防止表单重复提交
- Spring MVC拦截器+注解方式实现防止表单重复提交
- 关于约瑟夫_Joesphus问题(C语言数组解决)
- c++中头文件与实现文件的关系
- 数据结构与算法概念解析
- 冒泡排序
- 浅谈媒体查询
- spring-mvc拦截器+注解 解决重复请求
- 使用label标签,修改checkbox默认样式
- in 和 exists 区别,not in和not exists区别
- mina服务端检测客户端心跳实例
- 生产环境tcmalloc 缓存回收
- jquery的分页插件pagination的使用
- 颜色代码
- MySQL5.7.20源码安装
- OpenCV中Mat矩阵相乘——点乘、dot、mul运算详解