使用Session防止表單重復(fù)提交_第1頁(yè)
使用Session防止表單重復(fù)提交_第2頁(yè)
使用Session防止表單重復(fù)提交_第3頁(yè)
使用Session防止表單重復(fù)提交_第4頁(yè)
使用Session防止表單重復(fù)提交_第5頁(yè)
已閱讀5頁(yè),還剩9頁(yè)未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、JavaWeb學(xué)習(xí)總結(jié)(十三)使用Session防止表單重復(fù)提交在平時(shí)開(kāi)發(fā)中,如果網(wǎng)速比較慢的情況下,用戶提交表單后,發(fā)現(xiàn)服務(wù)器半天都沒(méi)有響應(yīng),那么用戶可能會(huì)以為是自己沒(méi)有提交表單,就會(huì)再點(diǎn)擊提交按鈕重復(fù)提交表單,我們?cè)陂_(kāi)發(fā)中必須防止表單重復(fù)提交。一、表單重復(fù)提交的常見(jiàn)應(yīng)用場(chǎng)景有如下的form.jsp頁(yè)面 1 2 3 4 5 Form表單 6 7 8 9 10 用戶名:11 12 13 14 form表單提交到DoFormServlet進(jìn)行處理 1 package xdp.gacl.session; 2 3 import java.io.IOException; 4 import javax.

2、servlet.ServletException; 5 import javax.servlet.http.HttpServlet; 6 import javax.servlet.http.HttpServletRequest; 7 import javax.servlet.http.HttpServletResponse; 8 9 public class DoFormServlet extends HttpServlet 10 11 public void doGet(HttpServletRequest request, HttpServletResponse response)12 t

3、hrows ServletException, IOException 13 /客戶端是以UTF-8編碼傳輸數(shù)據(jù)到服務(wù)器端的,所以需要設(shè)置服務(wù)器端以UTF-8的編碼進(jìn)行接收,否則對(duì)于中文數(shù)據(jù)就會(huì)產(chǎn)生亂碼14 request.setCharacterEncoding(UTF-8);15 String userName = request.getParameter(username);16 try 17 /讓當(dāng)前的線程睡眠3秒鐘,模擬網(wǎng)絡(luò)延遲而導(dǎo)致表單重復(fù)提交的現(xiàn)象18 Thread.sleep(3*1000);19 catch (InterruptedException e) 20 e.prin

4、tStackTrace();21 22 System.out.println(向數(shù)據(jù)庫(kù)中插入數(shù)據(jù):+userName);23 24 25 public void doPost(HttpServletRequest request, HttpServletResponse response)26 throws ServletException, IOException 27 doGet(request, response);28 29 30 如果沒(méi)有進(jìn)行form表單重復(fù)提交處理,那么在網(wǎng)絡(luò)延遲的情況下下面的操作將會(huì)導(dǎo)致form表單重復(fù)提交多次1.1、場(chǎng)景一:在網(wǎng)絡(luò)延遲的情況下讓用戶有時(shí)間點(diǎn)擊多次

5、submit按鈕導(dǎo)致表單重復(fù)提交演示動(dòng)畫(huà)如下所示:1.2、場(chǎng)景二:表單提交后用戶點(diǎn)擊【刷新】按鈕導(dǎo)致表單重復(fù)提交演示動(dòng)畫(huà)如下所示:點(diǎn)擊瀏覽器的刷新按鈕,就是把瀏覽器上次做的事情再做一次,因?yàn)檫@樣也會(huì)導(dǎo)致表單重復(fù)提交。1.3、場(chǎng)景三:用戶提交表單后,點(diǎn)擊瀏覽器的【后退】按鈕回退到表單頁(yè)面后進(jìn)行再次提交演示動(dòng)畫(huà)如下所示:二、利用JavaScript防止表單重復(fù)提交既然存在上述所說(shuō)的表單重復(fù)提交問(wèn)題,那么我們就要想辦法解決,比較常用的方法是采用JavaScript來(lái)防止表單重復(fù)提交,具體做法如下:修改form.jsp頁(yè)面,添加如下的JavaScript代碼來(lái)防止表單重復(fù)提交 1 2 3 4 5 Fo

6、rm表單 6 7 var isCommitted = false;/表單是否已經(jīng)提交標(biāo)識(shí),默認(rèn)為false 8 function dosubmit() 9 if(isCommitted=false)10 isCommitted = true;/提交表單后,將表單是否已經(jīng)提交標(biāo)識(shí)設(shè)置為true11 return true;/返回true讓表單正常提交12 else13 return false;/返回false那么表單將不提交14 15 16 17 18 19 20 21 用戶名:22 23 24 25 我們看看使用了JavaScript來(lái)防止表單提交重復(fù)是否可以成功,運(yùn)行效果如下:可以看到,針

7、對(duì)在網(wǎng)絡(luò)延遲的情況下讓用戶有時(shí)間點(diǎn)擊多次submit按鈕導(dǎo)致表單重復(fù)提交這個(gè)應(yīng)用場(chǎng)景,使用JavaScript是可以解決這個(gè)問(wèn)題的,解決的做法就是用JavaScript控制Form表單只能提交一次。除了用這種方式之外,經(jīng)常見(jiàn)的另一種方式就是表單提交之后,將提交按鈕設(shè)置為不可用,讓用戶沒(méi)有機(jī)會(huì)點(diǎn)擊第二次提交按鈕,代碼如下:1 function dosubmit()2 /獲取表單提交按鈕3 var btnSubmit = document.getElementById(submit);4 /將表單提交按鈕設(shè)置為不可用,這樣就可以避免用戶再次點(diǎn)擊提交按鈕5 btnSubmit.disabled= d

8、isabled;6 /返回true讓表單可以正常提交7 return true;8 運(yùn)行效果如下:另外還有一種做法就是提交表單后,將提交按鈕隱藏起來(lái),這種做法和將提交按鈕設(shè)置為不可用是差不多的,個(gè)人覺(jué)得將提交按鈕隱藏影響到頁(yè)面布局的美觀,并且可能會(huì)讓用戶誤以為是bug(怎么我一點(diǎn)擊按鈕,按鈕就不見(jiàn)了呢?用戶可能會(huì)有這樣的疑問(wèn)),我個(gè)人在開(kāi)發(fā)中用得比較多的是表單提交后,將提交按鈕設(shè)置為不可用,反正使用JavaScript防止表單重復(fù)提交的做法都是差不多的,目的都是讓表單只能提交一次,這樣就可以做到表單不重復(fù)提交了。使用JavaScript防止表單重復(fù)提交的做法只對(duì)上述提交到導(dǎo)致表單重復(fù)提交的三種

9、場(chǎng)景中的【場(chǎng)景一】有效,而對(duì)于【場(chǎng)景二】和【場(chǎng)景三】是沒(méi)有用,依然無(wú)法解決表單重復(fù)提交問(wèn)題。三、利用Session防止表單重復(fù)提交對(duì)于【場(chǎng)景二】和【場(chǎng)景三】導(dǎo)致表單重復(fù)提交的問(wèn)題,既然客戶端無(wú)法解決,那么就在服務(wù)器端解決,在服務(wù)器端解決就需要用到session了。具體的做法:在服務(wù)器端生成一個(gè)唯一的隨機(jī)標(biāo)識(shí)號(hào),專業(yè)術(shù)語(yǔ)稱為T(mén)oken(令牌),同時(shí)在當(dāng)前用戶的Session域中保存這個(gè)Token。然后將Token發(fā)送到客戶端的Form表單中,在Form表單中使用隱藏域來(lái)存儲(chǔ)這個(gè)Token,表單提交的時(shí)候連同這個(gè)Token一起提交到服務(wù)器端,然后在服務(wù)器端判斷客戶端提交上來(lái)的Token與服務(wù)器端生

10、成的Token是否一致,如果不一致,那就是重復(fù)提交了,此時(shí)服務(wù)器端就可以不處理重復(fù)提交的表單。如果相同則處理表單提交,處理完后清除當(dāng)前用戶的Session域中存儲(chǔ)的標(biāo)識(shí)號(hào)。在下列情況下,服務(wù)器程序?qū)⒕芙^處理用戶提交的表單請(qǐng)求:1. 存儲(chǔ)Session域中的Token(令牌)與表單提交的Token(令牌)不同。2. 當(dāng)前用戶的Session中不存在Token(令牌)。3. 用戶提交的表單數(shù)據(jù)中沒(méi)有Token(令牌)。看具體的范例:1.創(chuàng)建FormServlet,用于生成Token(令牌)和跳轉(zhuǎn)到form.jsp頁(yè)面 1 package xdp.gacl.session; 2 3 import j

11、ava.io.IOException; 4 import javax.servlet.ServletException; 5 import javax.servlet.http.HttpServlet; 6 import javax.servlet.http.HttpServletRequest; 7 import javax.servlet.http.HttpServletResponse; 8 9 public class FormServlet extends HttpServlet 10 private static final long serialVersionUID = -884

12、689940866074733L;11 12 public void doGet(HttpServletRequest request, HttpServletResponse response)13 throws ServletException, IOException 14 15 String token = TokenProccessor.getInstance().makeToken();/創(chuàng)建令牌16 System.out.println(在FormServlet中生成的token:+token);17 request.getSession().setAttribute(token

13、, token); /在服務(wù)器使用session保存token(令牌)18 request.getRequestDispatcher(/form.jsp).forward(request, response);/跳轉(zhuǎn)到form.jsp頁(yè)面19 20 21 public void doPost(HttpServletRequest request, HttpServletResponse response)22 throws ServletException, IOException 23 doGet(request, response);24 25 26 2.在form.jsp中使用隱藏域來(lái)存

14、儲(chǔ)Token(令牌) 1 2 3 4 5 form表單 6 7 8 9 10 11 %-12 input type=hidden name=token value=13 -%14 15 16 用戶名: 17 18 19 20 3.DoFormServlet處理表單提交 1 package xdp.gacl.session; 2 3 import java.io.IOException; 4 import javax.servlet.ServletException; 5 import javax.servlet.http.HttpServlet; 6 import javax.servlet.

15、http.HttpServletRequest; 7 import javax.servlet.http.HttpServletResponse; 8 9 public class DoFormServlet extends HttpServlet 10 11 public void doGet(HttpServletRequest request, HttpServletResponse response)12 throws ServletException, IOException 13 14 boolean b = isRepeatSubmit(request);/判斷用戶是否是重復(fù)提交

16、15 if(b=true)16 System.out.println(請(qǐng)不要重復(fù)提交);17 return;18 19 request.getSession().removeAttribute(token);/移除session中的token20 System.out.println(處理用戶提交請(qǐng)求!);21 22 23 /*24 * 判斷客戶端提交上來(lái)的令牌和服務(wù)器端生成的令牌是否一致25 * param request26 * return 27 * true 用戶重復(fù)提交了表單 28 * false 用戶沒(méi)有重復(fù)提交表單29 */30 private boolean isRepeatS

17、ubmit(HttpServletRequest request) 31 String client_token = request.getParameter(token);32 /1、如果用戶提交的表單數(shù)據(jù)中沒(méi)有token,則用戶是重復(fù)提交了表單33 if(client_token=null)34 return true;35 36 /取出存儲(chǔ)在Session中的token37 String server_token = (String) request.getSession().getAttribute(token);38 /2、如果當(dāng)前用戶的Session中不存在Token(令牌),則用

18、戶是重復(fù)提交了表單39 if(server_token=null)40 return true;41 42 /3、存儲(chǔ)在Session中的Token(令牌)與表單提交的Token(令牌)不同,則用戶是重復(fù)提交了表單43 if(!client_token.equals(server_token)44 return true;45 46 47 return false;48 49 50 public void doPost(HttpServletRequest request, HttpServletResponse response)51 throws ServletException, IOE

19、xception 52 doGet(request, response);53 54 55 生成Token的工具類TokenProccessor 1 package xdp.gacl.session; 2 3 import java.security.MessageDigest; 4 import java.security.NoSuchAlgorithmException; 5 import java.util.Random; 6 import sun.misc.BASE64Encoder; 7 8 public class TokenProccessor 9 10 /*11 *單例設(shè)計(jì)模式

20、(保證類的對(duì)象在內(nèi)存中只有一個(gè))12 *1、把類的構(gòu)造函數(shù)私有13 *2、自己創(chuàng)建一個(gè)類的對(duì)象14 *3、對(duì)外提供一個(gè)公共的方法,返回類的對(duì)象15 */16 private TokenProccessor()17 18 private static final TokenProccessor instance = new TokenProccessor();19 20 /*21 * 返回類的對(duì)象22 * return23 */24 public static TokenProccessor getInstance()25 return instance;26 27 28 /*29 * 生成Token30 * To

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論