表单重复提交的问题

       先参考这3篇博文

http://blog.csdn.net/gideal_wang/article/details/4189694

http://developer.51cto.com/art/201311/417014.htm

http://www.cnblogs.com/xdp-gacl/p/3859416.html 

下面通过注解和拦截器来实现该功能:

package com.nasuxwx.plug.web.formtoken;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * 验证form表单重复提交注解
 * @title FormToken.java
 * @since 2015年11月13日
 */
@Documented
@Inherited
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface FormToken {

	/**
	 * 是否移除formToken参数,默认false:不移除
	 * @title isRemove
	 * @author dinggh
	 * @since 2015年11月13日
	 * @return
	 */
	boolean isRemove() default false;
	
	/**
	 * 是否添加formToken参数,默认false:不添加
	 * @title isAdd
	 * @author dinggh
	 * @since 2015年11月13日
	 * @return
	 */
	boolean isAdd() default false;
}

package com.nasuxwx.plug.web.formtoken;

import java.io.PrintWriter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import com.nasuxwx.plug.util.FormTokenProccessor;

/**
 * 验证form表单重复提交
 * @title FormTokenInterceptor.java
 * @since 2015年11月13日
 */
public class FormTokenInterceptor extends HandlerInterceptorAdapter{
	private Logger logger = LoggerFactory.getLogger(FormTokenInterceptor.class);
	/**
	 * 验证form表单重复提交,如果未重复提交则移除session中的formToken
	 */
	@Override
	public boolean preHandle(HttpServletRequest request,
			HttpServletResponse response, Object handler) throws Exception {
		// TODO Auto-generated method stub
		
		if (handler.getClass().isAssignableFrom(HandlerMethod.class)) {
			FormToken preFormToken = ((HandlerMethod) handler).getMethodAnnotation(FormToken.class);
			
			//声明需要防止表单重复提交,并且需要移除参数
	        if (preFormToken!=null&&preFormToken.isRemove()) {
	        	String formToken = (String) request.getSession().getAttribute("formToken");
	    		String clientFormToken = request.getParameter("formToken");
	    		
	    		boolean isRepeatSubmit = false;
	    		if (StringUtils.isBlank(formToken)) {
	    			isRepeatSubmit = true;
	    		}
	    		
	    		if (StringUtils.isBlank(clientFormToken)) {
	    			isRepeatSubmit = true;
	    		}
	    		
	    		if (StringUtils.isNotBlank(clientFormToken)&&!clientFormToken.equals(formToken)) {
	    			isRepeatSubmit = true;
	    		}
	    		
	    		if (isRepeatSubmit) {
	    			logger.info("form表单重复提交!" + request.getServletPath());
	    			response.reset();
	    			PrintWriter out = response.getWriter();
	    			out.print("FORM_REPEAT_SUBMIT");
	    			out.flush();
	    			out.close();
	    			request.getSession().setAttribute("formValid", false);
	    			return false;
				}else {
					request.getSession().removeAttribute("formToken");
				}
			}
	        
		}
		
		return super.preHandle(request, response, handler);
	}

	/**
	 * 设置formToken到session中
	 */
	@Override
	public void postHandle(HttpServletRequest request,
			HttpServletResponse response, Object handler,
			ModelAndView modelAndView) throws Exception {
		// TODO Auto-generated method stub
		if (handler.getClass().isAssignableFrom(HandlerMethod.class)) {
			FormToken preFormToken = ((HandlerMethod) handler).getMethodAnnotation(FormToken.class);
			
			//声明需要防止表单重复提交,并且需要添加参数
	        if (preFormToken!=null&&preFormToken.isAdd()) {
	        	String formTokenStr = FormTokenProccessor.getInstance().makeToken();
	        	request.getSession().setAttribute("formToken", formTokenStr);
			}
			
		}
		super.postHandle(request, response, handler, modelAndView);
	}

	
	
}
package com.nasuxwx.plug.util;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Random;

import sun.misc.BASE64Encoder;

/**
 * form 表单验证令牌
 * @title FormTokenProccessor.java
 * @since 2015年11月12日
 */
public class FormTokenProccessor {

    /*
     *单例设计模式(保证类的对象在内存中只有一个)
     *1、把类的构造函数私有
     *2、自己创建一个类的对象
     *3、对外提供一个公共的方法,返回类的对象
     */
    private FormTokenProccessor(){}
    
    private static final FormTokenProccessor instance = new FormTokenProccessor();
    
    /**
     * 返回类的对象
     * @return
     */
    public static FormTokenProccessor getInstance(){
        return instance;
    }
    
    /**
     * 生成Token
     * Token:Nv6RRuGEVvmGjB+jimI/gw==
     * @return
     */
    public String makeToken(){  //checkException
        //  7346734837483  834u938493493849384  43434384
        String token = (System.currentTimeMillis() + new Random().nextInt(999999999)) + "";
        //数据指纹   128位长   16个字节  md5
        try {
            MessageDigest md = MessageDigest.getInstance("md5");
            byte md5[] =  md.digest(token.getBytes());
            //base64编码--任意二进制编码明文字符   adfsdfsdfsf
            BASE64Encoder encoder = new BASE64Encoder();
            return encoder.encode(md5);
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException(e);
        }
    }
}
	/**
	 * 绑定银行卡信息填写页面
	 * @title toPtpMerBindCardPage
	 * @since 2015年10月19日
	 * @param page
	 * @param request
	 * @param model
	 * @return
	 */
	@FormToken(isAdd=true)
	@RequestMapping("/toPtpMerBindCardPage.nasuxwx")
	public String toPtpMerBindCardPage(Integer page,HttpServletRequest request,Model model){
		Site site = Context.getCurrentSite(request);
		
		String url = site.getTemplate("ump/toPtpMerBindCardPage.html");
		PPUser pPUser = (PPUser) request.getSession().getAttribute("user");
		
		String orderIdPre = request.getParameter(NasuxConstant.UMPPARAM);
		if (StringUtils.isBlank(orderIdPre)) {
			orderIdPre = request.getParameter("orderIdPre");
		}
		model.addAttribute("orderIdPre", orderIdPre);
		if (pPUser!=null) {
			model.addAttribute("UserId", pPUser.getId());
				
		}else {
			return "forward:/weixin/register.nasuxwx";
		}
		
		return url;
	} 
	/**
	 * 绑定银行卡
	 * @since 2015年10月19日
	 * @param page
	 * @param request
	 * @param model
	 * @return
	 */
	@FormToken(isRemove=true)
	@RequestMapping("/ptpMerBindCard.nasuxwx")
	//@ResponseBody
	public String ptpMerBindCard(Integer page,HttpServletRequest request,Model model){
		String url = "";
		PPUser pPUser = (PPUser) request.getSession().getAttribute("user");
		
		Map<String, String> paramMap = new HashMap<String, String>();
		String cardId = request.getParameter("cardId");//用户在页面中输入的绑定的银行卡号
		cardId = StringUtils.trim(cardId);
		paramMap.put("card_id", cardId);
		
		//String bankName = request.getParameter("bankName");
		/*String msg = this.checkBankCardNo(cardId, bankName);
		if (!"1".equals(msg)) {
			return msg;
		}*/
		
		String orderIdPre = request.getParameter("orderIdPre");
		paramMap.put("orderIdPre", orderIdPre);
		
		url = this.umpService.ptpMerBindCard(paramMap, pPUser);
		
		return "redirect:"+url;
	}

下面是一些JS调用验证的方法

/**
 * 重置formToken
 */
function resetFormToken(){
	
	$.ajax({
        type: "POST",
        url:"/formtoken/resetFormToken.nasuxwx?_t="+new Date(),
        data:$("#registerForm").serialize(),// 要提交的表单 
        success: function(msg) {
        	if(msg){
        		var formTokenInputs = $("input[name='formToken']");
        		$.each(formTokenInputs,function(i,formTokenInput){
        			$(formTokenInput).val(msg);
        		});
        	}
        }
        
	});
}

function validFormTokenAndSubmitForm(formToken,formName){
	$.ajax({
        type: "POST",
        url:"/formtoken/validFormToken.nasuxwx?_t="+new Date(),
        data:{"formToken":formToken},// 要提交的表单 
        success: function(msg) {
        	if(msg&&msg=="true"){
        		$("#"+formName).submit();
        	}
        }
        
	});
}
package com.nasuxwx.plug.web.formtoken;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class FormTokenController {

	@FormToken(isAdd=true)
	@RequestMapping("/formtoken/resetFormToken.nasuxwx")
	@ResponseBody
	public String resetFormToken(HttpServletRequest request){
		String formToken = (String) request.getSession().getAttribute("formToken");
		return formToken;
	}
	
	@RequestMapping("/formtoken/validFormToken.nasuxwx")
	@ResponseBody
	public String validFormToken(HttpServletRequest request,
			@RequestParam(value="formToken")String clientFormToken){
		
		String formToken = (String) request.getSession().getAttribute("formToken");
		boolean isRepeatSubmit = false;
		if (StringUtils.isBlank(formToken)) {
			isRepeatSubmit = true;
		}
		
		if (StringUtils.isBlank(clientFormToken)) {
			isRepeatSubmit = true;
		}
		
		if (StringUtils.isNotBlank(clientFormToken)&&!clientFormToken.equals(formToken)) {
			isRepeatSubmit = true;
		}
		
		return !isRepeatSubmit?"true":"false";
	}
}







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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值