SpingMVC使用拦截器防止表单重复提交

原理:
在Session中保存一个表单的唯一编号,将该编号放在一个隐藏域中,同其他数据一同提交。在提交表单后,通过拦截器或其他机制检查唯一编号,如果存在则说明表单是第一次提交,如果不存在则被重复提交(在第一次提交检查后就会从Session中移除该编号)。

步骤:1,生成两个拦截器;2,在表单中加入隐藏域;3,在对应的action中加入把隐藏赋值的代码;4,配置文件中做出响应配置。


//拦截器1,作为在添加的时候的拦截  
package com.tagsdata.tdshop.interceptor;  
  
import java.util.UUID;  
import javax.servlet.http.HttpServletRequest;  
import javax.servlet.http.HttpServletResponse;  
import org.springframework.web.servlet.HandlerInterceptor;  
import org.springframework.web.servlet.ModelAndView;  
public class ProductAddInteceptor implements HandlerInterceptor{  
  
    @Override  
    public void afterCompletion(HttpServletRequest arg0,  
            HttpServletResponse arg1, Object arg2, Exception arg3)  
            throws Exception {  
        // TODO Auto-generated method stub  
          
    }  
  
    @Override  
    public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1,  
            Object arg2, ModelAndView arg3) throws Exception {  
        // TODO Auto-generated method stub  
          
    }  
  
    @Override  
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response,  
            Object handler) throws Exception {  
        String token = getUUID();  
        request.getSession().setAttribute("post_token", token);  
System.out.println("放在session的token:"+token);  
        return true;  
    }  
  
    /** 
     * 随机获取UUID字符串(无中划线) 
     *  
     * @return UUID字符串 
     */  
    public static String getUUID() {  
        String uuid = UUID.randomUUID().toString();  
        return uuid.substring(0, 8) + uuid.substring(9, 13) + uuid.substring(14, 18) + uuid.substring(19, 23) + uuid.substring(24);
	}
}


//拦截器2,作为校验表单隐藏域跟session的uuid是否相同  
package com.tagsdata.tdshop.interceptor;  
  
import java.util.UUID;  
import javax.servlet.http.HttpServletRequest;  
import javax.servlet.http.HttpServletResponse;  
import org.springframework.web.servlet.HandlerInterceptor;  
import org.springframework.web.servlet.ModelAndView;  
  
public class ProductSaveInteceptor implements HandlerInterceptor {  
  
    @Override  
    public void afterCompletion(HttpServletRequest arg0,  
            HttpServletResponse arg1, Object arg2, Exception arg3)  
            throws Exception {  
        // TODO Auto-generated method stub  
System.out.println("执行afterCompletion方法");  
        //arg1.sendRedirect("common/error");  
          
    }  
  
    @Override  
    public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1,  
            Object arg2, ModelAndView arg3) throws Exception {  
System.out.println("执行postHandle方法");  
  
    }  
  
    @Override  
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response,  
            Object handler) throws Exception {  
        String session_token = (String) request.getSession().getAttribute("post_token");  
        String post_token =request.getParameter("post_token");  
System.out.println("session跟form对比:"+session_token.equalsIgnoreCase(post_token));  
        if(session_token.equalsIgnoreCase(post_token)){  
            request.getSession().removeAttribute(post_token);  
            String token = getUUID();  
            request.getSession().setAttribute("post_token", token);  
System.out.println("============cross interceptor========");  
            return true;  
        }  
        //throw new Exception("duplicated");  
        //response.sendRedirect("/WEB-INF/template/common/error.ftl");  
        request.getRequestDispatcher("/WEB-INF/template/common/error.ftl").forward(request, response);  
        return false;  
    }  
      
    /** 
     * 随机获取UUID字符串(无中划线) 
     *  
     * @return UUID字符串 
     */  
    public static String getUUID() {  
        String uuid = UUID.randomUUID().toString();  
        return uuid.substring(0, 8) + uuid.substring(9, 13) + uuid.substring(14, 18) + uuid.substring(19, 23) + uuid.substring(24);
	}
}


在商品添加的表单中加入一个隐藏域,接收token数据   :<input type="hidden" name="post_token" value="${post_token!}" />


// 添加  
@RequestMapping(value = "/add", method = RequestMethod.GET)  
public String add(HttpServletRequest request) {  
    //拿到拦截器放在session的内容,放在隐藏域中  
    String post_token = (String) request.getSession().getAttribute("post_token");  
    request.setAttribute("post_token", post_token);</span>  
    return VIEW_PATH + "product_Type_input";  
} 

//配置文件中,加入相应的拦截  
    <!-- 防止重复提交 -->  
   <mvc:interceptors>  
        <mvc:interceptor>  
            <mvc:mapping path="/product**/add/**"/>  
            <mvc:mapping path="/product**/edit/**"/>  
            <bean class="com.tagsdata.tdshop.interceptor.ProductAddInteceptor"/>  
        </mvc:interceptor>  
        <mvc:interceptor>  
            <mvc:mapping path="/product**/save/**"/>  
            <mvc:mapping path="/product**/update/**"/>  
            <bean class="com.tagsdata.tdshop.interceptor.ProductSaveInteceptor"/>  
        </mvc:interceptor>  
    </mvc:interceptors>  


PS:要是拦截不成功,可在拦截器上做出一些打印字符,看看控制台是否有出现打印字符,若没有,则可能是隐藏域没有赋值。
拦截器的执行顺序是:preHandle方法——true时,执行action,然后postHandle方法——最后afterCompletion方法;
 ——false时,就不执行下去。
根据执行顺序可以在返回false之前作出跳转处理,有以下三种方法:
//1,抛出异常,然后在配置文件中,作出异常处理
throw new Exception("duplicated");
//2.response跳转
response.sendRedirect("/WEB-INF/template/common/error.ftl");
//3.request跳转
request.getRequestDispatcher("/WEB-INF/template/common/error.ftl").forward(request, response);
以上三种方法建议第三种,读者也可根据自己的需要选择。
最后,因为这个是SpringMVC整合freemarker,可能有很多不足的地方没说到,希望读者勿喷,做此文只是为了交流。


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值