java_WEB開發(fā)防刷新-創(chuàng)新互聯(lián)

成都創(chuàng)新互聯(lián)公司堅持“要么做到,要么別承諾”的工作理念,服務(wù)領(lǐng)域包括:網(wǎng)站設(shè)計、成都網(wǎng)站建設(shè)、企業(yè)官網(wǎng)、英文網(wǎng)站、手機端網(wǎng)站、網(wǎng)站推廣等服務(wù),滿足客戶于互聯(lián)網(wǎng)時代的普陀網(wǎng)站設(shè)計、移動媒體設(shè)計的需求,幫助企業(yè)找到有效的互聯(lián)網(wǎng)解決方案。努力成為您成熟可靠的網(wǎng)絡(luò)建設(shè)合作伙伴!>客戶端處理: 面對客戶端我們可以使用Javascript腳本來解決,如下 1。重復(fù)刷新、重復(fù)提交 Ways One:設(shè)置一個變量,只允許提交一次。 <script language="javascript"> var checkSubmitFlg= false; function checkSubmit() { if (checkSubmitFlg == true) { return false; } checkSubmitFlg= true; return true; } document.ondblclick= function docondblclick() { window.event.returnValue= false; } document.onclick= function doconclick() { if (checkSubmitFlg) { window.event.returnValue= false; } } </script> <html:form action="myAction.do" method="post" onsubmit="return checkSubmit();"> Way Two : 將提交按鈕或者image置為disable <html:form action="myAction.do" method="post" onsubmit="getElById('submitInput').disabled = true; return true;"> <html:image styleId="submitInput" src="images/ok_b.gif" border="0" /> </html:form> 2。防止用戶后退 這里的方法是千姿百態(tài),有的是更改瀏覽器的歷史紀(jì)錄的,比如使用window.history.forward()方法;有的是“用新頁面的URL替換當(dāng)前的歷史紀(jì)錄,這樣瀏覽歷史記錄中就只有一個頁面,后退按鈕永遠不會變?yōu)榭捎??!北热缡褂胘avascript:location.replace(this.href); event.returnValue=false; 2.服務(wù)器端的處理(這里只說Struts框架的處理) 利用同步令牌(Token)機制來解決Web應(yīng)用中重復(fù)提交的問題,Struts也給出了一個參考實現(xiàn)。 基本原理: 服務(wù)器端在處理到達的請求之前,會將請求中包含的令牌值與保存在當(dāng)前用戶會話中的令牌值進行比較, 看是否匹配。在處理完該請求后,且在答復(fù)發(fā)送給客戶端之前,將會產(chǎn)生一個新的令牌,該令牌除傳給 客戶端以外,也會將用戶會話中保存的舊的令牌進行替換。這樣如果用戶回退到剛才的提交頁面并再次 提交的話,客戶端傳過來的令牌就和服務(wù)器端的令牌不一致,從而有效地防止了重復(fù)提交的發(fā)生。 if (isTokenValid(request, true)) { // your code herereturn mapping.findForward("success"); }else { saveToken(request); return mapping.findForward("submitagain"); } Struts根據(jù)用戶會話ID和當(dāng)前系統(tǒng)時間來生成一個唯一(對于每個會話)令牌的,具體實現(xiàn)可以參考 TokenProcessor類中的generateToken()方法。 1. //驗證事務(wù)控制令牌,<html:form >會自動根據(jù)session中標(biāo)識生成一個隱含input代表令牌,防止兩次提交2. 在action中: //<input type="hidden" name="org.apache.struts.taglib.html.TOKEN" // value="6aa35341f25184fd996c4c918255c3ae">if (!isTokenValid(request)) errors.add(ActionErrors.GLOBAL_ERROR, new ActionError("error.transaction.token")); resetToken(request);//刪除session中的令牌3. action有這樣的一個方法生成令牌 protected String generateToken(HttpServletRequest request) { HttpSession session= request.getSession(); try { byte id[] = session.getId().getBytes(); byte now[] = new Long(System.currentTimeMillis()).toString().getBytes(); MessageDigest md= MessageDigest.getInstance("MD5"); md.update(id); md.update(now); return (toHex(md.digest())); }catch (IllegalStateException e) { return (null); }catch (NoSuchAlgorithmException e) { return (null); } } 總結(jié) 對于重復(fù)提交、重復(fù)刷新、防止后退等等都是屬于系統(tǒng)為避免重復(fù)記錄而需要解決的問題,在客戶端去處理需要針對每一種的可能提出相應(yīng)的解決方案,然而在服務(wù)器端看來只不過是對于數(shù)據(jù)真實性的檢驗問題,基于令牌的處理就是一勞永逸的方法。 同時我們也看到,從不同的角度去看待問題,其解決的方法也是不同的。客戶端更追求的是用戶的操作,而服務(wù)端則將注意力放在了數(shù)據(jù)的處理上,所以在某個對于服務(wù)器端看似容易的問題上,用客戶端來解決卻麻煩了很多!反之依然。所以在某些問題的處理上我們需要綜合考慮和平衡,是用客戶端來解決?還是用服務(wù)器端來處理?
         在java web工程中,當(dāng)jsp向Servlet提交請求時,如何防止刷新提交(F5)? 

         第一種解決方法,參照老紫竹的思路: 


         可以使用的方法有,在jsp中定義一個變量值,這個變量值應(yīng)該是唯一的,可以使用算法來保證生成數(shù)據(jù)的唯一性,例如hash算法,或者生成一個隨機數(shù)(Random),并將這個數(shù)值保存到一個Set中,并將Set保存在session中,提交Servlet時將這個參數(shù)傳遞過去,在Servlet中的處理:接到參數(shù)和session中的set后,判斷set中有沒有傳來的參數(shù)值,如果沒有則頁面是刷新造成的,并不是來自頁面的提交,這時不做insert data的處理。 

         jsp 代碼 : 

<% 
   //生成一個formhash,算法可以自己定,不隨便重復(fù)就可以了        Random ran = new Random();
        String formhash= String.valueOf(ran.nextInt());
//讀取當(dāng)前session里面的hashCode集合,此處使用了Set,方便判斷。        Set<String> formhashSession = (Set<String>) session.getAttribute("formhashSession");
if (formhashSession == null) {
             formhashSession= new HashSet<String>();
        }
// 檢測重復(fù)問題   while (formhashSession.contains(formhash)) {
             formhash= String.valueOf(ran.nextInt());
        }
// 保存到session里面        formhashSession.add(formhash);
// 保存        session.setAttribute("formhashSession", formhashSession);
%> 

    <form>中增加:<input type="hidden" name="formhash" id="formhash" value="<%=formhash%>" />    

         Servlet代碼: 

// 拿到表單的formhash         String formhash = request.getParameter("formhash");
// 拿到session里面的集合         Set<String> formhashSession = (Set<String>) session.getAttribute("formhashSession");
// 如果沒有,則是重復(fù)提交,或者非法提交  if (formhashSession == null || !formhashSession.contains(formhash)) {
                System.out.println("重復(fù)提交!");
           }else{ 

//正常的操作
           } 

// 最后,如果操作成功,從session里面把這個formhash 刪掉!           formhashSession.remove(formhash);
           session.setAttribute("formhashSession", formhashSession); 

參考文章:http://blog.csdn.net/java2000_net/archive/2008/02/25/2119298.aspx
          第二種解決方法, 參考struts的token(令牌)機制: 

          在提交的時候在Servlet中根據(jù)用戶的sessionid和當(dāng)前時間的long值生成一個令牌(每次提交都會生成一個新令牌),將令牌保存在該用戶的會話中,并將令牌的值以request屬性形式傳到前端頁面,在前端頁面的form中增加傳遞令牌的隱藏域<input type="hidden" name="clientToken" value="<%=clientToken%>" />,提交form的時候,也會將clientToken傳入Servlet,如果session中保存的令牌值與傳入的不同,則是重復(fù)提交,因為每次請求Servlet都會生成新的令牌,刷新時的令牌值是舊的令牌值,不是最新的令牌值。 

           jsp代碼: 

<% 
    String clientToken= (String)request.getAttribute("clientToken");
    clientToken= clientToken==null?"":clientToken;
%> 

<form>中增加<input type="hidden" name="clientToken" value="<%=clientToken%>" /> 

          Servlet代碼: 

          String clientToken= request.getParameter("clientToken");
          String sessionToken= (String) session.getAttribute("token"); 

if(sessionToken!=null&&!clientToken.equals(sessionToken)){
                 System.out.println("請不要重復(fù)提交!");
          }else{ 

//正常的操作
          } 

//生成新令牌           String token = generateToken(request);
           request.setAttribute("clientToken", token);
//替換舊令牌           session.setAttribute("token", token);

網(wǎng)頁名稱:java_WEB開發(fā)防刷新-創(chuàng)新互聯(lián)
URL地址:http://bm7419.com/article6/ddhjig.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供建站公司外貿(mào)網(wǎng)站建設(shè)、軟件開發(fā)、App設(shè)計、企業(yè)網(wǎng)站制作、網(wǎng)站改版

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

成都網(wǎng)站建設(shè)