分類  >  Web前端 >

施用struts的同步令牌避免form的重複提交

tags:    時間:2013-12-10 10:22:30
使用struts的同步令牌避免form的重複提交

一、使用方法

1、  假如你要提交的頁面為toSubmit.jsp;

2、  在打開toSubmit.jsp的Action1中加入:saveToken(request),例如

public ActionForward execute(

    ActionMapping mapping,

    ActionForm form,

    HttpServletRequest request,

    HttpServletResponse response)

    throws Exception {

   

        //生成同步令牌

        saveToken(request);    

 

        return mapping.findForward("toSubmit");

}

3、  在提交toSubmit.jsp的Action2中加入:isTokenValid(request, true),例如:

public ActionForward execute(

    ActionMapping mapping,

    ActionForm form,

    HttpServletRequest request,

    HttpServletResponse response)

    throws Exception {

    // 驗證同步令牌

        if (isTokenValid(request, true)) { 

            //執行提交操作 

        }else {

            // 重複提交        

            return mapping.findForward("Error");

        }

}

4、  使用注意:toSubmit.jsp中的form必須使用struts的標籤<html:form>。

 

二、基本原理

第一步、在session中放入同步令牌

Action1中加入了saveToken(request)的方法后,調用TokenProcessor類的saveToken方法如下:

public synchronized void saveToken(HttpServletRequest request) {

 

    HttpSession session = request.getSession();

    String token = generateToken(request);

    if (token != null) {

        session.setAttribute(Globals.TRANSACTION_TOKEN_KEY, token);

    }

 

}

很明顯在session中放入了同步令牌,名稱為Globals.TRANSACTION_TOKEN_KEY。

 

第二步、在頁面創建hidden元素

當應用伺服器初始化toSubmit.jsp頁面遇到標籤<html:form>時,便會調用struts的FormTag類,其中有一個方法:

protected String renderToken() {

    StringBuffer results = new StringBuffer();

    HttpSession session = pageContext.getSession();

 

    if (session != null) {

        String token =

            (String) session.getAttribute(Globals.TRANSACTION_TOKEN_KEY);

            

        if (token != null) {

            results.append("<input type=\"hidden\" name=\"");

            results.append(Constants.TOKEN_KEY);

            results.append("\" value=\"");

            results.append(token);

            if (this.isXhtml()) {

                results.append("\" />");

            } else {

                results.append("\">");

            }

        }

    }

 

    return results.toString();

}

其意為:當檢測到session中的Globals.TRANSACTION_TOKEN_KEY不為空時,在toSubmit.jsp頁面創建元素:

<input type="hidden" name="org.apache.struts.taglib.html.TOKEN" value="">

名稱為:org.apache.struts.taglib.html.TOKEN就是Constants.TOKEN_KEY;

值為:session中的Globals.TRANSACTION_TOKEN_KEY的值,即為同步令牌值。

 

第三步、驗證同步令牌

Action2中加入isTokenValid方法,實際上是調用TokenProcessor類的isTokenValid方法如下:

public synchronized boolean isTokenValid(

    HttpServletRequest request,

    boolean reset) {

 

    // Retrieve the current session for this request

    HttpSession session = request.getSession(false);

    if (session == null) {

        return false;

    }

 

    // Retrieve the transaction token from this session, and

    // reset it if requested

    String saved = (String) session.getAttribute(Globals.TRANSACTION_TOKEN_KEY);

    if (saved == null) {

        return false;

    }

 

    if (reset) {

        this.resetToken(request);

    }

 

    // Retrieve the transaction token included in this request

    String token = request.getParameter(Constants.TOKEN_KEY);

    if (token == null) {

        return false;

    }

 

    return saved.equals(token);

}

它首先取得session中的令牌值,然後resetToken,再從頁面hidden元素取來令牌值,進行比較,如果相等則為第一次,不等則為重複提交。

其中resetToken方法如下:

public synchronized void resetToken(HttpServletRequest request) {

 

  HttpSession session = request.getSession(false);

  if (session == null) {

      return;

  }

  session.removeAttribute(Globals.TRANSACTION_TOKEN_KEY);

}

 

原文鏈接:http://www.blogjava.net/patterns/archive/2006/03/08/34352.html

推薦閱讀文章

Bookmark the permalink ,來源:互聯網