淺談利用Session防止表單重復(fù)提交
解決項(xiàng)目中表單重復(fù)提交的問(wèn)題,在平常的項(xiàng)目中有以下幾種可能出現(xiàn)表單重復(fù)提交的情況,比如說(shuō):
1.由于服務(wù)器緩慢或者網(wǎng)絡(luò)延遲的原因,重復(fù)點(diǎn)擊提交按鈕
2.已經(jīng)提交成功,但是還不停刷新成功頁(yè)面
3.已經(jīng)提交成功,通過(guò)回退,再次點(diǎn)擊提交按鈕。
這些情況都可能使數(shù)據(jù)庫(kù)中產(chǎn)生過(guò)多相同的冗余數(shù)據(jù),浪費(fèi)數(shù)據(jù)庫(kù)資源。只有轉(zhuǎn)發(fā)才會(huì)出現(xiàn),重定向則不會(huì)。
針對(duì)第一種情況的解決方案(使用JavaScript),對(duì)后面兩種無(wú)效:
首先在頁(yè)面中添加如下格式的JavaScript代碼
var submitFlag=false;
function checksubmit(){
if(!submitFlag){
submitFlag=true;
document.forms[0].submit();
}
}
(1)當(dāng)提交按鈕的type屬性為button時(shí):
設(shè)置按鈕的onClick=”checksubmit();”即可。
(2)當(dāng)提交按鈕的type屬性為submit時(shí):
設(shè)置按鈕的onClick=”checksubmit();”,并在<form>標(biāo)簽中增加onsubmit=”returnfalse”。因?yàn)閟ubmit按鈕的自動(dòng)提交時(shí)在點(diǎn)擊事件提交之后,將onsubmit設(shè)置為”returnfalse”,submit按鈕的自動(dòng)提交就會(huì)失效。
對(duì)于后面兩種情況,可以使用session解決,其原理是在運(yùn)行添加信息頁(yè)面時(shí)在session中放置信息,然后頁(yè)面提交信息給servlet處理,servlet獲取session中的信息,如果session中有信息不為空則將信息插入數(shù)據(jù)庫(kù),然后刪除session中的信息,下次再提交表單時(shí)session中的信息為空,那么則不執(zhí)行存儲(chǔ)信息過(guò)程。
但是單純使用session有其局限性,所以在實(shí)際開(kāi)發(fā)中,一般使用利用session結(jié)合UUID解決表單的重復(fù)提交,代碼如下:
定義一個(gè)UuidToken類(lèi)
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頁(yè)面上的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頁(yè)面增加一個(gè)隱藏域,利用uuid生成一個(gè)唯一的標(biāo)識(shí)號(hào),賦給隱藏域,把唯一的標(biāo)識(shí)號(hào) 放置到session中一份,代碼如下:
<input type="hidden" name="html.uuid" value='<%=UuidToken.getUuidToken().getUUIDAsStr(request)%>'>
提交給servlet后,獲取 jsp頁(yè)隱藏域的值,用隱藏域的值和session中放置的值做比對(duì),如果相同,保存數(shù)據(jù)并從session中刪除UUID,不相同則說(shuō)明是重復(fù)提交,不進(jìn)行處理。
Boolean flag= UuidToken.getUuidToken().isUUIDValidate(request);
if(flag){
// 保存信息到數(shù)據(jù)庫(kù)
//從session刪除uuid的
UuidToken.getUuidToken().resetUUID(request);
} else{
System.out.println("表單重復(fù)提交");
}
總結(jié)
以上就是本文關(guān)于淺談利用Session防止表單重復(fù)提交的全部?jī)?nèi)容,希望對(duì)大家有所幫助。感興趣的朋友可以繼續(xù)參閱本站其他相關(guān)專(zhuān)題,如有不足之處,歡迎留言指出。感謝朋友們對(duì)本站的支持!
相關(guān)文章
java如何實(shí)現(xiàn)獲取客戶(hù)端ip地址的示例代碼
本文主要介紹了java如何實(shí)現(xiàn)獲取客戶(hù)端ip地址,主要包括java獲取客戶(hù)端ip地址工具類(lèi)使用實(shí)例、應(yīng)用技巧,文中通過(guò)示例代碼介紹的非常詳細(xì),感興趣的小伙伴們可以參考一下2022-04-04
mybatis 集合嵌套查詢(xún)和集合嵌套結(jié)果的區(qū)別說(shuō)明
這篇文章主要介紹了mybatis 集合嵌套查詢(xún)和集合嵌套結(jié)果的區(qū)別說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-09-09
java使用JDBC連接數(shù)據(jù)庫(kù)的五種方式(IDEA版)
這篇文章主要介紹了java使用JDBC連接數(shù)據(jù)庫(kù)的五種方式(IDEA版),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-04-04
idea如何快速查找一個(gè)類(lèi)或類(lèi)中方法名和變量
這篇文章主要介紹了idea如何快速查找一個(gè)類(lèi)或類(lèi)中方法名和變量問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-11-11
mybatis自定義參數(shù)類(lèi)型轉(zhuǎn)換器數(shù)據(jù)庫(kù)字段加密脫敏
這篇文章主要為大家介紹了mybatis自定義參數(shù)類(lèi)型轉(zhuǎn)換器數(shù)據(jù)庫(kù)字段加密脫敏,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-09-09
SpringBoot教程_創(chuàng)建第一個(gè)SpringBoot項(xiàng)目
這篇文章主要介紹了SpringBoot教程_創(chuàng)建第一個(gè)SpringBoot項(xiàng)目,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-06-06
SpringBoot JSON全局日期格式轉(zhuǎn)換器實(shí)現(xiàn)方式
這篇文章主要介紹了SpringBoot JSON全局日期格式轉(zhuǎn)換器,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-04-04
詳解java一維數(shù)組及練習(xí)題實(shí)例
在本篇文章里小編給大家整理了關(guān)于java一維數(shù)組及練習(xí)題的相關(guān)知識(shí)點(diǎn)和實(shí)例代碼,有需要的朋友們跟著學(xué)習(xí)下。2019-07-07
使用java實(shí)現(xiàn)網(wǎng)絡(luò)爬蟲(chóng)
這篇文章主要介紹了使用java實(shí)現(xiàn)網(wǎng)絡(luò)爬蟲(chóng),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-07-07

