滿店香的家

          學習+實踐=進步

          第五部分 包拆解 4)org.directwebremoting.create包

              在dwr.xml中有,<creator>標簽負責公開用于Web遠程的類和類的方法,實際上最后調用的就是本包下面的script創建類。
          creator類型在1.1版本的時候有如下幾種,現在是3.0版本了,我查了下源碼,種類好像比下面要多(查XXXCreator有多少個)。
              new: 用Java的new關鍵字創造對象。 
              none: 它不創建對象,看下面的原因。 (v1.1+) 
              scripted: 通過BSF使用腳本語言創建對象,例如BeanShell或Groovy。 
              spring: 通過Spring框架訪問Bean。 
              jsf: 使用JSF的Bean。 (v1.1+) 
              struts: 使用Struts的FormBean。 (v1.1+) 
              pageflow: 訪問Beehive或Weblogic的PageFlow。 (v1.1+) 
             
              creator是在什么時候調用的呢?
               實際上,在Serlvet加載的時候有個doPost方法,doPost方法調用handle,handle再調用remotor,remotor最終調用相應的creator,比如NewCreator,creator實際上是執行創建script字符串的工作。
               舉例來說,我們想在html中某個地方直接顯示當前時間的long值,那么我們就可以調用java.util.Date類的getTime()方法。dwr.xml中寫法如下:

          <dwr> 
              
          <allow> 
                  
          <create creator="new" javascript="JDate">
                      
          <param name="class" value="java.util.Date"/>
                  
          </create>
                  
          <create creator="new" javascript="Demo">
                      
          <param name="class" value="your.java.Bean"/>
                  
          </create>
              
          </allow> 
          </dwr> 

           

          我們知道這樣所有的/dwr/*所有請求都由這個servlet來處理,那么實際上,瀏覽器加載
          <script type='text/javascript' src='dwr/interface/JDate.js'></script>時,實際上是在觸發servlet,這次觸發屬于系統觸發,不做事的,只有執行javascript調用方法時如:

          function getServerDateTime(){
              JDate.getTime(handleGetTime);
          }

          function handleGetTime(dateTime){
              DWRUtil.setValue(
          "date", dateTime);
          }


          才會觸發下面

          protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException
              
          {
                  doPost(req, resp);
              }


          doGet會調用到doPost

          protected void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
              
          {
                  
          try
                  
          {
                      webContextBuilder.set(request, response, getServletConfig(), getServletContext(), container);

                      UrlProcessor processor 
          = container.getBean(UrlProcessor.class);
                      processor.handle(request, response);
                  }

                  
          finally
                  
          {
                      webContextBuilder.unset();
                  }

              }
            在proccessor中我們看到如下代碼
           public void handle(HttpServletRequest request, HttpServletResponse response) throws IOException
              
          {
                  
          try
                  
          {
                      String pathInfo 
          = request.getPathInfo();
                      contextPath 
          = request.getContextPath();

                      
          if (pathInfo == null || pathInfo.length() == 0 || "/".equals(pathInfo))
                      
          {
                          response.sendRedirect(contextPath 
          + request.getServletPath() + indexHandlerUrl);
                      }

                      
          else
                      
          {
                          
          // Loop through all the known URLs
                          for (Entry<String, Object> entry : urlMapping.entrySet())
                          
          {
                              String url 
          = entry.getKey();

                              
          // If this URL matches, call the handler
                              if (pathInfo.startsWith(url))
                              
          {
                                  Handler handler 
          = (Handler) entry.getValue();
                                  handler.handle(request, response);
                                  
          return;
                              }

                          }


                          notFoundHandler.handle(request, response);
                      }

                  }

                  
          catch (Exception ex)
                  
          {
                      exceptionHandler.setException(ex);
                      exceptionHandler.handle(request, response);
                  }

              }

          這些handle有多種
          1,
          /**
           * A Handler that supports requests for auth.js
            */
          public class AuthHandler extends JavaScriptHandler
          2,
          /**
           * A Handler that supports requests for engine.js
           * @author Joe Walker [joe at getahead dot ltd dot uk]
           */
          public class EngineHandler extends JavaScriptHandler
          3,
          /**
           * A Handler that supports requests for util.js
           * @author Joe Walker [joe at getahead dot ltd dot uk]
           */
          public class GiHandler extends JavaScriptHandler
          4,
          /**
           * A handler for interface generation requests
           * @author Joe Walker [joe at getahead dot ltd dot uk]
           */
          public class InterfaceHandler extends JavaScriptHandler
          上面三種都是系統范圍的handle,對于我們自己編寫的類,應該是觸發InterfaceHandler 。

          我們再看如下關系
          public abstract class CachingFileHandler implements Handler
          public abstract class TemplateHandler extends CachingFileHandler
          public abstract class JavaScriptHandler extends TemplateHandler
          public class InterfaceHandler extends JavaScriptHandler
          逐級往上繼承

          InterfaceHandler,我們看到如下代碼,執行順序-4,里面調用了遠程remoter
              protected String generateTemplate(HttpServletRequest request, HttpServletResponse response) throws IOException
              
          {
                  String scriptName 
          = request.getPathInfo();
                  scriptName 
          = scriptName.replace(interfaceHandlerUrl, "");

                  String contextServletPath 
          = request.getContextPath() + request.getServletPath();

                  
          if (scriptName.endsWith(PathConstants.EXTENSION_JS))
                  
          {
                      scriptName 
          = scriptName.replace(PathConstants.EXTENSION_JS, "");
                      
          if (!LocalUtil.isJavaIdentifier(scriptName))
                      
          {
                          log.debug(
          "Throwing at request for script with name: '" + scriptName + "'");
                          
          throw new SecurityException("Script names may only contain Java Identifiers");
                      }


                      
          return remoter.generateInterfaceScript(scriptName, contextServletPath);
                  }

                  
          else if (scriptName.endsWith(PathConstants.EXTENSION_SDOC))
                  
          {
                      scriptName 
          = scriptName.replace(PathConstants.EXTENSION_SDOC, "");
                      
          if (!LocalUtil.isJavaIdentifier(scriptName))
                      
          {
                          log.debug(
          "Throwing at request for script with name: '" + scriptName + "'");
                          
          throw new SecurityException("Script names may only contain Java Identifiers");
                      }


                      
          return remoter.generateInterfaceSDoc(scriptName, contextServletPath);
                  }

                  
          else
                  
          {
                      log.debug(
          "Throwing at request for script with unknown extension: '" + scriptName + "'");
                      
          throw new SecurityException("Unknown extension");
                  }

              }
          類JavaScriptHandler代碼如下,調用了父類TemplateHandler的generateCachableContent方法執行順序-2
          protected String generateCachableContent(HttpServletRequest request, HttpServletResponse response) throws IOException
              
          {
                  String output 
          = super.generateCachableContent(request, response);

                  
          if (debug || compressor == null)
                  
          {
                      
          return output;
                  }


                  
          try
                  
          {
                      
          return compressor.compressJavaScript(output);
                  }

                  
          catch (Exception ex)
                  
          {
                      log.warn(
          "Compression system (" + compressor.getClass().getSimpleName() +") failed to compress script", ex);
                      
          return output;
                  }

              }


           TemplateHandler類代碼如下執行順序-3,里面調用了generateTemplate方法
              protected String generateCachableContent(HttpServletRequest request, HttpServletResponse response) throws IOException
              
          {
                  String template 
          = generateTemplate(request, response);

                  Map
          <String, String> replace = getSearchReplacePairs();
                  
          if (replace != null)
                  
          {
                      
          for (Map.Entry<String, String> entry : replace.entrySet())
                      
          {
                          String search 
          = entry.getKey();
                          
          if (template.contains(search))
                          
          {
                              template 
          = template.replace(search, entry.getValue());
                          }

                      }

                  }


                  
          return template;
              }


              
          /**
               * Generate a template to undergo search and replace processing according to
               * the search and replace pairs from {
          @link #getSearchReplacePairs()}.
               * 
          @param request The HTTP request data
               * 
          @param response Where we write the HTTP response data
               * 
          @return A template string containing ${} sections to be replaced
               
          */

              
          protected abstract String generateTemplate(HttpServletRequest request, HttpServletResponse response) throws IOException;

          CachingFileHandler類代碼如下,handle方法里面調用了generateCachableContent()方法
          執行順序-1
          public void handle(HttpServletRequest request, HttpServletResponse response) throws IOException
              
          {
                  
          if (isUpToDate(request))
                  
          {
                      response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
                      
          return;
                  }


                  String output;

                  
          synchronized (scriptCache)
                  
          {
                      String url 
          = request.getPathInfo();
                      output 
          = scriptCache.get(url);
                      
          if (output == null)
                      
          {
                          output 
          = generateCachableContent(request, response);
                      }

                      scriptCache.put(url, output);
                  }


                  response.setContentType(mimeType);
                  response.setDateHeader(HttpConstants.HEADER_LAST_MODIFIED, CONTAINER_START_TIME);
                  response.setHeader(HttpConstants.HEADER_ETAG, ETAG);

                  PrintWriter out 
          = response.getWriter();
                  out.println(output);
              }

          代碼有點繞
          我們看到在InterfaceHandler類中
          有一行代碼如下:
          remoter.generateInterfaceScript(scriptName, contextServletPath);
          如果按例子,對于聲明在dwr.xml中的JDate類,scriptName應該是JDate,contextServletPath應該是'dwr/interface/'

          執行generateInterfaceScript方法生成相應的字符串,對應于JDate.js
          在CachingFileHandler類中的方法handle最后一行如下,
          out.println(output);
          在這個地方,將返回內容輸出到客戶端。

          posted on 2008-03-30 00:59 滿店香 閱讀(737) 評論(0)  編輯  收藏 所屬分類: dwr源碼分析

          主站蜘蛛池模板: 辽宁省| 武宣县| 通城县| 惠安县| 梁山县| 克拉玛依市| 漾濞| 利津县| 哈巴河县| 逊克县| 罗江县| 米脂县| 宁河县| SHOW| 东乡| 水城县| 武威市| 皮山县| 黄陵县| 象州县| 安溪县| 中西区| 广州市| 汝阳县| 贵阳市| 桦川县| 日喀则市| 许昌县| 恭城| 利川市| 道真| 上栗县| 万盛区| 南宫市| 邵东县| 布拖县| 怀仁县| 永定县| 莲花县| 宁化县| 惠安县|