Spring MVC拦截器+注解方式实现防止表单重复提交

原理:在新建页面中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.在新建页面中加入


1

     <input type="hidden" name="token" value="${token}">

转自:http://my.oschina.net/mushui/blog/143397

特别说明:尊重作者的劳动成果,转载请注明出处哦~~~http://blog.yemou.net/article/query/info/tytfjhfascvhzxcyt335

时间: 2024-10-29 03:01:58

Spring MVC拦截器+注解方式实现防止表单重复提交的相关文章

php记录IP方式来防止表单重复提交

例子  代码如下 复制代码 <?php session_start(); if(empty($_SESSION['ip']))//第一次写入操作,判断是否记录了IP地址,以此知道是否要写入数据库 { $_SESSION['ip']=$_SERVER['REMOTE_ADDR'];//第一次写入,为后面刷新或后退的判断做个铺垫 ...........//写入数据库操作 } else//已经有第一次写入后的操作,也就不再写入数据库 { echo '请不要重复提交表单或刷新页面';//写一些已经写入的

Spring MVC拦截器实现分析

Spring MVC拦截器实现分析 一.Servlet Filter与Spring interceptor的执行顺序 Filter有顺序吗?我们怎么控制filter的执行顺序.通过Tomcat的代码分析,servlet在Filter执行完成后才调用,如有多个filter怎么控制执行顺序,首先会想到在web.xml配置某个参数,例如order之类的,但查找一下一番,servlet并没有这个参数.试试filter Mapping的配置的先后顺序,果然有效,原来filter的执行顺序就考filter

spring MVC拦截器01

spring MVC拦截 作用:身份校验,权限检查,防止非法访问. 场景:一个bbs系统,用户没有登录就无法发帖或者删除评论; 一个博客系统,没有登录就无法发表博文,无法增加分类,无法删除博文. spring MVC 拦截实现分为2步 (1)编写拦截器类,必须继承org.springframework.web.servlet.HandlerInterceptor 核心方法: public boolean preHandle(HttpServletRequest request, HttpServ

自定义 spring mvc 拦截器(近期项目需求实现)

          需求背景:特定文件夹下任何文件不经过登录,全部拦截强制跳转登录,并客户端禁止下载服务器定制文件夹文件           经过1天多时间的各种尝试,自定义式的强大拦截器实现了,废话不说了,直接贴代码啦.    demo:       1>   根目录下 index.html 内容:               <a href="html/index.html">index</a><br/>              <

spring mvc拦截器无法拦截DWZ的请求,求指点。。。

问题描述 拦截器是这样配置的: <mvc:interceptors> <mvc:interceptor> <mvc:mapping path="/*" > </mvc:mapping>如果不配置或/*,将拦截所有的Controller <bean class="com.hangzhou.controller.interceptor.LoginInterceptor"></bean> </m

Struts2 自定义拦截器栈后无法得到表单参数之解决办法

我自定义了一个拦截器,目的是在action执行之前像ValueStack中设置一些属性,代码是这样的: view plaincopy to clipboardprint? HttpServletRequest request=(HttpServletRequest)ActionContext.getContext().get(StrutsStatics.HTTP_REQUEST);        OgnlValueStack stack=(OgnlValueStack)request.getAt

spring mvc 拦截器路径问题,只拦截固定后缀

拦截固定后缀  匹配url正确配置为 /**/*.htm     错误:**.htm    /**.htm   *.htm  <mvc:interceptors> <!-- <bean class="com.host.app.web.interceptor.AllInterceptor"/> --> <mvc:interceptor> <mvc:mapping path="/**/*.htm" /><

spring mvc拦截器页面不跳转问题

问题描述 就是不跳转到我指定的Controller上.请教大神.publicbooleanpreHandle(HttpServletRequestrequest,HttpServletResponseresponse,Objectobject)throwsException{StringrequestPath=ResourceUtil.getRequestPath(request);//用户访问的资源地址System.out.println(requestPath+"--->访问路径&qu

path-spring Mvc 拦截器拦截不成功

问题描述 spring Mvc 拦截器拦截不成功 拦截不成功,各位大神帮忙看下配置有没错.这样配置可不可以拦截 解决方案 你这样太麻烦了,用springMVC的统一拦截器,然后在controller层中加注解就行了 过程如下:http://blog.csdn.net/evankaka/article/details/45501811 解决方案二: spring MVC - Inteceptors(拦截器)spring MVC - Inteceptors(拦截器) 解决方案三: ,用springM