struts2 防止頁面重複提交

關於這個問題,在網上搜索,有一大堆的解決方案,都說用token。

具體咋用呢?

參考了文章

1:http://blog.csdn.net/polisman/archive/2009/12/03/4931520.aspx

2:http://bbs.tarena.com.cn/archiver/tid-62871.html

 

寫適合我自己的內容。

 

1. 建立這個token類

 
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;  
 
import javax.servlet.http.HttpServletRequest;  
import javax.servlet.http.HttpSession;  
 
 
public class TokenProcessor {  
   private long privious;//上次生成表單標識號得時間值  
   private static TokenProcessor instance=new TokenProcessor();  
   public static String FORM_TOKEN_KEY="FORM_TOKEN_KEY";  
   private TokenProcessor(){  
         
   }  
   public static TokenProcessor getInstance(){  
       return instance;  
   }  
   /**//* 
    * 驗證請求中得標識號是否有效,如果請求中的表單標識與當前用戶session中的相同,返回結果true= 
    */ 
   public synchronized boolean isTokenValid(HttpServletRequest request){  
       //未避免session對象不存在時候創建Session對象  
       HttpSession session=request.getSession(false);  
       if(session==null){return false;}  
       String saved=(String)session.getAttribute(FORM_TOKEN_KEY);  
       if(saved==null){  
           return false;  
       }  
       String token=(String)request.getParameter(FORM_TOKEN_KEY);  
       if(token==null){  
           return false;  
       }  
       return saved.equals(token);  
   }  
     
   /**//* 
    * 清楚存儲在當前用戶session中的表單標識號 
    */ 
   public synchronized void reset(HttpServletRequest request){  
       HttpSession session=request.getSession(false);  
       if(session==null){  
           return;  
       }  
      session.removeAttribute(FORM_TOKEN_KEY);  
   }  
     
   /**//* 
    * 產生表單標識號並將之保存在當前用戶得session中 
    */ 
     
   public synchronized void saveToken(HttpServletRequest request){  
       HttpSession session=request.getSession();  
       try {  
        byte id[]=session.getId().getBytes();  
        long current=System.currentTimeMillis();  
        if(current==privious){  
            current++;  
        }  
        privious=current;  
        byte now[]=String.valueOf(current).getBytes();  
        MessageDigest md=MessageDigest.getInstance("MD5");  
        md.update(id);  
        md.update(now);  
        String token=toHex(md.digest());  
        session.setAttribute(FORM_TOKEN_KEY, token);  
      } catch (NoSuchAlgorithmException e) {  
          
      }  
   }  
   /**//* 
    * 將一個字節數轉換成十六進制得字符串 
    *  
    */ 
   public String toHex(byte buffer[]){  
       StringBuffer sb=new StringBuffer(buffer.length*2);  
       for (int i = 0; i < buffer.length; i++) {  
        sb.append(Character.forDigit((buffer[i]&0x60)>>4, 16));  
        sb.append(Character.forDigit(buffer[i]&0x0f, 16));  
    }  
       return sb.toString();  
         
   }  

 

 

2.jsp頁面頭部增加

<%

TokenProcessor tokemProcessor=TokenProcessor.getInstance();
    tokemProcessor.saveToken(request);
    String token=(String)request.getSession().getAttribute(tokemProcessor.FORM_TOKEN_KEY);
 request.setAttribute("form_token_key", tokemProcessor.FORM_TOKEN_KEY);
    request.setAttribute("token", token);

%>

<form>

<input type="hidden" name="${form_token_key }" value="${token }"/>

</form>

 

3. form提交的action中 先判斷

public String save(){

 

TokenProcessor tokemProcessor=TokenProcessor.getInstance();
   if (tokemProcessor.isTokenValid(request)) {

          save();

     tokemProcessor.reset(request);//一開始這個忘記寫了,差點放棄這個。哎,不仔細啊
     return Action.SUCCESS;

}else{

    tokemProcessor.saveToken(request);
    return Action.SUCCESS;

}

}

 

這樣就ok了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章