duansky'weblog

          統(tǒng)計

          留言簿(3)

          友情鏈接

          閱讀排行榜

          評論排行榜

          通過xml配置搞定Struts重復提交問題(轉)

          在webWork中有Token標簽,可以直接搞定重復提交的問題,但在Struts2.0以下的版本,傳統(tǒng)的做法只有通過提供的Token編程來搞定,代碼雖然不多但是,這樣的細節(jié)涉及了兩個Action,對于頁面的跳轉控制來說是一個額外的負擔,必須處處小心,本文闡述了如何通過Filter通過配置來避免struts的Form重復提交問題。
          核心代碼如下:

          package?com.yapulan.util.filter;?

          import
          ?java.io.IOException;?
          import
          ?java.util.HashMap;?
          import
          ?java.util.Iterator;?
          import
          ?java.util.List;?

          import
          ?javax.servlet.Filter;?
          import
          ?javax.servlet.RequestDispatcher;?
          import
          ?javax.servlet.ServletException;?
          import
          ?javax.servlet.FilterConfig;?
          import
          ?javax.servlet.http.HttpServletRequest;?
          import
          ?javax.servlet.http.HttpServletResponse;?
          import
          ?javax.servlet.FilterChain;?
          import
          ?javax.servlet.ServletRequest;?
          import
          ?javax.servlet.ServletResponse;?

          import
          ?org.apache.log4j.Logger;?
          import
          ?org.apache.struts.action.Action;?
          import
          ?org.apache.struts.action.ActionForm;?
          import
          ?org.apache.struts.action.ActionForward;?
          import
          ?org.apache.struts.action.ActionMapping;?
          import
          ?org.dom4j.Document;?
          import
          ?org.dom4j.Element;?
          import
          ?org.dom4j.io.SAXReader;?

          /**?
          *?重復提交令牌自動加載器?功能:讀取過濾器中設置的信息,讀入令牌設置組?
          */
          ?

          public?class?TokenFilter?implements?Filter?
          {?

          private?String?TokenConfig?=?"TokenConfig.xml"
          ;?
          private?HashMap?TokenMap?=?null
          ;?
          private?HashMap?ErrorMap?=?null
          ;?
          protected
          ?FilterConfig?filterConfig;?
          static?Logger?logger?=?Logger.getLogger(TokenFilter.class
          .getName());?

          public?void?init(FilterConfig?config)?throws?ServletException?
          {?
          this.filterConfig?=
          ?config;?
          this.TokenConfig?=?config.getInitParameter("tokenfile"
          );?
          logger.debug(
          "Tokenlist?init?OK!"
          );?
          }
          ?

          /**?
          *?初始化系統(tǒng)的xml文件,讀入令牌列表?
          */
          ?
          @SuppressWarnings(
          {?"unchecked",?"deprecation"?}
          )?
          public?void?initConfig(ServletRequest?srequest)?
          {?

          HttpServletRequest?httpRequest?
          =
          ?(HttpServletRequest)?srequest;?
          try?
          {?

          TokenMap?
          =?new
          ?HashMap();?
          ErrorMap?
          =?new
          ?HashMap();?

          SAXReader?reader?
          =?new
          ?SAXReader();?
          Document?document?
          =?reader.read(httpRequest.getRealPath(this
          .TokenConfig));?
          List?list1?
          =?document.getRootElement().selectNodes("/TokenList/Token/TokenForm"
          );?
          List?list2?
          =?document.getRootElement().selectNodes("/TokenList/Token/TokenAction"
          );?
          List?list3?
          =?document.getRootElement().selectNodes("/TokenList/Token/ErrorPage"
          );?

          Iterator?iter1?
          =
          ?list1.iterator();?
          Iterator?iter2?
          =
          ?list2.iterator();?
          Iterator?iter3?
          =
          ?list3.iterator();?
          while?(iter1.hasNext()&&iter2.hasNext()&&iter3.hasNext())?
          {?
          Element?element1?
          =
          ?(Element)?iter1.next();?
          Element?element2?
          =
          ?(Element)?iter2.next();?
          Element?element3?
          =
          ?(Element)?iter3.next();?
          TokenMap.put(element1.getStringValue(),?element2.getStringValue());?
          ErrorMap.put(element1.getStringValue(),?element3.getStringValue());?
          }
          ?
          logger.debug(
          "TokenFilter?Read?"
          ?
          +?httpRequest.getRealPath(this
          .TokenConfig)?
          +?"?is?OK!"
          );?
          }
          ?catch?(Exception?e)?{?
          logger.error(
          "TokenFilter?Read?"
          ?
          +?httpRequest.getRealPath(this
          .TokenConfig)?
          +?"?is?Error!"
          );?
          }
          ?

          }
          ?

          public?void
          ?doFilter(ServletRequest?srequest,?ServletResponse?sresponse,?
          FilterChain?chain)?
          throws?IOException,?ServletException?
          {?

          HttpServletRequest?httpRequest?
          =
          ?(HttpServletRequest)?srequest;?

          try?
          {?
          //取出實際的文件路徑直接調用文件,如index.html,login.jsp等?

          String?toURI?=?httpRequest.getRequestURI().replaceFirst(httpRequest.getContextPath(),?"");?
          if?(TokenMap==null
          )?
          {?
          initConfig(httpRequest);?
          }
          ?
          //檢測為提交jsp頁?

          if?(TokenMap.get(toURI)?!=?null)?
          {?
          FromTokenAction?token?
          =?new
          ?FromTokenAction();?
          token.execute(
          null,?null
          ,?srequest,?sresponse);?
          httpRequest.getSession().setAttribute(
          "PRE_TOKEN_FORM"
          ,?toURI);?
          logger.debug(
          "TokenFilter?save?'"+toURI?+"'?at?'PRE_TOKEN_FORM'?of?Session!"
          );?
          logger.debug(
          "TokenFilter?saveToken?to?'"+toURI?+"'?is?OK!"
          );?
          chain.doFilter(srequest,?sresponse);?
          return
          ;?
          }
          ?

          @SuppressWarnings(
          "unused"
          )?
          String?preURI?
          =(String)httpRequest.getSession().getAttribute("PRE_TOKEN_FORM"
          );?
          //檢測到為Action接收提交頁面?

          if?(TokenMap.get(preURI).equals(toURI))?
          {?
          TOTokenAction?token?
          =?new
          ?TOTokenAction();?
          token.execute(
          null,?null
          ,?srequest,?sresponse);?
          chain.doFilter(srequest,?sresponse);?
          return
          ;?
          }
          ?


          }
          ?catch?(Exception?e)?
          {?
          logger.error(e);?
          }
          ?

          chain.doFilter(srequest,?sresponse);?
          }
          ?

          public?void?setFilterConfig(final?FilterConfig?filterConfig)?
          {?
          this.filterConfig?=
          ?filterConfig;?
          }
          ?

          public?void?destroy()?
          {?
          TokenMap.clear();?
          ErrorMap.clear();?
          this.filterConfig?=?null
          ;?
          }
          ?

          //檢測到需要令牌增加一個令牌?

          public?class?FromTokenAction?extends?Action?{?
          public
          ?ActionForward?execute(ActionMapping?mapping,?ActionForm?form,?
          HttpServletRequest?request,?HttpServletResponse?response)?
          {?
          this
          .saveToken(request);?
          return?null
          ;?
          }
          ?
          }
          ?

          //到達Action前檢測令牌?

          public?class?TOTokenAction?extends?Action?{?
          public
          ?ActionForward?execute(ActionMapping?mapping,?ActionForm?form,?
          HttpServletRequest?request,?HttpServletResponse?response)?
          {?
          @SuppressWarnings(
          "unused"
          )?
          String?preURI?
          =(String)request.getSession().getAttribute("PRE_TOKEN_FORM"
          );?
          //如果檢測令牌錯誤執(zhí)行錯誤頁,正確將繼續(xù)執(zhí)行?

          if?(!isTokenValid(request,?true))?
          {?
          @SuppressWarnings(
          "unused"
          )?
          String?toURI?
          =
          ?(String)ErrorMap.get(preURI);?
          if?(toURI!=null
          )?
          {?
          RequestDispatcher?disp?
          =
          ?request.getRequestDispatcher(toURI);?
          try?
          {?
          disp.forward(request,?response);?

          }
          catch
          (Exception?e)?
          {?
          logger.error(e);?
          }
          ?
          }
          ?
          }
          ?
          return?null
          ;?
          }
          ?
          }
          ?

          }
          ?

          Web.xml的配制
          <!--?令牌自動加載配制?-->?
          <filter>?
          <filter-name>tokenFilter</filter-name>?
          <filter-class>com.yapulan.util.filter.TokenFilter</filter-class>?
          <init-param>?
          <param-name>tokenfile</param-name>?
          <param-value>/WEB-INF/TokenConfig.xml</param-value>?
          </init-param>?
          </filter>?

          注意:將代碼包中web.xml做以下修改:

          <filter-mapping>?
          <filter-name>tokenFilter</filter-name>?
          <url-pattern/*</url-pattern>?
          </filter-mapping>?
          設置好過濾器,只要配置列表即可避免所有的重復提交問題,不必在編程時再次考慮了

          <?xml?version="1.0"?encoding="UTF-8"?>?
          <TokenList?xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"?xsi:noNamespaceSchemaLocation="TokenConfig.xsd">?
          <Token>?
          <TokenForm>/index.jsp</TokenForm>?
          <TokenAction>/TokenAction.do</TokenAction>?
          <ErrorPage>/error.html</ErrorPage>?
          </Token>?
          <Token>?
          <TokenForm>/index1.jsp</TokenForm>?
          <TokenAction>/TokenAction1.do</TokenAction>?
          <ErrorPage>/error1.jsp</ErrorPage>?
          </Token>?
          <Token>?
          <TokenForm>/index2.jsp</TokenForm>?
          <TokenAction>/TokenAction2.do</TokenAction>?
          <ErrorPage>/error2.jsp</ErrorPage>?
          </Token>?
          <Token>?
          <TokenForm>/index3.jsp</TokenForm>?
          <TokenAction>/TokenAction3.do</TokenAction>?
          <ErrorPage>/error3.jsp</ErrorPage>?
          </Token>?
          </TokenList>?
          注意:本代碼可以很好的驗證非法的提交,對于管理非法的提交是一個不可多得的具有一定安全意義封裝。
          請熱心的朋友分析有無其它沒有考慮的細節(jié)問題,并且是否有可以進一部完善的地方,謝謝!

          轉自:http://www.aygfsteel.com/SE7EN/archive/2008/08/14/222083.html

          posted on 2008-11-29 02:22 duansky 閱讀(302) 評論(0)  編輯  收藏 所屬分類: Java

          主站蜘蛛池模板: 松江区| 西峡县| 延长县| 偃师市| 舞钢市| 北票市| 平塘县| 昌黎县| 蒲江县| 宜兰市| 广饶县| 大新县| 循化| 南靖县| 南漳县| 浦江县| 屏南县| 盐城市| 江都市| 岳普湖县| 施甸县| 东城区| 宝兴县| 呼玛县| 游戏| 永新县| 河北省| 洛阳市| 玉龙| 信丰县| 赫章县| 卢龙县| 肥东县| 凌云县| 万荣县| 沂水县| 姚安县| 旬邑县| 伊宁县| 灵台县| 交口县|