瘋狂

          STANDING ON THE SHOULDERS OF GIANTS
          posts - 481, comments - 486, trackbacks - 0, articles - 1
            BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理

          淺析struts中的ExecuteAndWaitInterceptor,以及簡單例子

          Posted on 2010-09-25 00:59 瘋狂 閱讀(3258) 評論(0)  編輯  收藏 所屬分類: java 、strutsweb

            大致把源碼中類前面的一段注釋給翻譯一下:
              
               1 ExecuteAndWaitInterceptor很適合在后臺長時間運行的action時,他可以可為用戶一個友好的等待界面,例如進度條。
              2  不在默認的攔截stack 里面,使用的時候需要配置,但必須是在攔截堆棧的最后一個。
             大致配置如下:
            <action name="test" method="test" class="com.joe.web.action.ActionTest">
                   <interceptor-ref name="completeStack"/>
                   <interceptor-ref name="execAndWait">
                       <param name="delay">1000</param>
                      <param name="delaySleepInterval">50</param>
                 </interceptor-ref>
                <result name="wait">wait.jsp</result>
                <result name="success">success.jsp</result>
             </action>    3 使用的時候需要配置一個名為wait的result,并指向自己的等待頁面,如果沒有struts

          將使用FreeMarker代替,通過使用FreemarkerResult動態注入一個等待頁面:struts提供的面板頁面可見于:
          org/apache/struts2/interceptor/wait.ftl
          內容大致如下:

          <html>
              <head>
                  <meta http-equiv="refresh" content="5;url=<@s.url includeParams="none"/>"/>
              </head>
              <body>
                  Please wait while we process your request...
                  <p/>

                  This page will reload automatically and display your request when it is completed.
              </body>
          </html>

          其中的includeParams參數取值為

          none,不把參數參加到url參數中

          all,是把getpost中的參數參加到url參數中

          get,是只把get中的參數參加到url參數中

               execAndWait攔截器有2個參數:
                   delay :意思是初始等待多少秒才出現等待頁面。當在這個等待時間內action執行完畢,就不用出現wai界面,如果不配,一開始就會出現。
                 delaySleepInterval:每個對少時間檢查action是否執行完畢。
               
            -------------
          大致的原理是:strus遇到這種配置了execAndWait的action會另外起一個線程來執行,這個線程名叫BackgroundProcess,并通過一個done屬性的變化來標準執行情況,struts將此線程放到session中,頁面每隔一段時間去檢查是done==true?  如果不是,就據需返回wai頁面,否則返回主action的返回界面。
           BackgroundProcess大致源碼:
           
          public BackgroundProcess(String threadName, final ActionInvocation invocation, int threadPriority) {
                  
          this.invocation = invocation;
                  
          this.action = invocation.getAction();
                  
          try {
                      
          final Thread t = new Thread(new Runnable() {
                          
          public void run() {
                              
          try {
                                  beforeInvocation();
                                  result 
          = invocation.invokeActionOnly();
                                  afterInvocation();
                              }
           catch (Exception e) {
                                  exception 
          = e;
                              }


                              done 
          = true;
                          }

                      }
          );
                      t.setName(threadName);
                      t.setPriority(threadPriority);
                      t.start();
                  }
           catch (Exception e) {
                      exception 
          = e;
                  }

              }

          當這個action結束后會將done屬性設置為true表示執行結束,正是每次去檢查這個屬性來判別。

             攔截器主要源碼:

           

           if ((!executeAfterValidationPass || secondTime) && bp == null) {
                          bp = getNewBackgroundProcess(name, actionInvocation, threadPriority);
                          session.put(KEY + name, bp);//放入session
                          performInitialDelay(bp); // first time let some time pass before showing wait page
                          secondTime = false;
                      }

                      if ((!executeAfterValidationPass || !secondTime) && bp != null && !bp.isDone()) {//是否完畢
                          actionInvocation.getStack().push(bp.getAction());//將后臺action的相關信息push到statck,時候的頁面可是使用        
                  if (TokenHelper.getToken() != null) {
                              session.put(TokenHelper.getTokenName(), TokenHelper.getToken());
                          }

                          Map results = proxy.getConfig().getResults();
                          if (!results.containsKey(WAIT)) {//如果沒有配置wait,struts將為你inject一個
                              LOG.warn("ExecuteAndWait interceptor has detected that no result named 'wait' is available. " +
                                      "Defaulting to a plain built-in wait page. It is highly recommend you " +
                                      "provide an action-specific or global result named '" + WAIT +
                                      "'.");
                              // no wait result? hmm -- let's try to do dynamically put it in for you!

                              //we used to add a fake "wait" result here, since the configuration is unmodifiable, that is no longer
                              //an option, see WW-3068
                              FreemarkerResult waitResult = new FreemarkerResult();
                              container.inject(waitResult);
                              waitResult.setLocation("/org/apache/struts2/interceptor/wait.ftl");
                              waitResult.execute(actionInvocation);

                              return Action.NONE;
                          }

                          return WAIT;
                      } else if ((!executeAfterValidationPass || !secondTime) && bp != null && bp.isDone()) {//如果執行完畢return  bp.getResult();
                          session.remove(KEY + name);
                          actionInvocation.getStack().push(bp.getAction());

                          // if an exception occured during action execution, throw it here
                          if (bp.getException() != null) {
                              throw bp.getException();
                          }

                          return bp.getResult();
                      } else {
                          // this is the first instance of the interceptor and there is no existing action
                          // already run in the background, so let's just let this pass through. We assume
                          // the action invocation will be run in the background on the subsequent pass through
                          // this interceptor
                          return actionInvocation.invoke();
                      }

          。

          一個簡單的例子(不包含lib):
            /Files/freeman1984/execAndWait.rar
            
            


             
          主站蜘蛛池模板: 潢川县| 大余县| 北辰区| 南安市| 桓台县| 沿河| 云龙县| 西乌| 开封市| 宜川县| 柳州市| 昭平县| 泸水县| 泸定县| 东兰县| 沈丘县| 营口市| 右玉县| 江川县| 饶平县| 长治县| 兰坪| 永福县| 德惠市| 台湾省| 长白| 南宁市| 根河市| 西和县| 温州市| 石阡县| 芮城县| 昌都县| 丰宁| 泰来县| 廉江市| 永德县| 杂多县| 黄大仙区| 滨州市| 凤山县|