spring防止F5重复提交相同表单通用代码

直接上代码.

创建一个类:Form:

package form;

import java.io.Serializable;
import java.util.Date;


import org.apache.commons.lang.builder.ToStringBuilder;
/** 
 * 表单类 
 * 
 * @author DigitalSonic 
 */  
public class Form implements Serializable {  
    /** 
     * serialVersionUID 
     */  
    private static final long   serialVersionUID        = 8796758608626021150L;  
    public static final String  FORM_UNIQ_ID_FIELD_NAME = "_form_uniq_id";  
    /** 表单标识*/  
    private String              token;  
    /** 表单创建时间*/  
    private Date                createTime;  
    /** 
     * 构造函数 
     */  
    public Form(String token) {  
        this.token = token;  
        this.createTime = new Date();  
    }  
    public String toString() {  
        return ToStringBuilder.reflectionToString(this);  
    }  
    public String getToken() {  
        return token;  
    }  
    public Date getCreateTime() {  
        return createTime;  
    }  

}  


创建一个接口:

package form;
import javax.servlet.http.HttpServletRequest;  


import org.aioframework.web.form.entity.Form;
/** 
 * 表单管理器,负责管理Session中的表单。 
 * 
 * @author DigitalSonic 
 */  


public interface FormManager {  
    /** 
     * 生成一个新的表单 
     */  
    public Form newForm(HttpServletRequest request);  
    /** 
     * 判断表单是否存在。 
     */  
    public boolean hasForm(HttpServletRequest request, String token);  
    /** 
     * 访问参数中是否存在表单Token。 
     */  
    public boolean hasFormToken(HttpServletRequest request);  
    /** 
     * 销毁一个表单 
     */  
    public void destroyToken(HttpServletRequest request, String token);  
    /** 
     * 打印表单信息。 
     */  
    public String dumpForm(HttpServletRequest request, String token);  
}  


创建类FormManager Impl实现自定义接口FormManager :

import java.util.ArrayList;  
import java.util.HashMap;  
import java.util.List;  
import java.util.Map;  


import javax.servlet.http.HttpServletRequest;  
import javax.servlet.http.HttpSession;  


import org.aioframework.web.form.entity.Form;
import org.aioframework.web.form.service.FormManager;
import org.apache.commons.lang.RandomStringUtils;  
import org.apache.commons.lang.StringUtils;  
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
/** 
 * 表单管理器实现类 
 * 
 * @author DigitalSonic 
 */  
@Service("formManager")
@Transactional
public class FormManagerImpl implements FormManager {  
    private static final String SESSION_KEY_OF_FROMS = "_forms_in_session";  
    /** 表单最大个数 */  
    private int                 maxFormNum           = 7;  
      
    /** 
     * 销毁一个表单 
     */  
    public void destroyToken(HttpServletRequest request, String token) {  
        getForms(request).remove(token);  
    }  
    /** 
     * 打印表单信息。 
     */  
    public String dumpForm(HttpServletRequest request, String token) {  
        Form form = getForms(request).get(token);  
        if (form == null) {  
            return "null";  
        }  
        return form.toString();  
    }  
    /** 
     * 判断表单是否存在。如果token为null,直接返回false。 
     * 
     * @see #getForms(HttpServletRequest) 
     */  
    public boolean hasForm(HttpServletRequest request, String token) {  
        if (token == null) {  
            return false;  
        }  
        return getForms(request).containsKey(token);  
    }  
      
    /** 
     * 访问参数中是否存在表单Token。 
     */  
    public boolean hasFormToken(HttpServletRequest request) {  
        String formToken = request.getParameter(Form.FORM_UNIQ_ID_FIELD_NAME);  
        return StringUtils.isNotBlank(formToken);  
    }  
    /** 
     * 生成一个新的表单,如果目前表单个数大于设定的最大表单数则先删除最早的一个表单。<br> 
     * 新表单用RandomStringUtils.randomAlphanumeric(32)生成Token。 
     * 
     * @return 创建的新表单 
     * @see #removeOldestForm(HttpServletRequest) 
     * @see org.apache.commons.lang.RandomStringUtils#random(int) 
     */  
    public Form newForm(HttpServletRequest request) {  
        Form form = new Form(RandomStringUtils.randomAlphanumeric(32));  
        Map<String, Form> forms = getForms(request);  
        synchronized (forms) {  
            // 如果目前表单个数大于等于最大表单数,那么删除最老的表单,添加新表单。  
            if (forms.size() >= maxFormNum) {  
                removeOldestForm(request);  
            }  
            forms.put(form.getToken(), form);  
        }  
        return form;  
    }  
    /** 
     * 获得目前session中的表单列表。 
     * 
     * @return 返回的Map中以表单的token为键,Form对象为值 
     */  
    @SuppressWarnings("unchecked")  
    protected Map<String, Form> getForms(HttpServletRequest request) {  
        Map<String, Form> formsInSession = null;  
        HttpSession session = request.getSession();  
        synchronized (session) {  
            formsInSession = (Map<String, Form>) session.getAttribute(SESSION_KEY_OF_FROMS);  
            if (formsInSession == null) {  
                formsInSession = new HashMap<String, Form>();  
                session.setAttribute(SESSION_KEY_OF_FROMS, formsInSession);  
            }  
        }  
        return formsInSession;  
    }
    /** 
     * 删除最老的Form 
     * 
     * @see #destroyToken(HttpServletRequest, String) 
     */  
    protected void removeOldestForm(HttpServletRequest request) {  
        List<Form> forms = new ArrayList<Form>(getForms(request).values());  
        if (!forms.isEmpty()) {  
            Form oldestForm = forms.get(0);  
            for (Form form : forms) {  
                if (form.getCreateTime().before(oldestForm.getCreateTime())) {  
                    oldestForm = form;  
                }  
            }  
            destroyToken(request, oldestForm.getToken());  
        }  
    }  
    public void setMaxFormNum(int maxFormNum) {  
        this.maxFormNum = maxFormNum;  
    }  
}


sping配置文件增加:

<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**" />
<bean class="form.EncodingInterceptor" />
</mvc:interceptor>

</mvc:interceptors>

EncodingInterceptor为自定义的类,代码如下:

package form;


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


import org.aioframework.web.form.entity.Form;
import org.aioframework.web.form.service.FormManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;


/**
 * 字符集拦截器
 * 
 */
public class EncodingInterceptor implements HandlerInterceptor {
@Autowired
private FormManager formManager;
/**
* 在controller后拦截
*/
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object object, Exception exception) throws Exception {


}


public void postHandle(HttpServletRequest request, HttpServletResponse response, Object object, ModelAndView modelAndView) throws Exception {


}


/**
* 在controller前拦截
*/
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object object) throws Exception {
   request.setCharacterEncoding("UTF-8");
   response.setCharacterEncoding("UTF-8");
   boolean flag = true;  
           String token = request.getParameter(Form.FORM_UNIQ_ID_FIELD_NAME);  
           if (token != null && !"".equals(token)) { 
                if (formManager.hasForm(request, token)) {  
                     formManager.destroyToken(request, token);  
                } else {
                     flag = false;  
                      throw new Exception("表单重复提交或过期,令牌[" + token + "]");  
                 }
            }
            return flag;  
}
}


使用发放:

到表单页面的方法中增加代码:

Form from = formManager.newForm(request);
request.setAttribute("token", from.getToken());


页面中的form表单中增加一个input:

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


复制粘贴后修改下包名可以直接使用。



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值