利用SpringMVC定义拦截器实现防止重复提交

之前谈到过前端页面防止重复提交的方法,现在谈谈后端拦截器实现方式。

自定义拦截器实现以下防重原理:

1.初始化页面时生成一个唯一ID,将其放在页面隐藏域和session中
2.拦截器拦截请求,校验来自页面请求中的唯一ID与session中的ID是否一致

3.判断,如果一致则提交成功并移除session中的ID,不一致则说明重复提交并记录日志

一、自定义注解

package com.test.sub.repeatsubmit;  
  
import java.lang.annotation.ElementType;  
import java.lang.annotation.Retention;  
import java.lang.annotation.RetentionPolicy;  
import java.lang.annotation.Target;  
  
@Target(ElementType.METHOD)  
@Retention(RetentionPolicy.RUNTIME)  
public @interface Token {  
      
    boolean save() default false;  
    boolean remove() default false;  
      
} 
二、自定拦截器
    package com.test.sub.repeatsubmit;  
      
    import java.lang.reflect.Method;  
    import java.util.UUID;  
      
    import javax.servlet.http.HttpServletRequest;  
    import javax.servlet.http.HttpServletResponse;  
      
    import org.apache.log4j.Logger;  
    import org.springframework.web.method.HandlerMethod;  
    import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;  
      
    public class RepeatSubmitInterceptor  extends HandlerInterceptorAdapter{  
          
        private static final Logger log = Logger.getLogger(RepeatSubmitInterceptor.class);  
          
        @Override  
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)  
            throws Exception {  
            HandlerMethod handlerMethod = null;  
            try {  
                handlerMethod = (HandlerMethod)handler;  
            } catch (Exception e) {  
                return true;  
            }  
            Method method = handlerMethod.getMethod();  
              
            Token token = method.getAnnotation(Token.class);  
            if(token != null ){  
                boolean saveSession = token.save();  
                if(saveSession){  
                    request.getSession(true).setAttribute("token", UUID.randomUUID());  
                }  
                  
                boolean removeSession = token.remove();  
                if(removeSession){  
                    if(isRepeatSubmitSession(request)){  
                        log.info("repeat submit session :"+request.getServletPath());  
                        return false;  
                    }  
                    request.getSession(true).removeAttribute("token");  
                }  
            }  
            return true;  
        }  
          
        private boolean isRepeatSubmitSession(HttpServletRequest request){  
            String sessionToken = String.valueOf(request.getSession(true).getAttribute("token"));  
            String clientToken =  String.valueOf(request.getParameter("token"));  
            if(sessionToken == null || sessionToken.equals("")){  
                return true;  
            }  
            if(clientToken == null || clientToken.equals("")){  
                return true;  
            }  
            if(!sessionToken.equals(clientToken)){  
                return true;  
            }  
            return false;  
        }  
      
    }  
三、初始化加载防重页面,生成唯一ID(代码片段)

    /** 
     * 打开新增或修改页面 
     * @return 
     */  
    @RequestMapping("showAddPage")  
    @Token(save=true)  
    public String showPlanAddPage(String rowId,int param,Model model) {...}  

四、页面隐藏域保存ID 或者 ajax提交时加入ID

    <!-- 表单提交 -->  
    <input type="hidden" name="token" value="${token }">  

    var data=encodeURI("name="+$('#name').val()+"&token=${token}");  
    $.ajax({  
       type: "POST",  
       async:true,  
       url: "${rootPath}/iminventoryplan/save",  
       data:data,  
       success: function(msg){  
        if(msg.result == 'true' || msg.result == true) {  
        $.messager.alert('提示',msg.msg,'info');  
        goBack(1);  
        }  
        else {  
        $.messager.alert('提示',msg.msg,'error');  
        $('#appsave').linkbutton('enable');  
        goBack(1);  
        }  
        }  
    });  

五、需要防重校验的方法

    /** 
    * 保存新增或修改的记录,将其持久化到数据库中 
    * @return 
    */  
    @RequestMapping("/save")  
    @ResponseBody  
    @Token(remove=true)  
    public Map<String,String> saveTkiminventoryplanInfo(HttpServletRequest request){...}  
六、Spring加入拦截器配置

<mvc:interceptor>  
    <mvc:mapping path="/**" />  
    <bean class="com.test.sub.repeatsubmit.RepeatSubmitInterceptor" ></bean>  
</mvc:interceptor> 


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值