Terry.Li-彬

          虛其心,可解天下之問;專其心,可治天下之學;靜其心,可悟天下之理;恒其心,可成天下之業(yè)。

            BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
            143 隨筆 :: 344 文章 :: 130 評論 :: 0 Trackbacks
           

          先前的文章提到/c/*的請求都是交給MainServlet處理的,現(xiàn)在分析對于不同的/c/*,例如/c/layout或者/c/update_layout等請求是怎么傳遞到不同的action去的呢。

          下面以顯示 Add Content 為例進行分析,Add Content 窗口其實是一個在 portlet-custom.xml 中定義的名為87的portlet。點擊Add Content鏈接會產(chǎn)生一個Reqest,開始整個處理的流程。

          1. Request的生成。

          當時頁面的源文件中有關(guān)的代碼為:
          <li class="add-content">
          <a href="javascript: void(0);" onclick="LayoutConfiguration.toggle('10102', '87', '');">Add Content</a>
          </li>

          點擊add content調(diào)用的是LayoutConfiguration.toogle()。

          layout_configuratioin.js
          var LayoutConfiguration = {
            toggle : function (plid, ppid, doAsUserId) {
            var url = themeDisplay.getPathMain() + "/portal/render_portlet?p_l_id=" + plid + "&p_p_id=" +ppid + "&doAsUserId=" + doAsUserId + "&p_p_state=exclusive";
            AjaxUtil.update(url, popup, {onComplete: function(){
                         LayoutConfiguration.init();
                         Liferay.Util.addInputType();
                         Liferay.Util.addInputFocus();}
            });};
            /*總之是會生成一個Ajax請求發(fā)送到服務(wù)器,過程以后可以分析 */

          用Wireshark捕捉到的Request數(shù)據(jù)如下,知道請求中含有/c/portal/render_portlet字段,那自然會送入 MainServlet處理了。

          2. MainServlet.service()

          /* 這里是Request首先到達的地方*/

          ServletContext ctx = getServletContext();
          req.setAttribute(WebKeys.CTX, ctx);
          PortletRequestProcessor portletReqProcessor = PortletRequestProcessor.getInstance(this, moduleConfig);
          ctx.setAttribute(WebKeys.PORTLET_STRUTS_PROCESSOR, portletReqProcessor);
          callParentService(req, res);
          /* 調(diào)用ActionServlet.service(),由于在ActionServlet中沒有覆蓋service方法,所以 MainServlet 的super.service() 追溯到HttpServlet 的service方法 */

          3. HttpServlet.service()

          if (method.equals(METHOD_GET)) { ,,,
          } else if (method.equals(METHOD_POST)) {
            doPost(req, resp);
          } else if (method.equals(METHOD_PUT)) {
            doPut(req, resp); 
          } else if (method.equals(METHOD_DELETE)) {
            doDelete(req, resp);
          } else if (method.equals(METHOD_OPTIONS)) {
            doOptions(req,resp);
          } else if (method.equals(METHOD_TRACE)) {
            doTrace(req,resp);
          }

          /* 在 service 中,根據(jù)http的類型,分別調(diào)用 doPost, doGet, doPut, ...,由于ActionServlet中實現(xiàn)了doPost等方法,所以MainServlet.service()方法會傳遞到 ActionServlet中的doPost等方法。*/

          4. ActionServlet.doPost()

          process(request, response);

          /* 在另外ActionServlet的不同方法中,例如doGet(),doPut(),都調(diào)用了process()方法。*/


          5. ActionServlet.process()

          ModuleConfig config = getModuleConfig(request);
          RequestProcessor processor = getProcessorForModule(config);
          if (processor == null) {
            processor = getRequestProcessor(config);
          }
          processor.process(request, response);

          /* 最終傳遞到對應的Request Processor 的process()方法中去,也就是PortalRequestProcessor.process() */


          6. PortalRequestProcessor.process()

          public void process(HttpServletRequest req, HttpServletResponse res)
            throws IOException, ServletException {
            String path = super.processPath(req, res); //path = “/portal/render_portlet”
            ActionMapping mapping = (ActionMapping)moduleConfig.findActionconfig(path);
            super.process(req, res);
            /*由于TilesRequestProcessor中沒有定義process()方法,所以調(diào)用 RequestProcessor.process() */
          }


          7. RequestProcessor.process()

          public void process(HttpServletRequest request, HttpServletResponse response)
            throws IOException, ServletException {

            String path = processPath(request, response);
            //這里path = “/portal/render_portlet”.

            ActionMapping mapping = processMapping(request, response, path);
            //這里找到在struts-config.xml中定義的關(guān)于上面path的mapping.

            Action action = processActionCreate(request, response, mapping);
            //這里生成了RenderPortletAction.

            ActionForward forward = processActionPerform(request, response, action, form, mapping);

            processForwardConfig(request, response, forward);
          }

          至此,每個由 MainServlet 傳遞來的 Request 都能到達對應的 Action,例如 LayoutAction,RenderPortletAction,UpdateLayoutAction,由這些 Action 最終完成 Layout 和 Portlet 的呈現(xiàn)。這里對應的action是RenderPortletAction(由下面的struts-config.xml中定義)。

          下面以RenderPortletAction為例說明進一步的action過程。在struts-config.xml這個文件中定義了action class, forward path。

          <action path="/portal/layout" type="com.liferay.portal.action.LayoutAction">
            <forward name="portal.layout" path="portal.layout" />
          </action>

          <action path="/portal/update_layout" type="com.liferay.portal.action.UpdateLayoutAction" />

          <action path=“/portal/render_portlet” type=“com.liferay.portal.action.RenderPortletAction”>
            <forward name=“/portal/render_portlet” path=“/portal/render_portlet.jsp”/>
          </action>
          <!-- 這里定義了由RenderPortletAction來處理”/portal/render_portlet”,而且最后要forward到” /portal/render_portlet.jsp”。所以最后會把render_portlet.jsp包含到response的頁面當中-- >

          那render_portlet.jsp又是如何實現(xiàn)最終把add content這個portlet顯示出來的呢,下回接著分析。


           

          Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=2177383

          posted on 2008-03-14 14:12 禮物 閱讀(1177) 評論(0)  編輯  收藏 所屬分類: Liferay
          主站蜘蛛池模板: 宜都市| 讷河市| 色达县| 焦作市| 台中市| 成安县| 汽车| 大英县| 沂南县| 沾益县| 泗水县| 陇南市| 乌鲁木齐市| 镇远县| 安多县| 手机| 奎屯市| 黄平县| 古蔺县| 伊吾县| 鹿泉市| 扎鲁特旗| 封丘县| 尚志市| 和田县| 三台县| 红安县| 博野县| 宜君县| 南乐县| 平遥县| 垫江县| 繁昌县| 抚宁县| 南木林县| 东乌珠穆沁旗| 临猗县| 合川市| 新巴尔虎右旗| 米林县| 正蓝旗|