先前的文章提到/c/*的请求都是交给MainServlet处理的,现在分析对于不同的/c/*,例如/c/layout或者/c/update_layout等请求是怎么传递到不同的action去的呢。
下面以显示 Add Content 为例进行分析,Add Content 窗口其实是一个在 portlet-custom.xml 中定义的名为87的portlet。点击Add Content链接会产生一个Reqest,开始整个处理的流程。
1. Request的生成。
当时页面的源文件中有关的代码为:
<li class="add-content">
<a href="javascript: void(0);" onclick="LayoutConfiguration.toggle('10102', '87', '');">Add Content</a>
</li>
点击add content调用的是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请求发送到服务器,过程以后可以分析 */
用Wireshark捕捉到的Request数据如下,知道请求中含有/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);
/* 调用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 中,根据http的类型,分别调用 doPost, doGet, doPut, ...,由于ActionServlet中实现了doPost等方法,所以MainServlet.service()方法会传递到 ActionServlet中的doPost等方法。*/
4. ActionServlet.doPost()
process(request, response);
/* 在另外ActionServlet的不同方法中,例如doGet(),doPut(),都调用了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()方法,所以调用 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中定义的关于上面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 的呈现。这里对应的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又是如何实现最终把add content这个portlet显示出来的呢,下回接着分析。
[原]http://www.blogjava.net/libin2722/archive/2008/03/14/186276.html
分享到:
相关推荐
【深入浅出Liferay Portal】系列文章主要针对Liferay Portal 4.3.3版本进行讲解,旨在帮助读者深入理解这个企业级门户平台的内部机制。Liferay Portal是一款开源的企业级内容管理和协作平台,它提供了丰富的功能,如...
本书深入浅出地介绍了portlet开发,包括portlet生命周期、MVC Portlet、JSR 286规范以及portlet与JavaScript框架的交互,为开发者提供实操指导。 8. 《Liferay Portal Performance Tuning》 性能调优是任何系统都...
如《Liferay in Action》、《Liferay Portal Systems Development》和《Liferay User Interface Development》,以及一些中文文档,这些资源对于深入理解和开发Liferay应用非常有价值。 首先,《Liferay in Action...
温兵可能是一位在LifeRay社区有影响力的专家,他的著作通常会结合实际经验,深入浅出地解析LifeRay的开发技术,对初学者和有经验的开发者都极具价值。 2. **LifeRay二次开发指南**:二次开发指南是针对已经熟悉...
《Liferay 6.0.5 开发指南》是一本针对初学者的Liferay平台入门教程,它深入浅出地介绍了Liferay Portal的各种概念和技术,为开发者提供了全面的知识框架。Liferay是一个开源的企业级门户平台,它允许用户构建、管理...
在本指南中,柯自聪深入浅出地讲解了Liferay Portal的基础知识以及二次开发的核心技术。 1. **Liferay Portal 简介**: Liferay Portal 提供了一个统一的用户界面,用于整合各种Web服务、应用和信息资源。它支持多...
文章深入浅出地介绍了Portal技术的基础概念,以及Liferay如何在实际项目中实现这些特性。 其次,《Liferay-Portal架构.pdf》详细剖析了Liferay的架构设计。Liferay采用模块化的设计,主要包括服务层(Service Layer...
通过深入浅出地介绍JSF 2.0的核心概念、技术和最佳实践,本书为读者提供了一个全面了解JSF 2.0的窗口。无论是初学者还是有经验的开发者,都可以从中受益匪浅。此外,由于本书由JSF的创始人亲自编写,因此内容具有很...
本书深入浅出地讲解了JSF 2.0的各项特性和应用,为读者提供了一个从入门到精通的学习路径。 #### 二、作者简介 - **Ed Burns**:Sun Microsystems的高级员工工程师,自1994年以来一直从事客户端和服务端Web技术的...
这本书是Spring框架学习者的宝贵资源,它深入浅出地介绍了如何在实际开发中应用Spring框架。下面将详细阐述Spring框架的核心概念和关键特性,以及它们在2.0版本中的重要变化。 Spring框架是一个开源的应用程序框架...
"回购"一词暗示了该课程的受欢迎程度和教学效果,可能因为其深入浅出的讲解、实用的案例分析或者强大的技术支持,使得学员愿意重复学习或购买。 【标签解析】:“Java”标签明确了课程所使用的编程语言,Java是一种...