JSP、Struts避免Form重復提交的幾種方案
Posted on 2008-11-07 23:38 J2EE Home工作室 閱讀(145) 評論(0) 編輯 收藏 所屬分類: JSP/Servlet2 還是javascript,將提交按鈕或者image置為disable
onsubmit="getElById('submitInput').disabled = true; return true;">
3 利用struts的同步令牌機制
利用同步令牌(Token)機制來解決Web應用中重復提交的問題,Struts也給出了一個參考實現。
基本原理:
服務器端在處理到達的請求之前,會將請求中包含的令牌值與保存在當前用戶會話中的令牌值進行比較,看是否匹配。在處理完該請求后,且在答復發送給客戶端之前,將會產生一個新的令牌,該令牌除傳給客戶端以外,也會將用戶會話中保存的舊的令牌進行替換。這樣如果用戶回退到剛才的提交頁面并再次提交的話,客戶端傳過來的令牌就和服務器端的令牌不一致,從而有效地防止了重復提交的發生。
if (isTokenValid(request, true)) {
// your code here
return mapping.findForward("success");
} else {
saveToken(request);
return mapping.findForward("submitagain");
}
Struts根據用戶會話ID和當前系統時間來生成一個唯一(對于每個會話)令牌的,具體實現可以參考TokenProcessor類中的generateToken()方法。
1. //驗證事務控制令牌,會自動根據session中標識生成一個隱含input代表令牌,防止兩次提交
2. 在action中:
// // 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);
}
}
在更新的時候防止按鈕重復點擊,主要是用Session來做判斷
在JSP/Servlet中可以
SynchroToken.java
package com.lims.util;
import org.apache.struts.util.*;
import javax.servlet.http.*;
import javax.servlet.jsp.*;
import org.apache.struts.action.*;
/**
*
Title: SynchroToken
*
Description:
*
Copyright: Copyright (c) 2004
*
Company: NetStar
* @author Jstar
* @version 1.0
* Created in 2004/04/21
*/
public class SynchroToken{
public final static java.lang.String TOKEN_NAME = "_token";
public static boolean checkToken (HttpServletRequest request){
boolean isEqual = false;
HttpSession session = request.getSession ();
String formToken = request.getParameter (TOKEN_NAME);
String sessionToken = (String)session.getAttribute (TOKEN_NAME);
System.out.println ("formToken: " + formToken + " sessionToken: " +
sessionToken);
if (formToken != null && sessionToken == null){
session.setAttribute (TOKEN_NAME, formToken);
isEqual = true;
}
return isEqual;
}
/**
* Insert the method's description here.
* Creation date: (4/19/2004 3:23:25 PM)
* @return java.lang.String
* @param request javax.servlet.http.HttpServletRequest
*/
public static String getToken (HttpServletRequest request){
String token = "" + System.currentTimeMillis ();
HttpSession session = request.getSession ();
if (session != null){
session.removeAttribute (TOKEN_NAME);
}
return token;z
}
/**
* Insert the method's description here.
* Creation date: (4/19/2004 3:24:10 PM)
* @return java.lang.String
*/
final static java.lang.String getTOKEN_NAME (){
return TOKEN_NAME;
}
public static String message (PageContext pageContext, String key) throws
JspException{
return RequestUtils.message (pageContext, null, null, key);
}
}