成都創新互聯公司堅持“要么做到,要么別承諾”的工作理念,服務領域包括:網站設計、成都網站建設、企業官網、英文網站、手機端網站、網站推廣等服務,滿足客戶于互聯網時代的普陀網站設計、移動媒體設計的需求,幫助企業找到有效的互聯網解決方案。努力成為您成熟可靠的網絡建設合作伙伴!>客戶端處理:
面對客戶端我們可以使用Javascript腳本來解決,如下
1。重復刷新、重復提交
Ways One:設置一個變量,只允許提交一次。
<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。防止用戶后退
這里的方法是千姿百態,有的是更改瀏覽器的歷史紀錄的,比如使用window.history.forward()方法;有的是“用新頁面的URL替換當前的歷史紀錄,這樣瀏覽歷史記錄中就只有一個頁面,后退按鈕永遠不會變為可用。”比如使用javascript:location.replace(this.href); event.returnValue=false;
2.服務器端的處理(這里只說Struts框架的處理)
利用同步令牌(Token)機制來解決Web應用中重復提交的問題,Struts也給出了一個參考實現。
基本原理:
服務器端在處理到達的請求之前,會將請求中包含的令牌值與保存在當前用戶會話中的令牌值進行比較,
看是否匹配。在處理完該請求后,且在答復發送給客戶端之前,將會產生一個新的令牌,該令牌除傳給
客戶端以外,也會將用戶會話中保存的舊的令牌進行替換。這樣如果用戶回退到剛才的提交頁面并再次
提交的話,客戶端傳過來的令牌就和服務器端的令牌不一致,從而有效地防止了重復提交的發生。
if (isTokenValid(request, true)) {
// your code herereturn mapping.findForward("success");
}else {
saveToken(request);
return mapping.findForward("submitagain");
}
Struts根據用戶會話ID和當前系統時間來生成一個唯一(對于每個會話)令牌的,具體實現可以參考
TokenProcessor類中的generateToken()方法。
1. //驗證事務控制令牌,<html:form >會自動根據session中標識生成一個隱含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);
}
}
總結
對于重復提交、重復刷新、防止后退等等都是屬于系統為避免重復記錄而需要解決的問題,在客戶端去處理需要針對每一種的可能提出相應的解決方案,然而在服務器端看來只不過是對于數據真實性的檢驗問題,基于令牌的處理就是一勞永逸的方法。
同時我們也看到,從不同的角度去看待問題,其解決的方法也是不同的。客戶端更追求的是用戶的操作,而服務端則將注意力放在了數據的處理上,所以在某個對于服務器端看似容易的問題上,用客戶端來解決卻麻煩了很多!反之依然。所以在某些問題的處理上我們需要綜合考慮和平衡,是用客戶端來解決?還是用服務器端來處理?
在java web工程中,當jsp向Servlet提交請求時,如何防止刷新提交(F5)?
第一種解決方法,參照老紫竹的思路:
可以使用的方法有,在jsp中定義一個變量值,這個變量值應該是唯一的,可以使用算法來保證生成數據的唯一性,例如hash算法,或者生成一個隨機數(Random),并將這個數值保存到一個Set中,并將Set保存在session中,提交Servlet時將這個參數傳遞過去,在Servlet中的處理:接到參數和session中的set后,判斷set中有沒有傳來的參數值,如果沒有則頁面是刷新造成的,并不是來自頁面的提交,這時不做insert data的處理。
jsp 代碼 :
<%
//生成一個formhash,算法可以自己定,不隨便重復就可以了 Random ran = new Random();
String formhash= String.valueOf(ran.nextInt());
//讀取當前session里面的hashCode集合,此處使用了Set,方便判斷。 Set<String> formhashSession = (Set<String>) session.getAttribute("formhashSession");
if (formhashSession == null) {
formhashSession= new HashSet<String>();
}
// 檢測重復問題 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");
// 如果沒有,則是重復提交,或者非法提交 if (formhashSession == null || !formhashSession.contains(formhash)) {
System.out.println("重復提交!");
}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中根據用戶的sessionid和當前時間的long值生成一個令牌(每次提交都會生成一個新令牌),將令牌保存在該用戶的會話中,并將令牌的值以request屬性形式傳到前端頁面,在前端頁面的form中增加傳遞令牌的隱藏域<input type="hidden" name="clientToken" value="<%=clientToken%>" />,提交form的時候,也會將clientToken傳入Servlet,如果session中保存的令牌值與傳入的不同,則是重復提交,因為每次請求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("請不要重復提交!");
}else{
//正常的操作
}
//生成新令牌 String token = generateToken(request);
request.setAttribute("clientToken", token);
//替換舊令牌 session.setAttribute("token", token);
網頁名稱:java_WEB開發防刷新-創新互聯
URL地址:http://vcdvsql.cn/article6/ddhjig.html
成都網站建設公司_創新互聯,為您提供建站公司、外貿網站建設、軟件開發、App設計、企業網站制作、網站改版
聲明:本網站發布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創新互聯