通過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é)問題,并且是否有可以進一部完善的地方,謝謝!

          posted on 2008-08-14 18:35 SE7EN 閱讀(378) 評論(0)  編輯  收藏


          只有注冊用戶登錄后才能發(fā)表評論。


          網站導航:
           
          <2008年8月>
          272829303112
          3456789
          10111213141516
          17181920212223
          24252627282930
          31123456

          導航

          統(tǒng)計

          常用鏈接

          留言簿(1)

          隨筆檔案

          搜索

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 砀山县| 刚察县| 东丰县| 新余市| 安西县| 东港市| 本溪市| 清苑县| 农安县| 西城区| 冀州市| 红原县| 平顶山市| 龙里县| 安仁县| 临猗县| 福泉市| 辽中县| 正宁县| 福清市| 兴海县| 乌兰浩特市| 连南| 北票市| 鹤壁市| 三原县| 隆尧县| 绩溪县| 舞钢市| 太白县| 仁布县| 轮台县| 清水县| 保亭| 天水市| 盐山县| 墨竹工卡县| 台南县| 瓮安县| 双流县| 抚州市|