- 浏览: 194797 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
官人与夫人:
我的也是,看完特地登陆来,赞一个!
SpringMVC JPA 事务,数据库保存操作没有异常但数据保存不成功 -
悲伤的小脑:
这个少了 种情况吧。就是一个时间段完全包含另外一个时间段,这应 ...
java 判断两个时间段是否有交集 -
nilm61:
vip3652204732 写道为什么会报NULL错误,路径是 ...
java调用ffmpeg获取视频信息函数代码 -
vip3652204732:
为什么会报NULL错误,
路径是对的啊。
68行报NULL错误 ...
java调用ffmpeg获取视频信息函数代码 -
liuxuejin:
好!真需要
java调用ffmpeg获取视频信息函数代码
当用户在浏览器地址栏上输入http://localhost:8080/ 后,经过几次迭代,服务器最终处理的是http://localhost:8080/c/portal/update ,那当服务器收到/c/portal/update的请求后做了什么动作,最后是怎么向浏览器发送网页信息呢?
1. 首先MainServlet接收这个请求,然后传递到LayoutAction。(具体怎么传递后续会介绍到)
在struts-config.xml中有定义,表明有关"/portal/layout"的请求是由LayoutAction来处理的。而在tiles-def.xml中定义"/portal/layout"最终传递到"/portal/layout.jsp"。
struts-config.xml
------------------------
<action path="/portal/layout" type="com.liferay.portal.action.LayoutAction">
<forward name="portal.layout" path="portal.layout" />
</action>
tiles-def.xml
------------------
<definition name="portal.layout" extends="portal">
<put name="content" value="/portal/layout.jsp" />
<put name="selectable" value="true" />
</definition>
2. 下面分析LayoutAction的简要流程
LayoutAction.execute()
--------------------------------
ThemeDisplay themeDisplay = (ThemeDisplay)req.getAttribute(WebKeys.THEME_DISPLAY);
Layout layout = themeDisplay.getLayout();
/* 加入/html/portal/layout/view/portlet.jsp 到网页*/
incluldeLayoutContent
(req, res, themeDisplay, layout);
/* 加入/html/portal/layout.jsp 到网页,先portlet.jsp,后layout.jsp*/
return mapping.findForward("portal.layout");
LayoutAction.includeLayoutContent()
-----------------------------------------------------
String path = StrutsUtil.TEXT_HTML_DIR;
/* path = "/html" */
path += PortalUtil.getLayoutViewPage(layout);
/* path = "/html/portal/layout/view/portlet.jsp" */
RequestDispatcher rd = ctx.getRequestDispatcher(path);
rd.include(req, stringServletRes);
可见两个jsp文件是页面的关键所在。
/portal/layout/view/portlet.jsp
-----------------------------------------
<%
String content = LayoutTemplateLocalUtil.getContent(layoutTypePortlet.getLayoutTemplateId(),
false, theme.getThemeId());
%>
<%= RuntimePortletUtil.processTemplate
(application, request, response, pageContext, content) %>
/*****************************************************
其中content的内容通过断点调试可以知道(是什么时候生成的呢?)
<div class="columns-2" id="content-wrapper">
<table id="layout-grid">
<tr>
<td class="lfr-column thirty" id="column-1" valign="top">
$processor.processColumn("column-1")
</td>
<td class="lfr-column seventy" id="column-2" valign="top">
$processor.processColumn("column-2")
</td>
</tr>
</table>
</div>
*****************************************************/
/* RuntimePortletUtil.processTemplate()函数返回的是一个很长很长的字符串,就是最终用于显示页面上各个portlet的代码,下面有分析 */
RuntimePortletUtil.processTemplate()
------------------------------------------------------
TemplateProcessor processor = new TemplateProcessor(ctx, req, res, portletId);
VelocityContext vc = new VelocityContext();
vc.put("processor", processor);
// Velocity variables
VelocityVariables.insertVariables(vc, req);
vc.put("taglibLiferay", velocityTaglib);
vc.put("theme", velocityTaglib);
StringWriter sw = new StringWriter();
Velocity.evaluate(vc, sw, RuntimePortletUtil.class.getName(), content);
String output = sw.toString();
/*****************************************************
output的初始内容为:
<div class="columns-3" id="content-wrapper">
<table id="layout-grid">
<tr>
<td class="lfr-column thirty" id="column-1" valign="top">
[$TEMPLATE_COLUMN_column-1$]
</td>
<td class="lfr-column thirty" id="column-2" valign="top">
[$TEMPLATE_COLUMN_column-2$]
</td>
<td class="lfr-column thirty" id="column-3" valign="top">
[$TEMPLATE_COLUMN_column-3$]
</td>
</tr>
</table>
</div>
*****************************************************/
Map columnsMap = processor.getColumnsMap();
while (itr.hasNext()) {
Map.Entry entry = (Map.Entry)itr.next();
String key = (String)entry.getKey();
String value = (String)entry.getValue();
output = StringUtil.replace(output, key, value);
}
/
*****************************************************
如果首页面上有四个portlet,名字为A,B,C,D,其中A在左边一列上,B,C同在中间一列,D在右边一列。则output的内容为:
<div class="columns-3" id="content-wrapper">
<table id="layout-grid">
<tr>
<td class="lfr-column thirty" id="column-1" valign="top">
<div class="lfr-portlet-column" id="layout-column_column-1">
[$TEMPLATE_PORTLET_A$]
</div>
</td>
<td class="lfr-column thirty" id="column-2" valign="top">
<div class="lfr-portlet-column" id="layout-column_column-2">
[$TEMPLATE_PORTLET_B$]
[$TEMPLATE_PORTLET_C$]
</div>
</td>
<td class="lfr-column thirty" id="column-3" valign="top">
<div class="lfr-portlet-column" id="layout-column_column-3">
[$TEMPLATE_PORTLET_D$]
</div>
</td>
</tr>
</table>
</div>
*****************************************************/
Map portletsMap = processor.getPortletsMap();
itr = portletsMap.entrySet().iterator();
while (itr.hasNext()) {
StringMaker sm = new StringMaker();
processPortlet(sm, ctx, req, res, portlet, queryString, columnId, columnPos,columnCount, null);
output = StringUtil.replace(output, "[$TEMPLATE_PORTLET_" + portlet.getPortletId() + "$]", sm.toString());
/*****************************************************
这里每迭代一个portlet,output的内容中就添加了该portlet的view.jsp代码段落,而且还会增加portlet的标准头部和边框,如最小化,关闭等按钮及其对应的JavaScript代码。
*****************************************************/
}
return output;
/* 这个output就是在portlet.jsp中要显示的内容 */
portal.jsp
------------
<c:choose>
<c:when test="<%= themeDisplay.isStateExclusive() %>">
<%= request.getAttribute(WebKeys.LAYOUT_CONTENT) %>
</c:when>
<c:when test="<%= themeDisplay.isStatePopUp() %>">
<liferay-theme:include page="portal_pop_up.jsp" />
</c:when>
<c:otherwise>
<liferay-theme:include page="portal_normal.jsp
" />
</c:otherwise>
</c:choose>
在Liferay中没有发现portal_normal.jsp的踪影,发现portal_normal.vm似乎有点相关。portal_normal粉墨登场。
portal_normal.vm
-------------------------
#parse ($init)
<html dir="#language ("lang.dir")">
<head>
<title>$company_name - $the_title</title>
$theme.include($top_head_include
)
#css ($css_main_file)
#js ($js_main_file)
#if ($company_logo != "")
<style type="text/css">
#banner .logo {background: url($company_logo) no-repeat;
height: ${company_logo_height}px;
width: ${company_logo_width}px; }
</style>
#end
</head>
<body class="$css_class">
$theme.include($top_messages_include)
<div id="wrapper">
<div id="banner">
<div id="banner-inner">
<h1 class="logo">
<a href="$company_url">$company_name</a>
</h1>
<div id="page-search">
$theme.journalContentSearch()
</div>
#parse ("$full_templates_path/dock.vm")
#if ($update_available_url)
<div class="popup-alert-notice">
<a class="update-available"
href="$update_available_url">#language("updates-are-available-for-liferay")</a>
</div>
#end
#if ($has_navigation)
#parse ("$full_templates_path/navigation.vm")
#end
</div>
</div>
#if ($selectable)
$theme.include($content_include)
#else
<div id="content-wrapper" class="login">
$portletDisplay.recycle()
$portletDisplay.setTitle($the_title)
$theme.wrapPortlet("portlet.vm", $content_include)
</div>
#end
<div id="footer">
<p class="language">$theme.language()</p>
</div>
</div>
$theme.include($bottom_ext_include)
$theme.include($session_timeout_include)
$theme.include($sound_alerts_include)
</body>
</html>
可见关键是一些Velocity变量的值,例如$top_head_include。
init.vm
----------
#set ($bottom_ext_include = "$dir_include/common/themes/bottom.jsp")
#set ($content_include = "$dir_include$tilesContent")
#set ($session_timeout_include = "$dir_include/common/themes/session_timeout.jsp")
#set ($sound_alerts_include = "$dir_include/common/themes/sound_alerts.jsp")
#set ($top_head_include = "$dir_include/common/themes/top_head.jsp")
#set ($top_messages_include = "$dir_include/common/themes/top_messages.jsp")
可见$top_head_include就是top_head.jsp。
top_head.jsp
-------------------
<%@ include file="/html/common/themes/top_js.jspf" %>
<%@ include file="/html/common/themes/top_js-ext.jsp" %>
portal/portal-web/docroot/html/common/themes/top_js.jspf
<%
String[] javaScriptFiles = PropsUtil.getArray(PropsUtil.JAVASCRIPT_FILES);
for (int i = 0; i < javaScriptFiles.length; i++) {
%>
<script src="<%= themeDisplay.getPathJavaScript() %>/<%= javaScriptFiles[i] %>"
type="text/javascript"></script>
<%
}
%>
那javascriptFiles又如何得到的呢?
portal.properties
------------------------
javascript.files=\
jquery/jquery.js,\
jquery/cookie.js,\
jquery/tabs.js,\
\
liferay/liferay.js,\
liferay/browser.js,\
liferay/util.js,\
liferay/language.js,\
liferay/layout.js,\
\
liferay/ajax.js,\
liferay/animate.js,\
liferay/auto_fields.js,\
liferay/color_picker.js,\
liferay/columns.js,\
liferay/dock.js,\
liferay/dynamic_select.js,\
liferay/freeform.js,\
liferay/layout_configuration.js,......
另外还有一个很重要的properties文件值得关注:language.properties。好累啊,还有很多细节可以继续挖掘,还涉及到Velocity的一些变量的操作,休息下先。
发表评论
-
Liferay中的Portlet事件通信
2013-12-31 09:46 776Liferay中的Portlet事件通信在有的项目开发中是需 ... -
Resources for Liferay Developers
2013-06-21 22:04 849The following are useful re ... -
liferay webservice 使用
2012-12-18 14:57 17951.自定义实体向外提供webservice接口的步骤 ... -
Liferay 验证码动态刷新
2012-07-23 19:11 13801.使用liferay标签生成 验证码的url < ... -
liferay6.1 启用logj4j.properties定义日志
2012-07-02 14:57 1327在编译好的环境下 即tomcat/webapp/ROOT/WE ... -
liferay 一个实例对应多个域名
2012-06-14 15:00 990在 社区 组织 的管理页面 中有个设置 liferay6 ... -
liferay6.1 环境搭建遇到点问题
2012-06-13 18:07 1088执行 ant all 出现问题 The enviro ... -
liferay 页面的portlet:defineObjects 标签
2012-06-11 21:28 1137<defineObjects> 标记的作用: ... -
liferay6.1sdk目录认识
2012-06-11 21:00 1012iferay SDK有如下的目录结 ... -
liferay 未了解的领域
2012-06-07 14:20 05.2中通过SharePoint协议与MS Office整合 ... -
mark liferay 表结构分析
2012-04-26 16:22 1349liferay中每个page(layout)的界面顺序是通过l ... -
几个liferay整合
2012-04-18 09:51 0Liferay integration with LDAP ... -
liferay theme中添加portlet实例及几个theme中使用变量
2012-02-29 20:09 8831、 在theme中直接加入上面的标签就可以把指定的por ... -
liferay4.3笔记之整合CAS server进行单点登录(SSO)
2011-04-14 10:04 1137Lieferay和web项目中整合Li ... -
Liferay 5.2.3: custom URLs formats
2011-04-14 09:29 724Liferay SEO capabilities s ... -
Velocity模板(VM)语言介绍 1 liferay 中的vm 转转
2011-03-31 10:14 17361. 关于 Veloci ... -
自定义页面布局Template转
2011-03-31 09:54 1096一、编写模板文件 我们将该页面风格名称定义为1_2_ ...
相关推荐
### Liferay Portal的内容和布局详解 #### 一、布局(Layout) **布局**是Liferay Portal中用于管理Portlet的关键概念之一。布局不仅决定着Portlet的呈现方式,还影响着用户的交互体验。在Liferay中,布局是通过一...
### Liferay Portal 二次开发详解 #### 一、Liferay Portal 概览 **Liferay Portal** 是一款开源的企业级门户平台,它基于Java技术构建,支持多种标准,包括JSR 168 和 WSRP (Web Services for Remote Portlets)。...
### Liferay Portal 模板开发知识点详解 #### 一、概述 Liferay Portal 是一个开源的企业级内容管理系统,主要用于构建企业门户和社区网站。Liferay Portal 提供了强大的功能,如用户管理、权限控制、工作流等,...
【知识点详解】 在部署Liferay Portal时,与Oracle数据库的集成是关键步骤。以下是对配置过程的详细解释: 1. **数据库配置修改**: - 首先,你需要在`portal-impl\src\portal.properties`文件中,取消Hypersonic...
#### 四、`web.xml`文件详解 `web.xml`文件中包含了多个元素,用于配置Liferay应用的各种参数。其中,`context-param`元素用于配置加载属性文件的信息,例如上面提到的`library-portlet.properties`。 ```xml ...
Liferay 是一个开源的企业级门户平台,用于构建和管理企业网站、社交网络和工作流程。在 Liferay 中,`portal.properties` 文件是一个至关重要的配置文件,它定义了系统的全局属性和行为。对于 Liferay 6.0.5 版本,...
《Liferay Portal文档》是一份详尽的指南,主要介绍了Liferay Portal的架构、工作原理及其核心组件——Portlet。Liferay Portal是一款开源的企业级门户平台,它提供了丰富的功能,如内容管理、社交网络、协作工具等...
【Liferay Portal 知识详解】 Liferay Portal 是一款开源的企业级门户平台,它提供了丰富的功能,如内容管理、社交网络、工作流程等,适用于构建企业内部或外部的交互式网站。本文将深入探讨 Liferay Portal 的核心...
《深入理解Alloy_Liferay:基于YUI封装的框架及使用文档详解》 Alloy_Liferay是一款基于YUI(Yahoo User Interface Library)封装的框架,主要用于Liferay Portal的开发和扩展。这款框架集成了YUI的强大功能,为...
**Liferay Benchmark Extension - 插件详解** Liferay Benchmark Extension 是一个专为Liferay门户平台设计的性能测试工具,主要用于衡量其在不同导航模式下的页面加载速度。Liferay是一款广泛使用的开源企业级内容...
**Liferay Luminis Bootstrap 3.0 布局详解** Liferay 是一款功能强大的开源企业级门户平台,它提供了丰富的自定义能力和强大的社区管理功能。Luminis 是 Liferay 的一个主题框架,旨在提供更美观、响应式的设计...
### Tomcat+Nginx配置详解 #### 一、Linux环境下Tomcat与JDK的安装配置 ##### 1. JDK 安装与环境变量配置 在Linux环境下安装JDK是搭建Tomcat服务器的基础步骤之一。 - **下载并解压JDK**: ```bash # tar xvf ...
### Portlet规范详解 #### 一、Portlet概念解析 Portlet规范,主要涉及JSR#168标准,是专为门户应用设计的一套框架,用于构建高度个性化和交互式的Web应用程序。它将门户(Portal)分解为三个关键部分:Portal ...
- **BookmarkPortlet**:一个简单的示例Portlet,用于演示基本的Portlet开发流程。 #### 6. **Portlet API - 基本元素** - **Portlet类**:提供了Portlet的核心功能实现方法,如处理请求、设置响应等。 - **...
在Windows XP系统下,配置过程如下: 【知识点详解】: 1. **JAVA_HOME**: 这个环境变量用于指明JDK的安装路径,例如D:\java\jdk1.5.0_08。它不仅对JDK本身,也对依赖JDK的其他应用,如Tomcat,Eclipse等至关重要。...
- **Liferay Portlet**:Liferay是一款流行的开源Portal平台,支持多种Portlet开发方式。 ##### 5. 高级Portlet技术 - **自定义Portlet行为**:通过扩展Portlet API来实现更复杂的业务逻辑。 - **Portlet间通信**:...
8. **portlet容器**:如Liferay Portal、IBM WebSphere Portal等,它们提供portlet运行所需的环境和服务,处理portlet的渲染、安全性和其他管理功能。 9. **用户体验**:良好的门户设计应考虑用户体验,包括界面...
**Portlet技术详解** Portlet是一种在Web应用程序中构建可重用、可组合组件的技术,尤其常见于企业级的portlet容器或门户应用中,如Liferay Portal、IBM WebSphere Portal等。Portlet允许开发者创建可嵌入到门户...