一、使用方法

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

          2、  在打開(kāi)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 {

              // 驗(yàn)證同步令牌

                  if (isTokenValid(request, true)) { 

                      //執(zhí)行提交操作 

                  }else {

                      // 重復(fù)提交        

                      return mapping.findForward("Error");

                  }

          }

          4、  使用注意:toSubmit.jsp中的form必須使用struts的標(biāo)簽<html:form>。

           

          二、基本原理

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

          Action1中加入了saveToken(request)的方法后,調(diào)用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。

           

          第二步、在頁(yè)面創(chuàng)建hidden元素

          當(dāng)應(yīng)用服務(wù)器初始化toSubmit.jsp頁(yè)面遇到標(biāo)簽<html:form>時(shí),便會(huì)調(diào)用struts的FormTag類,其中有一個(gè)方法:

          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();

          }

          其意為:當(dāng)檢測(cè)到session中的Globals.TRANSACTION_TOKEN_KEY不為空時(shí),在toSubmit.jsp頁(yè)面創(chuàng)建元素:

          <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的值,即為同步令牌值。

           

          第三步、驗(yàn)證同步令牌

          Action2中加入isTokenValid方法,實(shí)際上是調(diào)用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,再?gòu)捻?yè)面hidden元素取來(lái)令牌值,進(jìn)行比較,如果相等則為第一次,不等則為重復(fù)提交。

          其中resetToken方法如下:

          public synchronized void resetToken(HttpServletRequest request) {

           

            HttpSession session = request.getSession(false);

            if (session == null) {

                return;

            }

            session.removeAttribute(Globals.TRANSACTION_TOKEN_KEY);

          }

           

          posted on 2006-03-08 21:07 野草 閱讀(2729) 評(píng)論(3)  編輯  收藏 所屬分類: 2shtv

          評(píng)論:
          # re: 使用struts的同步令牌避免form的重復(fù)提交 2006-08-10 06:18 | ll
          請(qǐng)教啊,我查看了使用isTokenValid()方法的類以及其父類都沒(méi)有導(dǎo)入TokenProcessor類,甚至都沒(méi)生成TokenProcessor對(duì)象,怎么會(huì)直接調(diào)用isTokenValid()方法呢,請(qǐng)指教  回復(fù)  更多評(píng)論
            
          # re: 使用struts的同步令牌避免form的重復(fù)提交 2006-11-09 12:28 | AK100
          首先確定導(dǎo)入了org.apache.struts包
          其次導(dǎo)入后org.apache.struts.action下就有這個(gè)方法了..  回復(fù)  更多評(píng)論
            
          # re: 使用struts的同步令牌避免form的重復(fù)提交 2008-11-05 08:08 | yangpan
          寫(xiě)的真詳細(xì)。。。好像懂了!

          我去看看。。不懂再來(lái)請(qǐng)教您! 謝謝  回復(fù)  更多評(píng)論
            
          主站蜘蛛池模板: 兴文县| 郯城县| 尼勒克县| 门源| 宁远县| 乌恰县| 东乡族自治县| 竹溪县| 西和县| 西充县| 武宣县| 利津县| 峨边| 新竹市| 汨罗市| 潜江市| 庄河市| 博白县| 曲阜市| 阜新| 雷州市| 沙湾县| 固镇县| 阳东县| 紫阳县| 栖霞市| 四会市| 甘谷县| 曲周县| 宁化县| 洞口县| 简阳市| 仁化县| 蒲江县| 资中县| 泸溪县| 南陵县| 新绛县| 崇信县| 年辖:市辖区| 揭东县|