Liferay 6.0.5开发中文指南
目录
Liferay 6.0.5开发指南... 1
1. 关于Liferay.3
2. Portal和portlet介绍...4
2.1 portal 规范...4
2.2 JSR168. 4
2.3 WSRP. 4
2.4 Portal和Portal服务器...5
2.5 Portlet和Portlet容器...7
2.6 Portlet 与Servlet的关系... 9
2.7 Portlet 的生命周期...10
2.8 Portlet 模式...11
2.8.1 必须支持的模式(语义同上)...12
2.8.2 可选择的客户模式...12
2.8.3 特定于 Portal 厂商的模式... 12
2.9 窗口状态...12
2.9.1 Normal13
2.9.2 Maximized. 13
2.9.3 Minimized. 13
2.10 数据模式...13
2.11 Portlet标签...14
2.11.1 defineObjects 标签...14
2.11.2 renderURL 标签...14
2.11.3 actionURL 标签...15
2.11.4 param 标签...16
2.11.5 namespace标签...16
2.12 Portal 的对象...16
2.12.1 Request 对象...16
2.12.2 Response 对象...18
2.12.3 PortletConfig 对象...19
2.12.4 Session 对象...19
2.12.5 Preference 对象...20
3. 开发配置...22
3.1 下载Liferay 6.0.5.22
3.2 开发工具...22
3.3 环境配置...22
3.3.1 JDK配置...22
3.3.2 ANT配置...23
3.3.3 eclipse配置...23
4. 访问Liferay门户...29
4.1 启动liferay门户的服务...29
4.2 访问liferay门户...30
4.2.1 登录liferay Portal30
4.2.2 设置语言...30
4.2.3 添加Portlet31
4.2.4 页面配置...32
4.2.5 设计布局...33
4.2.6 其他设置...33
5. Liferay开发模式...33
5.1 插件模式开发...33
5.2 扩展环境开发...34
5.3 两种模式比较...36
5.3.1 插件模式优点...36
5.3.2 插件模式缺点...36
5.3.3 扩展模式优缺点...36
6. Liferay portlet的开发...36
6.1 创建一个插件开发工程...36
6.2 编写自己的Portlet37
6.3 分析Portlet38
6.4 创建自己的portlet41
1. 关于Liferay
Liferay(又称Liferay Portal)是一个开源的Portal产品,提供对多个独立系统的内容集成,为企业信息、流程等的整合提供了一套完整的解决方案,和其他商业产品相比,Liferay有着很多优良的特性(但是缺点也很明显,文档太少,学习成本有点高),而且免费。该项目包含了一个完整的J2EE应用。该项目使用了Web、EJB以及JMS等技术,特别是其前台界面部分使用Struts框架技术,基于XML的portlet配置文件可以自由地动态扩展,使用了Web Services来支持一些远程信息的获取,使用 Apahce Lucene实现全文检索功能。
主要特点如下:
1、提供单一登陆接口,多认证模式(LDAP或SQL);
2、管理员能通过用户界面轻松管理用户,组,角色;
3、用户能可以根据需要定制个性化的portal layout;
4、能够在主流的J2EE应用服务器上运行,如JBoss+Jetty/Tomcat,JOnAS;
5、支持主流的数据库,如PostgreSQL,MySQL;
6、使用了第三方的开源项目,如Hibernate, Lucene, Struts;
7、支持包括中文在内的多种语言;
8、采用最先进的技术 Java, EJB, JMS, SOAP, XML;
Liferay详细介绍参看http://www.liferay.com/zh/products/liferay-portal其官方网站。目前国内有多个项目是基于liferay的二次开发,目前最新的版本为Liferay 6.0.5。
2. Portal和portlet介绍在进行liferay开发以前有必要介绍一下portal和portlet的相关概念。
2.1 portal 规范随着Portal的兴起,有众多的厂商开始涉足Portal产品开发,并构建自己的Portal组件和基于他的产品,比如IBM、ORACLE、Microsoft、apache、SAP等,但是各个产品之间互不兼容,给开发者和各个厂商带来了诸多不便。
2.2 JSR168在这种情况下,JSR168规范应运而生,2003年10月7日,JCP组织发布了JSR168(Java Specification Request),Portlet Specification V1.0,用来提供不同的Portal和Portlet之间的互通性。只要开发的Portlet遵循JSR168,就可以在所有遵循JSR168的Portal上部署运行。JSR168中定义了Portal的实现规范和接口,并对理想的Portlet进行了详细规划和描述。
2.3 WSRPwsrp是OASIS Web Service For Remote Rortlet的缩写。WSRP是Web Service的一种新的商业应用,一种新的标准,主要用来简化portal对于各种资源或程序整合的复杂度,可以避免编程带来的整合麻烦和问题。而且Portal管理员可以从海量的WSRP服务中选择需要的功能用以整合到目前所有的Portal中。它有三种角色:
①、 生产者 ==》 提供Portlet
②、 消费者 ==》 使用Portlet
③、 终端用户 ==》 最终用户
它的特点在于生产者将消费者所需要的信息通过WSRP返回给消费者,这些信息是相对标记片断,例如HTML、XHTML等,可以直接嵌入用户的页面中,而不用像Web Service一样开发用户端接口。
实现这个规范,Portal 可以跟各式各样的数据源打交道,彻底终结信息孤岛的窘境。
2.4 Portal和Portal服务器
Portal是一个 Web应用程序,它通常提供不同来源的个性化、单点登录的内容集合,并且托管不同后端系统的表示层。Portal的主要任务是将不同的应用程序集合到一个页面,这个页面的外观是Portal 用户共有的。Portal也可以有复杂的个性化特征,这些特征能够给用户提供自定义内容。Portal页可以有不同的 Portlet 集,以便为不同的用户创建内容。
下图展示了 Portal 的体系结构,比如一个由 WebSphere Portal 提供服务的Portal。客户端请求由 PortalWeb 应用程序进行处理,它为当前用户检索当前页上的 Portlet。然后,Portal Web应用程序为每个 Portlet 调用 Portlet 容器来通过 Container Invoker API 检索它的内容。Portlet 容器通过 Portlet API 调用Portlet。Container Provider Service Provider Interface(SPI)允许 portlet 容器通过Portal 检索信息。
Portlet 容器运行 Portlet,给它们提供所需的运行时环境,并且管理它们的生命周期。它为Portlet 首选项项提供持久性存储,这使得能够为不同的用户生成自定义输出。
Portal 服务器是容纳Portlet 容器,支持Portlet 呈现的普通或者特殊Web 服务器。Portal 服务器通常会提供个性化设置、单点登录、内容聚合、信息发布、权限管理等功能,支持各种信息数据来源,并将这些数据信息放在网页中组合而成,提供个性化的内容定制,不同权限的浏览者能够浏览不同的信息内容。通常,Portal 提供以下功能:
单点登录:Portal 通常采用ACL、SSL、LDAP 等业界标准的安全技术,提供对所有现有应用系统的安全集成,只需在Portal 的唯一入口上登录一次,就可以访问所有应用系统和数据。对于安全性要求较高的应用系统,如电子商务平台、交易系统等,通过扩展接口传递用户身份信息,如数字证书信息、数字签名信息等,进行二次身份认证,保证单点登陆的安全性。
权限控制:系统采用LDAP 对用户资源进行统一的管理,同时提供二次开发接口,可以与其他应用系统的用户管理模块对接,并能随相关业务系统实时更新访问权限。通过完善的授权机制及存取控制,用户访问权限控制到字段级别,确保用户只能访问具有权限的应用系统及相关信息。
内容管理: 实现应用系统之间实时交换信息。采用多种缓存机制,保证内容交换的性能和准确性。采用基于XML 的Rich Site Summary (RSS)标准,迅速在各应用系统之间传播最新变化。
信息发布: 实现信息门户内容的动态维护。动态网站系统可与OA 协同办公系统、知识管理系统等集成,网站信息须经OA 系统的审批流程流转通过后或知识管理平台设置具有外部共享权限后才可正式发布,真正实现内外信息发布的同步。
文件管理: 系统实现无缝集成多种数据源,包括:数据库、文档(Office 文档、PDF、AutoCAD、甚至ZIP 文档)、Web 网页、FTP 站点等,并对数据按业务要求和职务特点加以分析整理,通过统一Web 界面主动推送(Push)至用户的门户桌面,帮助用户做出及时、正确的决策。
2.5 Portlet和Portlet容器
Portlet 是Portal 中最重要的组件,负责在Portal 中呈现信息内容,有相应的生命周期。通过自定义Portlet,用户很容易定义个性化的Portal 页面。Portlet 由Portlet 容器负责管理、处理请求并返回动态页面,可以作为Portal 的可即插即用的界面组件。
Portlet 容器提供Portlet执行的环境,包含很多Portlet 并管理它们的生命周期,保存Portlet的定制信息。一个Portal 容器接收到来自Portal的请求后,接着将这个请求传递给存在Portal 容器的Portlet执行。Portlet 容器没有义务去组合Portlet产生的信息內容,这个工作必须由Portal 来处理。Portal和 Portal 容器可以放在一起视为同一个系统的组件,或者分开成为两个独立的组件。
一个Portlet是以Java技术为技术的Web组件,由Portlet容器所管理,专门处理客户的信息请求以及产生各种动态的信息内容。Portlet 为可插式的客户界面组件,提供呈现层成为一个信息系统。这些由Portlet产生的内容也被称为片段,而片段是具有一些规则的标记( HTML、XHTML、WML ),而且可以和其他的片段组合而成一个复杂的文件。一个或多个 Portlet 的内容聚合而成为一个 Portal 网页。而 Portlet 的生命周期是被 Portlet 容器所管理控制的。客户端和Portlet的互动是由Portal通过典型的请求/响应方式实现,正常来说,客户会和Portlet所产生的内容互动,举例来说,根据下一步的连接或者是确认送出的表单,结果Portal将会接收到Portlet的动作,将这个处理状况转向到目标Portlet。这些Portlet 内容的产生可能会因为不同的使用者而有不同的变化,完全是根据客户对于这个Portlet的设置。
下图展示了基本的 Portal 页组件。Portal 页表示一个完整的标记文档并且聚集若干 Portlet 窗口;也就是说,它将不同的应用程序用户界面组合到一个统一的表示中去。Portal 页使用户能够通过登录对话框向 Portal 验证自己的身份以便访问个性化的 Portal 视图。大部分 Portal 页包括一些导航机制以允许用户导航到其他的 Portal 页。
Portal 页
Portlet 窗口包括:
标题栏,带有 Portlet 的标题
修饰,包括用于更改 Portlet 的窗口状态的按钮(比如最大化或最小化 Portlet)和用于更改 Portlet 的模式的按钮(比如显示帮助或编辑预定义的 Portlet 设置)
由 Portlet 产生的内容(也称为一个标记段)。
图 3在不同的浏览器上展示了一个 Portlet 窗口。如您所见,该 portlet 产生的标记段并不局限于 HTML,而可以是任何标记。
图 3:在 HTML 浏览器(顶部)和 WML 浏览器(底部)中显示的 Portlet
2.6 Portlet 与Servlet 的关系
Portlet 被定义成为一个新的组件,具有新的明确的界面与行为。为了尽可能与现有的Servlet结合达到重复使用的目的,Portlet 的规范利用了 Servlet的规范,许多观念都很相似的,结合 Portlet、Servlet及 Jsp 在同一个网站系统中,我们称为Portlet应用。在同一个 Portlet 应用中,他们将分享同一个类加载器(ClassLoader),上下文(Context)及 Session。
①、 Portlet 和 Servlet 的相似之处
? Portlet 也是 Java 技术的 web组件
? Portlet 也是有特定的 container 在管理
? Portlet 可以动态产生各种内容
? Portlet 的生命周期由 container 所管理
? Portlet 和客户端的互动是通过 request/response 的机制
②、 Portlet 和 Servlet 也有一些不同
? Portlet 只产生 markup 信息片段,不是完整的网页文件。而 Portal会将所有的Portlet markup 信息片段放到一个完整的 Portal网页。
? Portlet 不会和 URL 有直接的关系客户端必须通过 portal系统才能和Portlet 互动
? Portlet 有一些定义好的 request 处理,action request以及 render request。
? Portlet 默认定义 Portlet modes 及窗口状态可以指出在网页中该 Portlet的哪个功能正在执行及现在的状态。
? Portlet 可以在同一个 portal 网页之中存在多个。
③、 Portlet 有一些附加的功能是 Servlet 所没有的
? Portlet 能够存取及储存永久配置文件及定制资料。
? Portlet 可以存取使用者数据
? Portlet 具有 URL 的重写功能在文件中去动态建立连结,允许 portal server不用去知道如何在网页的片段之中建立连结及动作。
? Portlet 可以储存临时性的数据在 Portlet session 之中,拥有两个不同的范围:application-wide scope及 Portlet private scope 。
④、 Portlet不具有一些功能,但是 Servlet 却有提供
? Servlet 具有设置输出的文字编码( character set encoding)方式
? Servlet 可以设置 HTTP 输出的 header
? Servlet 才能够接收客户对于 portal 发出的 URL请求
2.7 Portlet 的生命周期一个Portlet有着良好的生命周期管理,定义了怎样装载,实例化和初始化,怎样响应来自客户端的请求及怎样送出服务。这个Portlet生命周期由Portlet接口的init,processAction,render和destroy方法来表达。
载入和实例化:Portlet 容器负责载入和实例化Portlet。当Portlet 容器运行Portlet 应用或者延迟到Portlet 需要服务使用者的请求时,Portlet 就会被载入并实例化。载入Portlet 类后,Portlet 类随即被实例化。
初始化:Portlet 类实例化后,Portlet 容器还需要初始化Portlet。以调用Portlet 去响应客户端的请求。Portlet 容器呼叫Portlet 接口中的init 方法初始化Portlet。扩展自PortletConfig的类可以取出定义在部署描述文件中的初始化参数,以及Resource Bundle。
初始化异常:在 Portlet 初始化期间,Portlet 可能会丟出 UnavailableException 或PortletException 异常。此时,Portlet 容器不能把 Portlet 置入已启动的服务,并且 Portlet容器必需释放这个 Portlet。 destory 方法不能被呼叫,因为初始化被认为执行失败。发生 失败后,Portlet 容器会尝试着重新实例化及初始化 Portlet。这个异常处理的规则是:由一个UnavailableException 指定一个不能执行的最小时间,当此异常发生时,Portlet 容器必需等到指定时间过去后才产生并且初始化一个新的 Portlet。
在初始化过程中所丟出的 Runtime Exception 异常,被当作 PortletException 来处理。
下图描述从客户端到 Portlet的请求流,并且更详细地展示了动作和呈现阶段。在这个示例中,Portlet A接收了一个动作。在该动作执行之后,页面(A、B、C)上的所有Portlet 的呈现方法都被调用。
2.8 Portlet 模式Portlet执行不同的任务并根据它们的当前函数来创建内容。Portlet模式指示 Portlet 何时将执行函数。Portlet模式指定 Portlet应该执行哪一类任务和应该生成什么样的内容。当调用 Portlet时,Portlet 容器提供当前对 Portlet 的请求的模式。在处理动作请求时,Portlet可以程序化地改变它们的 Portlet 模式。
JSR 168 定义了三类 Portlet 模式:
2.8.1 必须支持的模式(语义同上)Edit
显示一个或多个视图以让用户自定义个性化的 Portletsettings.Help
Help
显示帮助视图。
View
显示 Portlet 输出。
2.8.2 可选择的客户模式
About
显示 Portlet 的目的、来源、版本和其他信息。
Config
显示一个或多个配置视图以让管理员配置对所有用户有效的Portlet 设置。
Edit_defaults
设置可修改的首选项的缺省值,这些首选项通常可以在EDIT 屏幕中进行更改。
Preview
呈现输出而不需要后端连接或特定于用户的可用数据。
显示适于打印的视图。
2.8.3 特定于 Portal 厂商的模式
这些模式只适用于特定的厂商Portal。
2.9 窗口状态窗口状态是分配给 Portlet 生成的 Portal 页面空间的指示器。Portlet容器提供当前的窗口状态给 Portlet,而 Portlet 通过窗口状态来决定它应该呈现多少信息。然而,在处理动作请求时,Portlet也可以程序化地改变它们的窗口状态。
JSR 168 定义了如下窗口状态:
2.9.1 NormalPortlet 与其他 Portlet共享空间,在产生它的输出时应该对考虑这种状态。
2.9.2 Maximized与处于正常的窗口状态相比,窗口有更真实的状态来提供它的输出。
2.9.3 MinimizedPortlet 应该只呈现最小的输出或没有输出。
除了这些窗口状态之外,JSR 168 允许 Portal 定义自定义窗口状态。
2.10 数据模式JSR 168为 Portlet定义了不同的机制以访问瞬态数据和持久性数据。
Portlet 可以设置和获取下列作用域内的瞬态数据:
请求
请求有附加的数据,比如请求参数和属性,与Servlet类似。请求可以包含一些特性,以允许进行扩展;也可以包含从Portal 传送到 Portlet 的客户端头字段(反之亦然)。
会话
Portlet可以将数据存储在具有全局作用域的会话中,以让 Web应用程序中的其他组件
访问这些数据;也可以将数据存储在Portlet作用域中,这个作用域是 Portlet 私有的。
上下文
Portlet可以将数据存储在 Web 应用程序上下文中,与 Servlet类似。
Portlet 可以访问这些作用域内的持久性数据:
每个 Portlet
Portlet可以将配置和个人数据存储在 Portlet引用中,以允许 Portlet 创建个性化的输出。Portlet可以定义允许用户在编辑模式下更改那些数据(例如股票报价)以及哪些数据是只能由管理员在配置模式下进行更改的配置设置(例如股票报价服务器)。
每个用户
Portlet可以读取用户概要信息来针对用户调整它的输出(例如显示用户所在城市的天气情况)。
2.11 Portlet标签
跟Servlet 一样,Portlet 也自定义了很多灵活的标签。通过这些标签,可以调用Portlet内部的参数比如renderResponse、renderRequest、PortletConfig 等,在JSP 中跟Portlet 通信。当然,在使用之前,除了要在web.xml 中声明标签库外,还要在JSP 的头部声明标签库调用:
Xml代码
2.11.1 defineObjects 标签
在使用Portlet 典型标签之前,要见声明<portlet:defineObjects/>,这样才可以使用其他的标签。defineObjects 中间不允许定义任何属性和包含任何内容。
2.11.2 renderURL 标签属性
值类型
对应值
windowState
String
minimized
normal
maximized
portletMode
String
view
edit
help
var
String
secure
String
true
false
Xml代码
<portlet:renderURL portletMode="view" windowState="maximized">
<portlet:param name="number" value="1"/>
<portlet:param name="page" value="2"/>
</portlet:renderURL>
创建一个当前RenderURL,当访问它时将使Portlet 窗口变为最大化状态,模式变为浏览。<portlet:param/>子元素会在生成的RenderURL 中增加number、page 两个参数和值。
2.11.3 actionURL 标签属性
值类型
对应值
windowState
String
minimized
normal
maximized
portletMode
String
view
edit
help
var
String
secure
String
true
false
Xml代码
<portlet:actionURL windowState="normal" PortletMode="edit">
<portlet:param name="action" value="login"/>
</portlet:actionURL>
创建一个当前ActionURL,当访问它时将使Portlet 窗口变为正常状态,模式变为编辑。<Portlet:param/>子元素会在生成的ActionURL 中增加action 参数和值。renderURL 和actionURL 两个标签在诸如生成form 表单的action 等方面特别有用。
2.11.4 param 标签
属性
值类型
name
String
用在renderURL 和actionURL 标签内部,用来在生成的URL 中增加参数和值。param标签不运行body 内容存在。2.11.5 namespace标签
为目前的Portlet 产生一个唯一的Value,防止与其他Portlet 或者Portal 上面的Value 冲突。上述标签的具体属性及其约束, 请参阅${CATALINA_HOME}/liferay/WEB-INF/tld/liferay-portlet.tld
2.12 Portal 的对象
JSR168 给Portal定义了几个特别的对象,用来操作Portal 特有的信息。这些对象跟Servlet的对象有点类似,又有点不同。这些对象都封装在${CATALINA_HOME}/common/lib/ext/portlet.jar包中,具体支持实现要视Portal 服务器而定。
2.12.1 Request 对象Portlet 中的Request与Servlet 的Request一样接受客户端发送的请求,但是与Servlet不同,Portlet的Request 分为Action Request及Render Request 两种类型,因此Portlet接口中定义了两种方法用来处理不同的Request。分别是processAction(ActionRequest request,ActionResponse response)和render(RenderRequest request,RenderResponse response),分别用以处理Action Request和Render Request。某种意义上来讲,render方法类似Servlet 中的service方法,doView,doEdit,doHelp方法又类似doGet,doPost方法。
①、 RenderRequest 和ActionRequest
PortletRequest 分为RenderRequest 和ActionRequest 两种,分别由renderURL 和actionURL来触发。renderURL 是actionURL 的一种优化。Portlet 的开发过程中尽量使用renderURL 而避免actionURL。actionURL 适用于有确实的Action(行为)的情况下。比如说,表单form提交后Persistent 状态的改变、session 的改变、perference 的修改等等。renderURL 通常用来处理Portlet 的导航。举个例子:
使用actionURL:
Java代码
<%
PortletURL pu = renderResponse.createActionURL();
pu.setParameter("ACTION","LOGIN");
<form name="usrform" method="post" action="<%=pu.toString()%>">
%>
说明:表单提交最好使用Post 方法而不是Get 方法,因为某些Portal 服务器可能会将内部状态编码到URL的Query 字符串中。使用renderURL:
Java代码
<%
PortletURL pu=renderResponse.createRenderURL();
Pu.setParameter("PAGE",Number);
%>
<a href="<%=pu%>">下一页</a>
②、 renderURL 和actionURL 的处理方式
当客户端请求是由一个renderURL 触发的时候,Portal 服务器会调用该Portal 页面所有Portlet 的render 方法。
而当客户端请求是由一个actionURL 触发的时候,Portal 服务器会先按用该页面所有Portlet 的processAction方法再调用render 方法。所以,要明确自己到底使用那种URL 来出发客户端请求。
③、 RenderRequest 和ActionRequest 的parameter 参数作用范围
当客户端请求由一个actionRequest 触发时,所有parameter 参数的取得都必须在processAction方法中进行。比如:
Java代码
public void processAction(ActionRequest req,ActionResponse res){
String str = req.getParameter("ACTION");
//response.setRenderParameter("ACTION",action);
}
public void doView(ActionRequest req,ActionResponse res){
String str = req.getParameter("ACTION");
}
如上processAction 方法中,getParameter 方法将能成功得到表单中的参数ACTION 所对应的值,因为我们知道,当目标Portlet 的processAction 方法运行完后,Portlet Container 将调用Portal 页面中所有Portlet 的render方法.但是实际上doView 方法中使用getParameter不会得到任何值.但是如果把processAction 方法中注释了的一行解除注释的话,你就可以在doView 方法中的得到参数ACTION 对应的值. 这说明action request 的参数,render方法中不可以直接取到.必须使用了setRenderParameter 方法,再次传递一次.
2.12.2 Response 对象与Request 对象一样,Response 对象也有两种:RenderResponse 和ActionResponse,分别用来封装对应的RenderRequest 和ActionRequest 的返回信息,比如重定向、窗口状态、Portlet 模式等。他们两者的父类PortletResponse 拥有serPorperty 和getPorperty 两个方法,用来递信息给Portal 容器。
ActionResponse 主要用来处理以下功能:
a) 重定向
b) 改变窗口状态、Portlet 模式
c) 传递parameter 参数到RenderRequest 中去RenderResponse 主要用来提供以下功能:
d) 设置ContentType
e) 得到OutputStream 和Writer 对象,用来输出页面内容
f) Buffering 缓冲
g) 设定Portlet 的标题,但是必须在Portlet 输出前调用,否则将被忽略
2.12.3 PortletConfig 对象和ServletConfig 对象类似, PortletConfig 对象提供对Portlet 初始化信息以及PortletContext 对象存取的方法。
和ServletConfig 对象不同的是,PortletConfig 对象提供对Portlet 的标题等资源的I18N支持,可以通过设定不同的Resource Bundle 文件以提供多种语言支持。
2.12.4 Session 对象由于容器不同,Portal 的Session 对象与Servlet 的Session 对象略有不同。由于Portlet 处于Portal 服务器的缘故,Portlet 的Session 分为Application Scope 和PortletScope。
两者的区别在于:
①、 Application Scope 范围的Session 中保存的对象,对于同一个Portlet 应用范围内的所有Portlet 都是可用的。
②、 Portlet Scope 范围的Session 中保存的对象,只对本Portlet 可用,其他Portlet 即使在同一个应用中,也不可用。
但是对于Portlet 应用来说,可以通过HttpSession 来访问。毕竟Portlet 应用也是Web应用。在使用Session 对象的时候,最好能明确指出使用的是那个Scope 范围的Session。比如:
Xml代码
<portlet:actionURL windowState="NORMAL" portletMode="view" var="pu1">
<portlet:param name="ACTION" value="ApplicationScope"/>
</portlet:actionURL>
<portlet:actionURL windowState="NORMAL" portletMode="view" var="pu2">
<portlet:param name="ACTION" value="PortletScope"/>
</portlet:actionURL>
这个JSP 创建了两个ActionURL,分别产生了两种PortletSession 对象。
Java代码
PortletSession ps = req.getPortletSession();
if(ps.getAttribute("PortletSession.AS",PortletSession.APPLICATION_SCOPE)!=null){
app=ps.getAttribute("PortletSession.AS",PortletSession.APPLICATION_SCOPE).
toString();
}
if(ps.getAttribute("PortletSession.PS",PortletSession.PORTLET_SCOPE)!=null){
portlet=ps.getAttribute("PortletSession.PS",PortletSession.PORTLET_SCOPE).
toString();
}
以上代码根据需要取得不同Scope 范围的Session 对象值。同一个应用下,可以直接通过ServletSession 取得
Java代码
PortletSession.APPLICATION_SCOPE范围下的Session 对象值。
HttpSession se = request.getSession();
if(se.getAttribute("PortletSession.AS")!=null){
app=se.getAttribute("PortletSession.AS"); }PortletSession.APPLICATION_SCOPE范围下的Session对象值。
HttpSession se = request.getSession();
if(se.getAttribute("PortletSession.AS")!=null){
app=se.getAttribute("PortletSession.AS");
}2.12.5 Preference 对象
Preference 对象被设计用来实现用户的个性化设置,可以帮助用户对Portlet进行符合用户需求的显示定制和行为定制,可以替代部分的数据库功能。需要指出的是,Preference对象只是用来存取简单的配置信息,并不能完全替代数据库应用。
Preference 对象对于配置信息采用键-值的形式存取,用户可以将需要的信息暂时保存在Preference中。
Java代码
PortletPreference p= req.getPortletPreferences();
p.setValue("educhina.username","educhina");
p.store();
Preference 对象用来存取用户的个性化信息,所以不同用户的Preference
对象不能共享,这点跟Session不同。可以在Portlet.xml 中配置Preference信息,如下:
Xml代码
<portlet-preferences>
<preference>
<name>educhina.username</name>
<value>educhina</value>
<read-only>true</read-only>
</preference>
</portlet-preferences>
另外,还可以配套使用PreferencesValidator对象,对Portlet 的Preference在存储之前进行验证,以确保Preference 的正确性。具体规范可以参照http://java.sun.com/xml/ns/Portlet/Portlet-app_1_0.xsd的<complexTypename="preferenceType">部分。
3. 开发配置3.1 下载Liferay 6.0.5
下载地址:http://sourceforge.net/projects/lportal/files
Liferay的sdk包 :liferay-plugins-sdk-6.0.5.zip
数据脚本包:liferay-portal-sql-6.0.5.zip
Liferay源代码包:liferay-portal-src-6.0.5.zip
集成包:liferay-portal-tomcat-6.0.5.zip
Eclipse插件:liferay-ide-eclipse-updatesite-1.1.0.zip
3.2 依赖工具JDK 1.6 以上:
JDK的下载可以去Oracle官方下载。
ANT1.7以上
Liferay IDE是一个Eclipse插件,安装方法和普通的插件一样,仅支持Eclipse 3.5和3.6其他版本不能保证能正常运行。
Eclipse下载地址:
Eclipse Galileo SR2 (3.5.2) http://releases.liferay.com/tools/ide/eclipse/galileo/stable/
Eclipse Helios (3.6.0) http://releases.liferay.com/tools/ide/eclipse/helios/stable
数据库:
Postgresql9.0
3.3 环境配置3.3.1 JDK配置
WINDOWS系统下:
(1)JAVA_HOME:JDK的安装目录
(2)PATH:把%JAVA_HOME%\bin目录加到path变量
(检查JDK是否安装正确,通过“JAVA –version”命令来判断。同样下边的ant也是同样的方式进行检查“ANT -version”)
Linux系统下:(运行下面命令)
查看当前JDK的版本:yum search jdk
如果在1.6以下,就卸载原来的,安装1.6以上的版本。
3.3.2 ANT配置Windows系统:
(1)ANT_HOME:ANT的安装目录
(2)PATH:把%ANT_HOME%\bin目录加到path变量
3.3.3 数据库配置Liferay默认数据库是Hypersonic,实际开发中我们不会用该数据库,这里我们就以postgreSql数据库为例来讲述一下liferay使用不同数据库的配置。
1) 在postgreSql数据库中创建liferay对应的数据库数据
下载liferay-portal-sql-6.0.5.zip包,解压缩后,把create文件夹下的create-postgresql.sql文件放到postgreSql数据库中执行数据脚本生成对应的表。
2) liferay对应的安装目录
a) 找到
liferay-portal-6.0.5/tomcat-6.0.26/webapps/ROOT/WEB-INF/lib/portal-imp.jar 的文件,解压缩后,找到portal.properies并打开编辑,找到以下代码如下图:
把上面四行代码用#注释掉,并把以下代码的注释去掉,如下图
设置对应的用户和密码
b) 找到liferay-portal-6.0.5/tomcat-6.0.26/conf/Catalina/localhost/ROOT.xml
打开添加以下代码:
<Resource name="jdbc/LiferayPool"
auth="Container"
type="javax.sql.DataSource"
username="postgres"
password="1102c1102c"
driverClassName="org.postgresql.Driver"
url="jdbc:postgresql://192.168.0.71:5432/lportal"
maxActive="20"
maxIdle="10"/>
3.3.4 eclipse配置linux下
(1)解压缩eclipse-jee-galileo-SR2-linux-gtk-x86_64.tar.gz包到一个文件夹下就会出现一个ecplise文件夹
在终端下运行以下命令:
[root@vm2 ~]# ls
apache-tomcat-6.0.29.tar.gzeclipse liferay-portal-6.0.5 pg9_rpm_install.sh
archives eclipse-jee-galileo-SR2-linux-gtk-x86_64.tar.gz liferay-portal-sql-6.0.5.zip pg9.tgz
ASE-ThirdPartyLegal.pdf flash-portlet-6.0.5.1.war liferay-portal-src-6.0.5.zip pgrpms
dbisql.rep liferay-ide-eclipse-updatesite-1.1.0.zip liferay-portal-tomcat-6.0.5.zip setup.bin
Desktop liferay-plugins-sdk-6.0.5.zip liferay-sdk
[root@vm2 ~]# cd eclipse
[root@vm2 eclipse]# ls
about_files artifacts.xml dropins eclipse.ini features libcairo-swt.so p2 readme
about.html configuration eclipse epl-v10.html icon.xpm notice.html plugins
[root@vm2 eclipse]# ./eclipse &
Windows下:
解压缩文件eclipse-jee-helios-SR1-win32-x86_64.zip到E盘根目录下,E盘根目录就会出现一个ecplise文件夹,进入该文件夹,运行eclipse.exe
得到以下界面:
(2)同样在终端用命令解压liferay-portal-tomcat-6.0.5.zip和liferay-plugins-sdk-6.0.5.zip。
(3)liferay IDE的配置,如下图
在help菜单中选择 Install New software选项,则出现以下页面:
点击Archive按钮,浏览liferay的eclipse插件的文件liferay-ide-eclipse-updatesite-1.1.0.zip,如下图:
点击ok按钮,进行liferay IDE的安装,如下图:
点击Next按钮后,再点击Finish按钮进行安装,如图
点击ok,再点击yes按钮完成IDE的安装。Eclipse重启后,完成IDE的安装。
(4)liferay SDK和liferay服务的配置
如下图:
按上面操作,得到以下图片
配置sdk ,如图:
配置liferay portal Runtime,如图
点击finish完成配置。
4. 访问Liferay门户4.1 启动liferay门户的服务
在eclipse中启动liferay服务,选择server视图右键菜单的Start,也可以在终端tomcat/bin目录下运行startup.sh,启动服务。如图:
服务启动完毕后,在浏览器中输入http://192.168.0.72:8080,Ip地址是你部署机器具体的Ip地址。
4.2 访问liferay门户4.2.1 登录liferay Portal
在打开的浏览器中,点击右上角的login,输入帐号和密码。在这里的输入的帐号密码为
email:bruno@7cogs.com
password:bruno
liferay从5.2之后的版本中都带有一个7cogs.inc公司的示例数据库,所以这里的管理员帐号密码如上。如果删除示例数据库,则账号密码如下:
email:test@liferay.com
password:test
4.2.2 设置语言登录之后会发现,这里的Liferay是英文的,虽然这些英文也比较简单,但还是中文看着舒服。点击左上角的Manager-control Panel进入到Liferay的控制面板。我们首先设置当前用户的语言,点击左边最上面的My Account,然后在右边的Miscellaneous下面找到 Display Settings,点击他。然后在中间的Language中选择“中文(中国)”,在下面的Time Zone里面选择到“(UTC+08:00 ) China Standard Time“,点击右边的save,现在的界面就变成中文的了,看着亲切多了。
现在的只是修改了当前用户的显示设置,在左边的门户下面找到设置,和上面的个人类似位置,显示设置里面修改语言、时区以及相应的Logo、主题包等。
4.2.3 添加Portlet
Liferay的强大之一就是自由的配置添加Portlet,在这里我们刚才是在控制面板里面,现在点击左上角的”返回7Cogs,INC“或者是右上角的"去-->7Cogs,Inc 私有的"(这里说明一下,私有的就是指这个组织的用户登录后可以看到的,公开的就是所有人都可以看到的)。
在这里点击右上角的”添加“),”更多“,这里可以看到如下图所示,这里面的这些内容管理、Google什么的都是Liferay里面自带的一些Portlet,可以在这里将这些Portle添加到自己想要添加的位置,点击其中的添加或者直接拖到界面中即可。
我们将来自己开的Portlet也将在这里归类,并通过此方法添加进来。
如果要删除相应的Portlet,点击每个portlet上面的x,就可删除。点击设置可以设置权限等。
4.2.4 页面配置上面的是添加portlet,下面介绍一些其他的页面配置,点击左上方”管理“-->”页面“,这里可以看到如下图所示:
左边的home/documents等就是上面的导航,在这里可以为这些导航添加相应的图标,易记的URL,复制其他页面等,还可以为其添加下级页面,图中的下级页面,其实就是home/document等的二级菜单,其他的也很容易一看就明白,不再多说。
在外观风格处可以为其设置相应的风格和添加自定义CSS等。
4.2.5 设计布局
管理下面有一个”设计布局“,在这里可以对portle的布局做设置,这个也不必多说,相信大部分人都玩QQ空间,这个就是和QQ空间的布局是一样的。现在的用的只是系统一些自带的布局,如何设计制作自己的布局,在后续中将提到。
4.2.6 其他设置
Liferay的大部分设置都可以在控制面板中看到,大部分设置还是比较简单的,多点两下差不多就熟悉了。其他的一些设置就根据自己的需要和具体需求设置了。
Liferay的通过这样的配置可以实现很大程度上的自由和和可配置,对于需求不确定或者经常变更的还是很有用的,个人感觉比较适合产品化项目。开发一定量的Portlet,根据用户的需要来通过配置实现相应的功能点。
5. Liferay开发模式Liferay开发模式分为插件模式开发和扩展环境开发模式,下面来详细介绍:
5.1 插件模式开发通过liferay ide建立的那个工程就是插件模式开发。什么是插件模式开发呢?简单说就是提供一个独立的war包放到应用服务器里面,如果我们打开%tomcat_home%/webapps就会看到我们建立的工程LiferayStudy-portlet,同时还看到许多其他的文件夹,如下:
这些文件夹是liferay里面自带的一些插件包,如chat、google map等。
5.2 扩展环境开发
Liferay 6以后的ext模式开发有了变动,在Liferay 6之前的版本中扩展环境叫做Extension Environment,从liferay 6以后这种模式叫做ext plugin。(其实现在的开发模式可以称为一种了,都可以统称为插件开发,不过这两种模式有很大区别,还是分开来比较好)
ext plugin(扩展插件)是以前使用Extension Enviroment(扩展环境)的升级版本,用来替代以前的ext开发模式。现在的ext plugin开发可以称为一种轻量级的扩展环境,现在做扩展环境只需要使用不到10M大小liferay-plugins-sdk,而早期版本的开发要么需要自己下载Ext环境,要么需要自己从源代码里面编译一个扩展环境出来。
虽然现在的ext plugin使用的是不到10M大小的SDK,但是开发方法和运行原理和之前使用的Extension Enviroment是一样的。
看一下liferay ext plugin模式在Eclipse里面的工程目录
在这里个工程里面我们写的java类文件一般在docroot/WEB-INF/ext-impl/src目录下面,jsp文件一般在doroot/ext-web/docroot目录下面。
文件夹ext-impl、ext-lib、ext-service、ext-util-bridges 、ext-util-java、 ext-util-taglib这些在部署的时候会被打成jar包,ext-web/dcroot对应的就是tomcat下面的root目录。
基本上和普通的java web工程没有太大的区别。
5.3 两种模式比较5.3.1 插件模式优点
插件模式开的是独立的web工程,优点非常明显,只要遵循JSR,就可以任何Web方式开发,对liferay基本上没有依赖,耦合很低,可以非常方便部署、开发、迁移。便于应对以后的Liferay版本升级,基本上不存在啥成本,copy相应的war包过去即可。
5.3.2 插件模式缺点
在优点明显的同时,缺点也很明显。每个都是独立的war包,代码之间的共享访问很难,同时不能调用Liferay的API。
5.3.3 扩展模式优缺点
扩展模式和插件模式刚好相反,扩展模式的优点就是插件模式的缺点;扩展模式的缺点就是插件模式的优点。
6. Liferay portlet的开发6.1 创建一个插件开发工程
Liferay的开发模式基本上有两种,一种是插件式的开发,一种是扩展环境的开发,现在我们使用Liferay IDE创建一个插件式的开发环境
Eclipse ->new->other->Liferay->Liferay Plug-in Project。如下图,填写相应的Project Name,点击确定。
这个时候我们就创建了一个插件开发的工程,名字叫liferayStudy。
6.2 编写自己的Portlet运行工程
在分析Portlet之前,首先让我们上面创建的工程在Liferay里面跑起来,在server视图里面,new-server选择Liferay server,next,如下:将有效的工程添加到Liferay server里面,然后点击完成。
在创建自己的Portlet之前,我们首先来分析一下liferay里面的portlet都有哪些东西。在完成上一步操作之后,启动Liferay server,输入帐号密码,点击“添加”-“更多”(不清楚之处,请参数上一篇文章)-“示例”,呵呵,现在看到了什么?我们刚才创建的工程liferayStudy,如下图。
点击添加,就可以看到将这个portlet添加到了Liferay中。
我们只是添加了一个插件工程,这个portlet从哪里来的呢?其实这个是创建工程是创建的一个默认portlet,在创建自己的portlet之前,首先来分析一下这个portlet是怎么添加到Liferay里面,并让我们简单通过添加来添加的呢?
涉及的文件如下:
portlet.xml
liferay-portlet.xml
liferay-display.xml
首先看portlet.xml里面的内容
Xml代码
<portlet>
<portlet-name>liferayStudy</portlet-name>
<display-name>LiferayStudy</display-name>
<portlet-class>com.liferay.util.bridges.mvc.MVCPortlet</portlet-class>
<init-param>
<name>view-jsp</name>
<value>/view.jsp</value>
</init-param>
<expiration-cache>0</expiration-cache>
<supports>
<mime-type>text/html</mime-type>
</supports>
<portlet-info>
<title>LiferayStudy</title>
<short-title>LiferayStudy</short-title>
<keywords>LiferayStudy</keywords>
</portlet-info>
<security-role-ref>
<role-name>administrator</role-name>
</security-role-ref>
<security-role-ref>
<role-name>guest</role-name>
</security-role-ref>
<security-role-ref>
<role-name>power-user</role-name>
</security-role-ref>
<security-role-ref>
<role-name>user</role-name>
</security-role-ref>
</portlet>
这里面的内容很多看名字都可以理解, 关键点在portlet-name,和init-param下面的其他权限什么的一看就明白不再细说。
portlet-name是和其他相关文件关联的“ID”,init-parma显示的是关联的JSP文件。
这个portlet.xml的定义是portlet 2.0规范定义的。
下面看lifery-portlet.xml
Xml代码
<liferay-portlet-app>
<portlet>
<portlet-name>liferayStudy</portlet-name>
<icon>/icon.png</icon>
<instanceable>true</instanceable>
<header-portlet-css>/css/main.css</header-portlet-css>
<footer-portlet-javascript>/js/main.js</footer-portlet-javascript>
<css-class-wrapper>liferayStudy-portlet</css-class-wrapper>
</portlet>
<role-mapper>
<role-name>administrator</role-name>
<role-link>Administrator</role-link>
</role-mapper>
<role-mapper>
<role-name>guest</role-name>
<role-link>Guest</role-link>
</role-mapper>
<role-mapper>
<role-name>power-user</role-name>
<role-link>Power User</role-link>
</role-mapper>
<role-mapper>
<role-name>user</role-name>
<role-link>User</role-link>
</role-mapper>
</liferay-portlet-app>
这个里面的大部分信息也是看名字就能知道是什么意思,这个文件算是将前面定义的portlet在liferay里面注册,关联信息是使用的portlet-name
下面看liferay-display.xml
Xml代码
<category name="category.sample">
<portlet id="liferayStudy" />
</category>
这里面的信息很少,只有portlet id="liferayStudy"这一个,这个是归类,将前面定义的portlet归类到哪个下面,这里面sample,所以在上面我们是在示例这个分类在下面找到这个portlet的。
6.4 创建自己的portlet
以前没有Liferay IDE时,上面的那些配置信息都要手动撰写的,现在有了liferay IDE,都可以通过向导创建来完成。
在我们上一步创建的工程里上面点右键-New--Liferay Portlet,出现的界面如下:
在这里输入相应的Portlet class,和相应的包名,其他的不用变,这两个是可以自定义的,点击下一步
点击下一步,完成即可。
刷新浏览器,在“添加”-->“更多”-->"示例"里面即可以看到我们到才添加的portlet。
点击添加的Portlet上面的小螺丝刀,可以看到,多了首选项和帮助等。这时我们在上面的Portlet Modes里面选中Edit,Help的效果
这些里面要显示什么具体的信息和要展现什么具体内容,根据需要了,相应的JSP存在docroot/portletdemo下面。
PS:在SDK的目录里面有一个build.properties文件,这是属性的配置文件,用来指定Tomcat的位置的,不推荐在这上面直接编辑,而是复制一份将其重命名为build.${user.name}.properties,其中的${user.name}指的是当前系统用户名,如果不确定,打开cmd,后面跟的就是当前用户名,如我的为huqiwen,有些是administrator。如果是administrator,就命名为build.administrator.properties。
在这个文件里面只要填上要修改的项就可以了,会自动覆盖build.properties里面的对应项