?

基于Struts的Web系統表單重復提交問題的解決方案*

2010-03-21 06:19孔祥盛
河南工學院學報 2010年3期
關鍵詞:令牌表單瀏覽器

曹 琨,孔祥盛

(新鄉學院計算機與信息工程學院,河南新鄉453003)

瀏覽器用戶在使用基于Struts的Web應用系統時,由于網絡延遲使瀏覽器用戶認為Web應用系統響應失敗,導致用戶重復提交表單數據。由于表單數據的重復提交,導致網絡和服務器資源的浪費,并有可能導致數據庫數據冗余,嚴重時可導致服務器死機現象,如何避免表單數據重復提交顯得格外重要[1]。

1 Struts系統中表單重復提交問題的解決方案

基于Struts的Web應用系統避免表單重復提交有以下四種解決方案:

①使用Javascript解決表單重復提交問題;②使用Cookie解決表單重復提交問題;③使用Session解決表單重復提交問題;④使用Struts同步令牌Token解決表單重復提交問題。

第①種方案為瀏覽器端的解決方案,該方案可以防止用戶重復點擊提交按鈕產生的表單重復提交問題,該方案受瀏覽器端制約;第②、③、④種方案為服務器端的解決方案,這三種方案可以防止用戶刷新頁面產生的表單重復提交問題[2]。

1.1 使用Javascript解決表單重復提交問題

通過使用提交按鈕的onClicks事件檢測用戶的提交狀態可以解決表單重復提交問題[3]。實現方法是:當用戶點擊提交按鈕后,使用按鈕的onClick事件控制按鈕,將按鈕變為灰色失效狀態(圖1),用戶不能再次點擊提交按鈕,從而解決用戶重復點擊提交按鈕時造成的表單重復提交問題,實現代碼如下:

<form method="post"name="thisForm"action="test.do" >

<input name="text"type="text"/>

<input name="submitButton"value="提交"type="submit"

onClick="document.thisForm.submitButton.

value= '正在提交,請等待...';

document.thisForm.submitButton.disabled=true;document.thisForm.submit();"/>

</form>

圖1 使用onClick事件解決表單重復提交問題

另外還可以使用表單的onSubmit事件檢測用戶的提交狀態解決表單重復提交問題[3]。實現方法是:使用Javascript記錄表單的提交次數(默認為1),當表單提交次數大于1時,將彈出圖2所示的對話框,提示用戶已經提交表單,從而解決用戶重復點擊提交按鈕造成的表單重復提交問題,實現代碼如下:

<script language="javascript">

<!--

var submitcount=1;

function submitOnce(form){

if(submitcount==1){

submitcount++;

return true;

}else{

alert("正在操作,請不要重復提交表單數據!");

return false;

}

}

//-->

</script>

<form method="post"name="thisForm"action="test.do"onSubmit="return submitOnce(this)" >

<input name="text"type="text"/>

<input name="submitButton"value="提交"type="submit"/>

</form>

圖2 使用onSubmit事件解決表單重復提交問題

由于Javascript腳本程序運行在瀏覽器端,使用該方法可以防止用戶重復點擊提交按鈕導致的表單重復提交問題,但是由于用戶可以屏蔽瀏覽器Javascript腳本程序的運行,因此該方法僅適用于瀏覽器開啟了Javascript功能。當瀏覽器屏蔽了Javascript腳本程序運行時,可以選擇下面三種服務器端的解決方案。

1.2 使用Cookie解決表單重復提交問題

在Struts的Action中使用Cookie記錄表單提交的狀態可以解決表單重復提交問題[3],實現方法是:當用戶第一次點擊提交按鈕后觸發Struts中的Action代碼運行,該Action為瀏覽器用戶設置一個Cookie,然后運行業務邏輯代碼,最后取消該Cookie。在運行業務邏輯代碼的過程中,當用戶刷新頁面時,判斷Cookie是否已經存在,若存在,Action將頁面重定向到失敗頁面,從而解決用戶刷新頁面時造成的表單重復提交問題,實現代碼如下:

Cookie cookies[]=request.getCookies();

for(int i=0;i< cookies.length;i++){

Cookie cookie=cookies[i];

if("submitOnce".equals(cookie.getName())){

return mapping.findForward("failure");

}

}

Cookie cookie=new Cookie("submitOnce","submitOnce");

cookie.setMaxAge(60);

response.addCookie(cookie);

//業務邏輯代碼

cookie.setMaxAge(0);

由于Cookie信息保存在瀏覽器端,用戶可以阻止瀏覽器使用Cookie,因此該方法僅適用于瀏覽器開啟Cookie。當瀏覽器禁用Cookie時,可以選擇下面兩種服務器端的解決方案。

1.3 使用Session解決表單重復提交問題

在Struts的Action中使用Session記錄表單提交的狀態可以解決表單重復提交問題[3],實現步驟如下:

1)包含有form表單的頁面通過應用服務器程序動態生成,服務器程序為每次產生的form表單都分配一個唯一隨機標識號random,并在Session和form表單的一個隱藏域中進行保存。

2)當用戶提交form表單時,負責接收這一請求的Struts的Action程序比較form表單隱藏域中的標識號與存儲在Session中的標識號是否相同,當遇到下列情形時,Action程序將認為表單重復提交,Action程序將頁面重定向到失敗頁面:

當前用戶Session不存在表單標識;用戶提交的表單數據沒有標識號;存儲在當前用戶的Session中的標識號與表單數據中的標識號不同。

實現代碼如下:

1)產生random并把random放入session對象和隱藏域中。

<%

int random=(int)(10000*Math.random());

session.setAttribute("random",random);

%>

<form method="post"name="thisForm"action="test.jsp" >

<input name="text"type="text"/>

<input type="hidden"name="random"value="<%=random%>">

<input name="submitButton"value="提交"type="submit"/>

</form>

2)判斷是否重復提交的Struts的Action的代碼實現。

Session session=request.getSession();

if(request.getParameter("random")==null||session.getAttribute("random")==null){return mapping.findForward("failure");

}else{

int randomSession = ((Integer)session.getAttribute("random")).intValue();

int randomRequest=Integer.parseInt(request.get-Parameter("random"));

if(randomSession!=randomRequest){

return mapping.findForward("failure");

}else{

//業務邏輯代碼

}

}

由于Session信息保存在服務器端,瀏覽器用戶無法干預Session的使用,因此該方法適用于任何場景。

1.4 通過Struts同步令牌Token解決表單重復提交問題

Struts的Action提供了另一個防止表單重復提交的方法,即同步令牌(Token)機制[4]。在 Struts中,通過TokenProcessor類來創建和處理令牌,Struts根據用戶會話ID和當前系統時間生成一個唯一的同步令牌(Token)。同步令牌機制的基本原理是[5]:應用服務器在處理到達的請求之前,會將請求中包含的令牌值與保存在當前用戶會話Session中的令牌值進行比較,看是否匹配。在處理完該請求后,且在響應發送給瀏覽器端之前,會產生一個新的令牌,該令牌除傳給瀏覽器端以外,也會將用戶會話Session中保存的舊的令牌進行替換。這樣如果用戶回退到剛才的提交頁面并再次提交的話,瀏覽器端傳過來的令牌就和服務器端的令牌不一致,從而有效地避免表單重復提交問題的發生。

在Struts中使用同步令牌(Token)解決表單重復提交問題的步驟如下:

1)在轉發jsp頁面之前,創建一個新的同步令牌,方法如下:

saveToken(request);

在轉發 jsp頁面時,<htm l:form>會自動根據session中標識ID生成一個表單隱藏域同步令牌數據,防止重復提交表單,生成的表單隱藏域格式如下:

<input type=”hidden”name=”org.apache.struts.taglib.html.TOKEN”

value=”6aa35341f25184fd996c4c918255c3ae”>,其中的value是調用TokenProcessor類中的generateToken()方法獲得的。

2)在jsp頁面的表單提交處理Action中加入同步令牌判斷方法,代碼如下:

if(isTokenValid(request,true)){

//業務邏輯代碼

}else{

//表單重復提交

saveToken(request);

return mapping.findForward(“failure”);

}

resetToken(request);//刪除session中的令牌

由于使用同步令牌解決表單重復提交問題的原理是基于Session會話的原理,因此該方法適用于所有Struts系統。

2 結語

本文介紹了基于Struts的Web系統中表單重復提交的四種解決方案,并詳細分析了每種方案的設計方法及應用場景,目前這四種解決方案已經運用到很多基于Struts的Web系統中。

[1]朱國輝,周琪云,朱文生.Web應用中重復提交的探討[J].計算機與現代化,2006,(7):75 -77.

[2]阮景奎,宋國柱.重復表單提交實現[J].湖北汽車工業學院學報,2007,(9):33 -35.

[3]Elliot White III,Jonathan Eisenhamer.PHP 5 in Practice[M].Sams,2006.

[4]廖儀奎.Java Web開發之Struts編程基礎與實例精講[M],北京:中國電力出版社,2006.

[5]楊兵.令牌技術在Web項目中的研究與應用[J].計算機與現代化,2005,(7):110 -112.

猜你喜歡
令牌表單瀏覽器
稱金塊
電子表單系統應用分析
基于路由和QoS令牌桶的集中式限速網關
反瀏覽器指紋追蹤
動態令牌分配的TCSN多級令牌桶流量監管算法
淺談網頁制作中表單的教學
環球瀏覽器
動態表單技術在教學管理中的應用*
基于Java可視化測繪生產流程表單的設計及實現
令牌在智能小區訪客系統的應用
91香蕉高清国产线观看免费-97夜夜澡人人爽人人喊a-99久久久无码国产精品9-国产亚洲日韩欧美综合