您的位置:首页 > Web前端 > JavaScript

表单重复提交的问题

2017-02-08 10:50 274 查看
       先参考这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";
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  jsp 表单重复提交