解決項目中表單重複提交的問題,在平常的項目中有以下幾種可能出現表單重複提交的情況,比如說:
1 由於服務器緩慢或者網絡延遲的原因,重複點擊提交按鈕
2 已經提交成功,但是還不停刷新成功頁面
3 已經提交成功,通過回退,再次點擊提交按鈕。
這些情況都可能使數據庫中產生過多相同的冗餘數據,浪費數據庫資源。只有轉發纔會出現,重定向則不會。
針對第一種情況的解決方案(使用JavaScript),對後面兩種無效:
首先在頁面中添加如下格式的JavaScript代碼
<script type="text/javascript">
var submitFlag=false;
function checksubmit(){
if(!submitFlag){
submitFlag=true;
document.forms[0].submit();
}
}
</script>
(1)當提交按鈕的type屬性爲button時:
設置按鈕的onClick=”checksubmit();”即可。
(2)當提交按鈕的type屬性爲submit時:
設置按鈕的onClick=”checksubmit();”,並在<form>標籤中增加οnsubmit=”return false”。因爲submit按鈕的自動提交時在點擊事件提交之後,將onsubmit設置爲”return false”,submit按鈕的自動提交就會失效。
對於後面兩種情況,可以使用session解決,其原理是在運行添加信息頁面時在session中放置信息,然後頁面提交信息給servlet處理,servlet獲取session中的信息,如果session中有信息不爲空則將信息插入數據庫,然後刪除session中的信息,下次再提交表單時session中的信息爲空,那麼則不執行存儲信息過程。
但是單純使用session有其侷限性,所以在實際開發中,一般使用利用session結合UUID解決表單的重複提交,代碼如下:
定義一個UuidToken類
public class UuidToken {
private static UuidToken UuidToken=new UuidToken();
private UuidToken(){
}
public static UuidToken getUuidToken() {
return UuidToken;
}
public synchronized String getUUIDAsStr(HttpServletRequest request){
HttpSession session=request.getSession();
String uuidStr=UUID.randomUUID().toString();
if(uuidStr!=null){
session.setAttribute("session.uuid", uuidStr);
}
return uuidStr;
}
/**
* 判斷session中保存的uuid和jsp頁面上的uuid是否相等
*/
public synchronized boolean isUUIDValidate(HttpServletRequest request) {
//獲取已存在的session
HttpSession session=request.getSession(false);
if(session==null){
return false;
}
String sessionuuid = (String)session.getAttribute ("session.uuid");
if(sessionuuid==null){
return false;
}
String htmluuid=request.getParameter("html.uuid");
if(htmluuid==null){
return false;
}
return sessionuuid.equals(htmluuid);
}
/**
* 刪除uuid
*/
public synchronized void resetUUID(HttpServletRequest request) {
HttpSession session=request.getSession(false);
if(session==null){
return;
}
session.removeAttribute("session.uuid");
}
}
在jsp頁面增加一個隱藏域,利用uuid生成一個唯一的標識號,賦給隱藏域,把唯一的標識號 放置到session中一份,代碼如下:
<input type="hidden" name="html.uuid" value='<%=UuidToken.getUuidToken().getUUIDAsStr(request)%>'>
提交給servlet後,獲取 jsp頁隱藏域的值,用隱藏域的值和session中放置的值做比對,如果相同,保存數據並從session中刪除UUID,不相同則說明是重複提交,不進行處理。
boolean flag= UuidToken.getUuidToken().isUUIDValidate(request);
if(flag){
// 保存信息到數據庫
//從session刪除uuid的
UuidToken.getUuidToken().resetUUID(request);
}else{
System.out.println("表單重複提交");
}
本文來自CSDN博客,轉載請標明出處:http://blog.csdn.net/liuxiaolei7676/archive/2010/06/03/5646165.aspx