JSP入門之避免Form表單重復(fù)提交的幾種方案
對于JSP入門的初級的學(xué)習(xí)者表單的提交是一個非常困擾的問題,那么如何避免Form表單多次提交呢?可以從以下的幾個方面入手:
一.對于初學(xué)JSP可以先通過Javascript中設(shè)置
設(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();"﹥
二. 對于JSP人門還要掌握J(rèn)avascript的另一設(shè)置
將表單提交按鈕或者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﹥
三.在JSP入門階段也要注意善于利用STRUTS的同步令牌機(jī)制
利用同步令牌(Token)機(jī)制來解決Web應(yīng)用中重復(fù)Form表單提交的問題,Struts也給出了一個參考實現(xiàn)。
基本原理:
服務(wù)器端在處理到達(dá)的請求之前,會將請求中包含的令牌值與保存在當(dāng)前用戶會話中的令牌值進(jìn)行比較,看是否匹配。在處理完該請求后,且在答復(fù)發(fā)送給客戶端之前,將會產(chǎn)生一個新的令牌,該令牌除傳給客戶端以外,也會將用戶會話中保存的舊的令牌進(jìn)行替換。這樣如果用戶回退到剛才的提交頁面并再次提交的話,客戶端傳過來的令牌就和服務(wù)器端的令牌不一致,從而有效地防止了重復(fù)提交的發(fā)生?!?
- if (isTokenValid(request, true)) {
- // your code here
- return 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);
- }
- }
在更新的時候防止表單按鈕重復(fù)點擊,主要是用Session來做判斷
四.在JSP入門時還要掌握頁面方式
- ﹤input type="hidden " name=" ﹤% =com.lims.util.SynchroToken.TOKEN_NAME%﹥ " value =" ﹤%= com.lims.util.SynchroToken.getToken(request)%﹥" ﹥
- SynchroToken.java
- package com.lims.util;
- import org.apache.struts.util.*;
- import javax.servlet.http.*;
- import javax.servlet.jsp.*;
- import org.apache.struts.action.*;
- /**
- * ﹤p﹥Title: SynchroToken ﹤/p﹥
- * ﹤p﹥Description: ﹤/p﹥
- * ﹤p﹥Copyright: Copyright (c) 2004﹤/p﹥
- * ﹤p﹥Company: NetStar﹤/p﹥
- * @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);
- }
- }
五.也可以通過添加中轉(zhuǎn)頁面的方式
對于JSP入門的角度講,可以通過添加中轉(zhuǎn)頁面的方式,這樣做雖然在視覺上不是很好,頁面間顯繁瑣,但是這是有效地避免Form表單重復(fù)提交的好方式。
【編輯推薦】