Spring MVC拦截器+注解方式实现防止表单重复提交
2016-06-13 18:15
537 查看
原理:在新建页面中Session保存token随机码,当保存时验证,通过后删除,当再次点击保存时由于服务器端的Session中已经不存在了,所有无法验证通过。
1.新建注解:
2. 新建拦截器
3. 在Spring中配置
4. 在相关方法中加入注解:
5.在新建页面中加入
<input type="hidden" name="token" value="${token}">
原理:在新建页面中Session保存token随机码,当保存时验证,通过后删除,当再次点击保存时由于服务器端的Session中已经不存在了,所有无法验证通过。
1.新建注解:
/** * <p> * 防止重复提交注解,用于方法上<br/> * 在新建页面方法上,设置needSaveToken()为true,此时拦截器会在Session中保存一个token, * 同时需要在新建的页面中添加 * <input type="hidden" name="token" value="${token}"> * <br/> * 保存方法需要验证重复提交的,设置needRemoveToken为true * 此时会在拦截器中验证是否重复提交 * </p> * @author: chuanli * @date: 2013-6-27上午11:14:02 * */ @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface AvoidDuplicateSubmission { boolean needSaveToken() default false; boolean needRemoveToken() default false; }
2. 新建拦截器
/** * <p> * 防止重复提交过滤器 * </p> * * @author: chuanli * @date: 2013-6-27上午11:19:05 */ public class AvoidDuplicateSubmissionInterceptor extends HandlerInterceptorAdapter { private static final Logger LOG = Logger.getLogger(AvoidDuplicateSubmissionInterceptor.class); @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { User user = UserUtil.getUser(); if (user != null) { HandlerMethod handlerMethod = (HandlerMethod) handler; Method method = handlerMethod.getMethod(); AvoidDuplicateSubmission annotation = method.getAnnotation(AvoidDuplicateSubmission.class); if (annotation != null) { boolean needSaveSession = annotation.needSaveToken(); if (needSaveSession) { request.getSession(false).setAttribute("token", TokenProcessor.getInstance().generateToken()); } boolean needRemoveSession = annotation.needRemoveToken(); if (needRemoveSession) { if (isRepeatSubmit(request)) { LOG.warn("please don't repeat submit,[user:" + user.getUsername() + ",url:" 4000 + request.getServletPath() + "]"); return false; } request.getSession(false).removeAttribute("token"); } } } return true; } private boolean isRepeatSubmit(HttpServletRequest request) { String serverToken = (String) request.getSession(false).getAttribute("token"); if (serverToken == null) { return true; } String clinetToken = request.getParameter("token"); if (clinetToken == null) { return true; } if (!serverToken.equals(clinetToken)) { return true; } return false; } }
3. 在Spring中配置
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"> <property name="interceptors"> <list> <bean class="com.sohu.tv.crm.aop.UserLogInterceptor"/> <bean class="com.sohu.tv.crm.aop.AvoidDuplicateSubmissionInterceptor"/> </list> </property> </bean>
4. 在相关方法中加入注解:
@RequestMapping("/save") @AvoidDuplicateSubmission(needRemoveToken = true) public synchronized ModelAndView save(ExecutionUnit unit, HttpServletRequest request, HttpServletResponse response) throws Exception { @RequestMapping("/edit") @AvoidDuplicateSubmission(needSaveToken = true) public ModelAndView edit(Integer id, HttpServletRequest request) throws Exception {
5.在新建页面中加入
<input type="hidden" name="token" value="${token}">
相关文章推荐
- Android真机连接Android studio或Eclipse输出不了日志问题
- spring AOP 的几种实现方式(能测试)
- 并发编程学习总结(六) :java 显式锁ReentrantLock使用详解之测试锁与超时
- myeclipse中的js文件报错
- Java中Class对象详解、类名.class、class.forName()、 getClass()区别
- 编程之美2.6精确表达浮点数Java版
- Eclipse Myeclipse 设定文件的默认打开方式
- spring 时间格式化注解@DateTimeFormat @JsonFormat
- java8中switch(String)的错误解决
- JAVA相关博客
- 主动获取spring容器工具类SpringContextUtil
- eclipse老版本加入新SDK后出现问题
- javacv开发详解之1:调用本机摄像头视频(建议使用javaCV1.3.3版本)
- Java List<>排序——重载Collections.sort方法
- 把eclipse工程迁移到Android studio,build成功但run时报butterknife的错,error: duplicate class: class_name$$View(类重复)
- java的一些知识(六)
- red服务在Eclipse中配置
- java中用FileDialog打开文件并将内容添加到文本
- java对象转json
- java 快速排序