瘋狂

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

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

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

            大致把源碼中類前面的一段注釋給翻譯一下:
              
               1 ExecuteAndWaitInterceptor很適合在后臺長時間運行的action時,他可以可為用戶一個友好的等待界面,例如進度條。
              2  不在默認(rèn)的攔截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動態(tài)注入一個等待頁面:struts提供的面板頁面可見于:
          org/apache/struts2/interceptor/wait.ftl
          內(nèi)容大致如下:

          <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參數(shù)取值為

          none,不把參數(shù)參加到url參數(shù)中

          all,是把getpost中的參數(shù)參加到url參數(shù)中

          get,是只把get中的參數(shù)參加到url參數(shù)中

               execAndWait攔截器有2個參數(shù):
                   delay :意思是初始等待多少秒才出現(xiàn)等待頁面。當(dāng)在這個等待時間內(nèi)action執(zhí)行完畢,就不用出現(xiàn)wai界面,如果不配,一開始就會出現(xiàn)。
                 delaySleepInterval:每個對少時間檢查action是否執(zhí)行完畢。
               
            -------------
          大致的原理是:strus遇到這種配置了execAndWait的action會另外起一個線程來執(zhí)行,這個線程名叫BackgroundProcess,并通過一個done屬性的變化來標(biāo)準(zhǔn)執(zhí)行情況,struts將此線程放到session中,頁面每隔一段時間去檢查是done==true?  如果不是,就據(jù)需返回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;
                  }

              }

          當(dāng)這個action結(jié)束后會將done屬性設(shè)置為true表示執(zhí)行結(jié)束,正是每次去檢查這個屬性來判別。

             攔截器主要源碼:

           

           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的相關(guān)信息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()) {//如果執(zhí)行完畢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
            
            


             
          主站蜘蛛池模板: 扎鲁特旗| 原阳县| 汝州市| 阿图什市| 沈丘县| 姜堰市| 汉寿县| 葵青区| 阳城县| 沅江市| 腾冲县| 延庆县| 崇文区| 奉化市| 浮梁县| 闵行区| 濉溪县| 丽水市| 运城市| 南开区| 新河县| 大荔县| 东丽区| 伊宁县| 晴隆县| 资兴市| 孝感市| 喀喇| 都兰县| 正阳县| 云林县| 阿克苏市| 东乌| 泗阳县| 岐山县| 介休市| 南昌市| 隆回县| 康马县| 阳城县| 法库县|