struts 防止重复提交

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

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

看代码。

首先是Token主类。类很简单,而且主要方法都给doc注释了
Java代码
Java代码
/*   
* 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;     
    }     
}  

/* 
* 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代码
Java代码
<%@ page import="com.paizuo.framework.util.Token" %> 

<%@ page import="com.paizuo.framework.util.Token" %>

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

Html代码
Java代码
<form>    
......     
<input type="hidden" name="<%=Token.TOKEN_STRING_NAME %>" value="<%=Token.getTokenString(session) %>">    
......     
</form>   

<form> 
......  
<input type="hidden" name="<%=Token.TOKEN_STRING_NAME %>" value="<%=Token.getTokenString(session) %>"> 
......  
</form> 

在Server端action中进行检验。
Java代码
if(Token.isTokenStringValid(request.getParameter(Token.TOKEN_STRING_NAME), request.getSession())){     
//进行正常业务流程     
}     
else{     
//进行防重复提交处理流程     
}   

if(Token.isTokenStringValid(request.getParameter(Token.TOKEN_STRING_NAME), request.getSession())){  
//进行正常业务流程  
}  
else{  
//进行防重复提交处理流程  


完毕。

版权声明:自由转帖,但请注明作者bobrow和出处,谢谢。

你可能感兴趣的:(jsp,struts,servlet,Blog)