利用Session防止表單重複提交

解決項目中表單重複提交的問題,在平常的項目中有以下幾種可能出現表單重複提交的情況,比如說:
 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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章