【参考博客:http://my.oschina.net/mushui/blog/143397】
原理:在新建页面中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:"
+ 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}">

拦截器springmvc防止表单重复提交【2】的更多相关文章

  1. 拦截器springmvc防止表单重复提交【1】

    [参考博客:http://www.cnblogs.com/hdwpdx/archive/2016/03/29/5333943.html] springmvc 用拦截器+token防止重复提交 首先,防 ...

  2. 拦截器springmvc防止表单重复提交【3】3秒后自动跳回首页【重点明白如何跳转到各自需要的页面没有实现 但是有思路】

    [1]定义异常类 [重点]:异常类有个多参数的构造函数public CmsException(String s, String... args),可以用来接受多个参数:如(“异常信息”,“几秒跳转”, ...

  3. 拦截器springmvc防止表单重复提交【3】自己实际项目

    1:[定义注解] package com.jspxcms.ext.interceptor; import java.lang.annotation.ElementType; import java.l ...

  4. springmvc防止表单重复提交demo

    原理:在去某个页面直接生成一个随机数(这里使用的是UUID)并放入session中,用户提交表单时将这个随机数传入服务端与session中的值进行比较,如果不不存在或不相等,则认为是重复提交:如果相等 ...

  5. SpringMVC防止表单重复提交

    最近公司上线,有同志进行攻击,表当防重复提交也没有弄,交给我 ,本人以前也没弄过,知道大概的思路,但是那样实在是太麻烦了,虽然后面试过使用过滤器加拦截器实现,不过还是有点小麻烦. 后来在网上搜索后发现 ...

  6. spring boot 学习(七)小工具篇:表单重复提交

    注解 + 拦截器:解决表单重复提交 前言 学习 Spring Boot 中,我想将我在项目中添加几个我在 SpringMVC 框架中常用的工具类(主要都是涉及到 Spring AOP 部分知识).比如 ...

  7. 12、Struts2表单重复提交

    什么是表单重复提交 表单的重复提交: 若刷新表单页面, 再提交表单不算重复提交. 在不刷新表单页面的前提下: 多次点击提交按钮 已经提交成功, 按 "回退" 之后, 再点击 &qu ...

  8. java struts2入门学习--防止表单重复提交.OGNL语言学习

    一.知识点回顾 防止表单重复提交核心思想: 客户端和服务器端和写一个token,比较两个token的值相同,则非重复提交;不同,则是重复提交. 1.getSession三种方式比较: request. ...

  9. 防止Web表单重复提交的方法总结

    在Web开发中,对于处理表单重复提交是经常要面对的事情.那么,存在哪些场景会导致表单重复提交呢?表单重复提交会带来什么问题?有哪些方法可以避免表单重复提交? 表单重复提交的场景 1.场景一:服务端未能 ...

随机推荐

  1. hadoop20---代理另一种方式

    package cn.itcast_05_proxy.service; /** * 这是一个业务的接口,这个接口中的业务就是返回衣服的价格 */ public interface IBoss {//接 ...

  2. cordova 5.0版本说明

    2015/04/21发布Cordova 5.0.0! 1)插件从Cordova plugins registry(CPR)全部移到npm,并且重新命名 ***org.apache.cordova.* ...

  3. 文件操作工具类: 文件/目录的创建、删除、移动、复制、zip压缩与解压.

    FileOperationUtils.java package com.xnl.utils; import java.io.BufferedInputStream; import java.io.Bu ...

  4. VC++6.0调试简单快捷键

    编译——F7 重新编译——Ctrl+F7 设置断点 ——F9 取消断点——F9 删除所有断点——Ctrl+Shift+F9 开始调试——F5 进行下一次调试——F5 停止调试——Shift+F5 逐过 ...

  5. 解决com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Specified key was too long; max key length is 767 bytes异常

    错误截图: 解决方法: 用root进入mysql终端,执行以下命令: alter database hive character set latin1;

  6. AJAX基础知识点——思维导图

    如图 思维导图图片链接 http://www.edrawsoft.cn/viewer/public/s/4db2e712070147 有道云笔记链接 http://note.youdao.com/no ...

  7. ES6 Babel 简单使用

    ECMAScript 是 JS 的语言标准.而 ES6 是新的 JS 语法标准. PS:严格来说,ECMAScript 还包括其他很多语言的语言标准. ECMAScript 发展历史 1995年:EC ...

  8. 分享:自定义JAVA注解

    元注解 元注解指用来定义注解的注解,例如:@Retention @Target Inherited @Documented等等.最为重要和经常使用的是@Retention @Target. @Rete ...

  9. Android 中Json解析的几种框架(Gson、Jackson、FastJson、LoganSquare)使用与对比

    介绍 移动互联网产品与服务器端通信的数据格式,如果没有特殊的需求的话,一般选择使用JSON格式,Android系统也原生的提供了JSON解析的API,但是它的速度很慢,而且没有提供简介方便的接口来提高 ...

  10. InflateException:Bin file line #19:Error inflating class MyTextView

    InflateException:Bin file line #19:Error inflating class MyTextView 一.错误简介 为了实现TextView的跑马灯效果,我自己写了一 ...