java mvc中重复提交表单,spring mvc 防止重复提交表单的两种方法,推荐第二种
第一種方法:判斷session中保存的token
比較麻煩,每次在提交表單時(shí)都必須傳入上次的token。而且當(dāng)一個(gè)頁面使用ajax時(shí),多個(gè)表單提交就會(huì)有問題。
注解Token代碼:
package com.thinkgem.jeesite.common.repeat_form_validator;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 頁面form token
* @author Administrator
*
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface FormToken {
boolean save() default false;
boolean remove() default false;
}
攔截器TokenInterceptor代碼:
package com.thinkgem.jeesite.common.repeat_form_validator;
import java.lang.reflect.Method;
import java.util.UUID;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
public class FormTokenInterceptor extends HandlerInterceptorAdapter {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
if (handler instanceof HandlerMethod) {
HandlerMethod handlerMethod = (HandlerMethod) handler;
Method method = handlerMethod.getMethod();
FormToken annotation = method.getAnnotation(FormToken.class);
if (annotation != null) {
boolean needSaveSession = annotation.save();
if (needSaveSession) {
request.getSession(false).setAttribute("formToken", UUID.randomUUID().toString());
}
boolean needRemoveSession = annotation.remove();
if (needRemoveSession) {
if (isRepeatSubmit(request)) {
return false;
}
request.getSession(false).removeAttribute("formToken");
}
}
return true;
} else {
return super.preHandle(request, response, handler);
}
}
private boolean isRepeatSubmit(HttpServletRequest request) {
String serverToken = (String) request.getSession(false).getAttribute("formToken");
if (serverToken == null) {
return true;
}
String clinetToken = request.getParameter("formToken");
if (clinetToken == null) {
return true;
}
if (!serverToken.equals(clinetToken)) {
return true;
}
return false;
}
}
然后在Spring MVC的配置文件里加入:
相關(guān)代碼已經(jīng)注釋,相信你能看懂。
關(guān)于這個(gè)方法的用法是:在需要生成token的controller上增加@FormToken(save=true),而在需要檢查重復(fù)提交的controller上添加@FormToken(remove=true)就可以了。
另外,你需要在view里在form里增加下面代碼:
已經(jīng)完成了,去試試看你的數(shù)據(jù)還能重復(fù)提交了吧。
注意在ajax提交時(shí) 要加上 formToken參數(shù)
第二種方法(判斷請求url和數(shù)據(jù)是否和上一次相同)
推薦,非常簡單,頁面不需要任何傳入,只需要在驗(yàn)證的controller方法上寫上自定義注解即可
寫好自定義注解
package com.thinkgem.jeesite.common.repeat_form_validator;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 一個(gè)用戶 相同url 同時(shí)提交 相同數(shù)據(jù) 驗(yàn)證
* @author Administrator
*
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface SameUrlData {
}
寫好攔截器
package com.thinkgem.jeesite.common.repeat_form_validator;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import com.thinkgem.jeesite.common.mapper.JsonMapper;
/**
* 一個(gè)用戶 相同url 同時(shí)提交 相同數(shù)據(jù) 驗(yàn)證
* 主要通過 session中保存到的url 和 請求參數(shù)。如果和上次相同,則是重復(fù)提交表單
* @author Administrator
*
*/
public class SameUrlDataInterceptor extends HandlerInterceptorAdapter{
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
if (handler instanceof HandlerMethod) {
HandlerMethod handlerMethod = (HandlerMethod) handler;
Method method = handlerMethod.getMethod();
SameUrlData annotation = method.getAnnotation(SameUrlData.class);
if (annotation != null) {
if(repeatDataValidator(request))//如果重復(fù)相同數(shù)據(jù)
return false;
else
return true;
}
return true;
} else {
return super.preHandle(request, response, handler);
}
}
/**
* 驗(yàn)證同一個(gè)url數(shù)據(jù)是否相同提交 ,相同返回true
* @param httpServletRequest
* @return
*/
public boolean repeatDataValidator(HttpServletRequest httpServletRequest)
{
String params=JsonMapper.toJsonString(httpServletRequest.getParameterMap());
String url=httpServletRequest.getRequestURI();
Map map=new HashMap();
map.put(url, params);
String nowUrlParams=map.toString();//
Object preUrlParams=httpServletRequest.getSession().getAttribute("repeatData");
if(preUrlParams==null)//如果上一個(gè)數(shù)據(jù)為null,表示還沒有訪問頁面
{
httpServletRequest.getSession().setAttribute("repeatData", nowUrlParams);
return false;
}
else//否則,已經(jīng)訪問過頁面
{
if(preUrlParams.toString().equals(nowUrlParams))//如果上次url+數(shù)據(jù)和本次url+數(shù)據(jù)相同,則表示城府添加數(shù)據(jù)
{
return true;
}
else//如果上次 url+數(shù)據(jù) 和本次url加數(shù)據(jù)不同,則不是重復(fù)提交
{
httpServletRequest.getSession().setAttribute("repeatData", nowUrlParams);
return false;
}
}
}
}
配置spring mvc
總結(jié)
以上是生活随笔為你收集整理的java mvc中重复提交表单,spring mvc 防止重复提交表单的两种方法,推荐第二种的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 微信分享朋友圈固定缩略图 php,微信转
- 下一篇: pytorch基于web端和C++的两种