JSP 防止刷新/后退引起的重复提交问题

Struts本身有一套完善的防止重复提交表单的Token(令牌)机制,但笔者目前的项目自写的framework没有用到Struts,故也得自写防止用户因为后退或者刷新来重复提交表单内容的Token机制。不难,容易实现。

实现原理:一致性。jsp生成表单时,在表单中插入一个隐藏<input>字段,该字段就是保存在页面端的token字符串,同时把该字符串存入session中。等到用户提交表单时,会一并提交该隐藏的token字符串。在服务器端,查看下是否在session中含有与该token字符串相等的字符串。如果有,那么表明是第一次提交该表单,然后删除存放于session端的token字符串,再做正常业务逻辑流程;如果没有,那么表示该表单被重复提交,做非正常流程处理,可以警告提示也可以什么也不做。

看代码。

首先是Token主类。类很简单,而且主要方法都给doc注释了

Java代码 复制代码
  1. /*  
  2. * blog: http://hi.baidu.com/bobylou  
  3. * $Revision: 1.1 $  
  4. * $Date: 2007/07/18 10:02:55 $  
  5. * $Author: bobrow$  
  6. */  
  7.   
  8. package com.paizuo.framework.util;   
  9.   
  10. import java.util.ArrayList;   
  11.   
  12. import javax.servlet.http.HttpSession;   
  13.   
  14. public class Token {   
  15.   
  16.     private static final String TOKEN_LIST_NAME = "tokenList";   
  17.   
  18.     public static final String TOKEN_STRING_NAME = "token";   
  19.   
  20.     private static ArrayList getTokenList(HttpSession session) {   
  21.        Object obj = session.getAttribute(TOKEN_LIST_NAME);   
  22.        if (obj != null) {   
  23.           return (ArrayList) obj;   
  24.        } else {   
  25.           ArrayList tokenList = new ArrayList();   
  26.           session.setAttribute(TOKEN_LIST_NAME, tokenList);   
  27.           return tokenList;   
  28.        }   
  29.     }   
  30.   
  31.     private static void saveTokenString(String tokenStr, HttpSession session) {   
  32.        ArrayList tokenList = getTokenList(session);   
  33.        tokenList.add(tokenStr);   
  34.        session.setAttribute(TOKEN_LIST_NAME, tokenList);   
  35.     }   
  36.       
  37.     private static String generateTokenString(){   
  38.        return new Long(System.currentTimeMillis()).toString();   
  39.     }   
  40.   
  41.     /**  
  42.      * Generate a token string, and save the string in session, then return the token string.  
  43.      *   
  44.      * @param HttpSession  
  45.      *            session  
  46.      * @return a token string used for enforcing a single request for a particular transaction.  
  47.      */  
  48.     public static String getTokenString(HttpSession session) {   
  49.        String tokenStr = generateTokenString();   
  50.        saveTokenString(tokenStr, session);   
  51.        return tokenStr;   
  52.     }   
  53.   
  54.     /**  
  55.      * check whether token string is valid. if session contains the token string, return true.   
  56.      * otherwise, return false.  
  57.      *   
  58.      * @param String  
  59.      *            tokenStr  
  60.      * @param HttpSession  
  61.      *            session  
  62.      * @return true: session contains tokenStr; false: session is null or tokenStr is id not in session  
  63.      */  
  64.     public static boolean isTokenStringValid(String tokenStr, HttpSession session) {   
  65.        boolean valid = false;   
  66.        if(session != null){   
  67.           ArrayList tokenList = getTokenList(session);   
  68.           if (tokenList.contains(tokenStr)) {   
  69.              valid = true;   
  70.              tokenList.remove(tokenStr);   
  71.           }   
  72.        }   
  73.        return valid;   
  74.     }   
  75. }  
/*
* blog: http://hi.baidu.com/bobylou
* $Revision: 1.1 $
* $Date: 2007/07/18 10:02:55 $
* $Author: bobrow$
*/

package com.paizuo.framework.util;

import java.util.ArrayList;

import javax.servlet.http.HttpSession;

public class Token {

    private static final String TOKEN_LIST_NAME = "tokenList";

    public static final String TOKEN_STRING_NAME = "token";

    private static ArrayList getTokenList(HttpSession session) {
       Object obj = session.getAttribute(TOKEN_LIST_NAME);
       if (obj != null) {
          return (ArrayList) obj;
       } else {
          ArrayList tokenList = new ArrayList();
          session.setAttribute(TOKEN_LIST_NAME, tokenList);
          return tokenList;
       }
    }

    private static void saveTokenString(String tokenStr, HttpSession session) {
       ArrayList tokenList = getTokenList(session);
       tokenList.add(tokenStr);
       session.setAttribute(TOKEN_LIST_NAME, tokenList);
    }
   
    private static String generateTokenString(){
       return new Long(System.currentTimeMillis()).toString();
    }

    /**
     * Generate a token string, and save the string in session, then return the token string.
     * 
     * @param HttpSession
     *            session
     * @return a token string used for enforcing a single request for a particular transaction.
     */
    public static String getTokenString(HttpSession session) {
       String tokenStr = generateTokenString();
       saveTokenString(tokenStr, session);
       return tokenStr;
    }

    /**
     * check whether token string is valid. if session contains the token string, return true. 
     * otherwise, return false.
     * 
     * @param String
     *            tokenStr
     * @param HttpSession
     *            session
     * @return true: session contains tokenStr; false: session is null or tokenStr is id not in session
     */
    public static boolean isTokenStringValid(String tokenStr, HttpSession session) {
       boolean valid = false;
       if(session != null){
          ArrayList tokenList = getTokenList(session);
          if (tokenList.contains(tokenStr)) {
             valid = true;
             tokenList.remove(tokenStr);
          }
       }
       return valid;
    }
}


怎么使用?

在jsp页面端。

首先import该类:

Html代码 复制代码
  1. <%@ page import="com.paizuo.framework.util.Token" %>  
<%@ page import="com.paizuo.framework.util.Token" %>

表单包含隐藏的token字符串:

Html代码 复制代码
  1. <form>  
  2. ......   
  3. <input type="hidden" name="<%=Token.TOKEN_STRING_NAME %>" value="<%=Token.getTokenString(session) %>">  
  4. ......   
  5. </form>  
<form>
......
<input type="hidden" name="<%=Token.TOKEN_STRING_NAME %>" value="<%=Token.getTokenString(session) %>">
......
</form>

在Server端action中进行检验。

Java代码 复制代码
  1. if(Token.isTokenStringValid(request.getParameter(Token.TOKEN_STRING_NAME), request.getSession())){   
  2. //进行正常业务流程   
  3. }   
  4. else{   
  5. //进行防重复提交处理流程   
  6. }  
if(Token.isTokenStringValid(request.getParameter(Token.TOKEN_STRING_NAME), request.getSession())){
//进行正常业务流程
}
else{
//进行防重复提交处理流程
}


完毕。

出自:http://alan3258.javaeye.com/blog/301359

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值