spring防止F5刷新提交重复表单,为form加入参数token

直接上代码.

创建一个类: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、付费专栏及课程。

余额充值