- 浏览: 30897 次
- 性别:
- 来自: 广州
文章分类
最新评论
第六节 Liferay Portal的部署描述文件
跟所有的Web应用一样,Liferay Portal采用多个XML部署描述文件,来初始化部署信息,规范操作模式,比如Portlet的初始化信息、可用的Portlet列表、Portlet所属角色和用户组等等。通过这些部署描述文件,Liferay Portal可以在启动的时候自动加载Portlet,根据需要生成所需的Portlet页面。普通的Web应用,也可以很方便的转换成可部署的Portlet。这种实现也是JSR168所规定的。
2.6.1 web.xml
http://java.sun.com/dtd/web-app_2_3.dtd 定义。
与其他普通Web应用相比,Liferay Portal的Portlet 应用还需要在web.xml中增加如下内容:
a、监听器:
<listener>
<listener-class>com.Liferay.portal.servlet.PortletContextListener</listener-class>
</listener>
这个要求web 服务器监听所有跟Portlet有关的请求信息,并将监听到的内容交给Liferay Portal的Portlet容器处理。
b、Portlet Servlet映射:
<servlet>
<servlet-name>yourPortlet</servlet-name>
<servlet-class>com.liferay.portal.servlet.PortletServlet</servlet-class>
<init-param>
<param-name>Portlet-class</param-name>
<param-value>full.name.of.yourPortlet</param-value>
</init-param>
<load-on-startup>0</load-on-startup>
</servlet>
。。。。。。。。。。。。。。。。。。。。。。。。。
<servlet-mapping>
<servlet-name>yourPortlet</servlet-name>
<url-pattern>/yourPortlet/*</url-pattern>
</servlet-mapping>
其中,servlet-name为部署的servlet名称;init-param中定义自己的Portlet类,这个param-name要跟portlet.xml、liferay-portlet.xml、liferay-display.xml中的portlet-name节点值一致。
c、标签库映射:
<taglib>
<taglib-uri>http://java.sun.com/Portlet</taglib-uri>
<taglib-location>/WEB-INF/tld/liferay-Portlet.tld</taglib-location>
</taglib>
定义了这个标签库映射,在JSP文件中才可以使用诸如<portlet:defineObjects />在内的一些特定的Portlet标签。
如果在应用中有用到其他的元素,可以按照web.xml规范加入到相应的位置当中。
Liferay Portal默认的liferay应用,由于使用了Struts、Hibernate、Spring在内的多个开源框架,所以{PORTAL_HOME}/liferay/WEB-INF/web.xml文件会相对复杂些。
在自定义的Portlet,可以使用getPortletConfig().getInitParameter(“ ”)和getPortletConfig().getParameterNames(“”)两个方法来取得在web.xml中定义的参数。
2.6.2 portlet.xml
portlet.xml用来定义Portlet的诸如部署名称、初始化参数、支持模式、resource bundle等普通的初始化信息,包括:portlet-name、display-name、portlet-class、init-param、expiration-cathe、supports、portlet-info、security-role-ref等等。其正式的规范请参考:http://java.sun.com/xml/ns/Portlet/Portlet-app_1_0.xsd 。根目录为portlet-webapp。
portlet-name:Portlet的规范名称,在Portlet应用中必须唯一,主要用在Portlet部署和映射中。
display-name:供部署工具调用的Portlet简称,在Portlet应用中必须唯一。
portlet-class:Portlet对应的类,这个类必须直接或者间接的继承javax.Portlet.GenericPortlet。
init-param:初始化参数,有成对的<name>和<value>子元素。通常定义Portlet相应模式下可用的JSP页面。
expiration-cathe:定义Portlet加载允许最长的过期时间,以秒为单位。-1代表用不过期。
supports:定义Portlet支持的模式。所有的Portlet都必须支持浏览模式。
其他的元素含义请参照:http://java.sun.com/xml/ns/Portlet/Portlet-app_1_0.xsd
当Web 应用中有多个的Portlet时,可以统一的在Portlet。xml中定义一组的<portlet>元素。
<portlet>
<portlet-name>TestPortlet</Portlet-name>
<display-name>TestPortlet</display-name>
<portlet-class>com.educhina.portal.FirstPortlet</Portlet-class>
<init-param>
<name>view-jsp</name>
<value>/view.jsp</value>
</init-param>
<init-param>
<name>edit-jsp</name>
<value>/edit.jsp</value>
</init-param>
<expiration-cache>0</expiration-cache>
<supports>
<mime-type>text/html</mime-type>
</supports>
<supports>
<mime-type>text/html</mime-type>
<Portlet-mode>edit</Portlet-mode>
</supports>
<portlet-info>
<title>educhina Test Portlet</title>
<short-title> educhina Test Portlet </short-title>
<keywords> educhina Test Portlet </keywords>
</portlet-info>
<security-role-ref>
<role-name>guest</role-name>
</security-role-ref>
</portlet>
2.6.3 liferay-Portlet.xml
定义Portlet默认可用的用户组、默认模板、是否支持多个实例等,规范由http://www.liferay.com/dtd/liferay-Portlet-app_3_5_0.dtd 定义。
liferay-portlet.xml主要包含单独或者成组的<portlet>、<role-mapper>。其中,<portlet>下包含<portlet-name>、<struts-path>、<use-default-template>、<instanceable>等子元素,<portlet-name>在应用中必须唯一,且要跟portlet.xml相同;<role-mapper>下包含成对的<role-name>、<role-link>子元素。具体的元素含义请查看上述dtd定义。
<liferay-portlet-app>
<portlet>
<portlet-name> TestPortlet </portlet-name>
<struts-path> TestPortlet </struts-path>
<use-default-template>true</use-default-template>
<instanceable>true</instanceable>
</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>
2.6.4 liferay-display.xml
定义Portlet默认的所属类别。Liferay Portal对Portlet实行按类别管理和划分用户权限。正如我们在用户策略中提到的,可以制定某个类别可用的用户组、用户和角色,方便权限控制。Liferay-display.xml规范由http://www.liferay.com/dtd/liferay-display_3_5_0.dtd 定义。
Liferay-display.xml中,<display>下成组的<category>描述了可用的类别,其中portlet元素的id必须与liferay-portlet.xml的portlet-name保持一致,且在应用中唯一。
<display>
<category name="category.test">
<portlet id="TestPortlet" />
</category>
</display>
2.6.5 liferay-layout-templates.xml
定义Portal可用的布局。正如我们在布局与品质中提到的那样,Portal采用tpl文件来规划桌面的布局。liferay-layout-templates。xml采用成组的layout-template来构建一个可用的布局列表。此xml的规范由http://www.liferay.com/dtd/liferay-layout-templates_3_6_0.dtd 来定义。
本文采用Liferay Portal默认的布局,暂时不需要定义自己的布局,故不准备深入讨论。读者有兴趣可以自己查看相关资料。
<layout-templates>
<layout-template id="1_column" name="1 Column">
<template-path>/html/layouttpl/1_column。tpl</template-path>
</layout-template>
<layout-template id="2_columns_i" name="2 Columns (50/50)">
<template-path>/html/layouttpl/2_columns_i。tpl</template-path>
</layout-template>
<layout-template id="3_columns" name="3 Columns">
<template-path>/html/layouttpl/3_columns。tpl</template-path>
</layout-template>
<layout-template id="1_2_1_columns" name="1-2-1 Columns">
<template-path>/html/layouttpl/1_2_1_columns。tpl</template-path>
</layout-template>
</layout-templates>
2.6.7 liferay-look-and-feel。xml
定义Portal可用品质的模板、图片、样式表等等,定义完毕后,Portal可以通过“布局与品质”管理工具来进行品质的切换。Liferay-look-and-feel.xml规范由http://www.liferay.com/dtd/liferay-look-and-feel_3_5_0.dtd 定义。
本文采用Liferay Portal默认的品质,不准备对品质的自定义深入探讨。有兴趣的读者可以查看相关资料。
第二部分 Liferay Portal 二次开发
本部分主要内容
GenericPortlet 自定义Portlet类 部署描述文件
第三章 开发自己的Portlet
在了解了Liferay Portal的基础架构,初步体会Liferay Portal良好的个性化定制之后,本章将开始Liferay Portal二次开发之旅,讲述并扩展Portlet的超类GenericPortlet,创建或者修改部署描述文件,构建属于自己的Portlet。
第一节 重要的基类:GenericPortlet
像Servlet一样,编写的Portlet也必须直接或者间接的扩展基类GenericPortlet,这个是由JCP针对Portal提出的JSR168规范定义的。只要扩展自规范的GenericPortlet,所有的Portlet都可以在支持JSR168规范的Portal服务器上运行。
GenericPortlet统一定义了可供Portal容器识别和调用的方法,包括:
public Init():初始化;
public Init(PortletConfig) :初始化;
public getInitParameter(String):取得在Portlet。xml中定义的初始化参数;
public getInitParameterNames():取得在Portlet。xml中定义的全部初始化参数;
public getPortletConfig():取得包含初始化参数的配置对象PortletConfig实例;
public getPortletContext():取得Portlet上下文;
public getPortletName():取得在Portlet。xml中定义的Portlet名称。
public getResourceBundle(Locale) :取得Portlet国际化的Resource Bundle;
protected getTitle(RenderRequest) :取得Portlet的标题;
protected doView(RenderRequest,RenderResponse) :Portlet浏览模式的处理方法;
protected doEdit(RenderRequest,RenderResponse) :Portlet编辑模式的处理方法;
protected doHelp(RenderRequest,RenderResponse) :Portlet帮助模式的处理方法;
protected doDispatch(RenderRequest,RenderResponse) :Portlet行为分发;
protected processAction(RenderRequest,RenderResponse) :Portlet处理Action Request的方法;
protected render(RenderRequest,RenderResponse):Portal处理Render Request的方法;
public destroy():Portlet销毁,终止其生命周期。
在Portlet Portal运行的时候,doView、doEdit、doHelp三个方法分别被调用,用以生成Portlet标记。同样也可以调用Servlet生成Portlet标记,或者不调用JSP或者Servlet,直接在方法中得到PrintWriter然后用最简单的pw.println()打印出内容。这个过程类似Servlet,如下:
PrintWriter pw = renderResponse.getWriter();
pw.println(“Hello,world!”);
与Servlet类似,可以使用getInitParamter(String s)得到配置文件中Portlet的初始值,只不过Servlet在web.xml中,而Portlet在portlet.xml中。
portlet.xml:
<init-param>
<name>jspView</name>
<value>/jsp/view。jsp</value>
</init-param>
针对如上portlet.xml中的初始化信息,可以采用如下的调用方式:
SimplePortlet.java:
String jspName = getPortletConfig()。getInitParameter("jspView");
第二节 Portlet标签
跟Servlet一样,Portlet也自定义了很多灵活的标签。通过这些标签,可以调用Portlet内部的参数比如renderResponse、renderRequest、PortletConfig等,在JSP中跟Portlet通信。当然,在使用之前,除了要在web。xml中声明标签库外,还要在JSP的头部声明标签库调用:<%@ taglib uri="http://java。sun。com/Portlet" prefix="Portlet" %>
3.2.1 defineObjects标签
在使用Portlet典型标签之前,要见声明<portlet:defineObjects/>,这样才可以使用其他的标签。defineObjects中间不允许定义任何属性和包含任何内容。
3.2.2 renderURL标签
属性 值类型 对应值
windowState String minimized
normal
maximized。
PortletMode String view, edit , help
var String
secure
String true
false
创建一个当前RenderURL,当访问它时将使Portlet窗口变为最大化状态,模式变为浏览。<portlet:param/>子元素会在生成的RenderURL中增加number、page两个参数和值。
3.2.3 actionURL标签
属性 值类型 对应值
windowState String minimized
normal
maximized。
portletMode String view, edit , help
var String
secure
String true
false
<portlet:actionURL windowState="normal" PortletMode="edit">
<portlet:param name="action" value="login"/>
</portlet:actionURL>
创建一个当前ActionURL,当访问它时将使Portlet窗口变为正常状态,模式变为编辑。<Portlet:param/>子元素会在生成的ActionURL中增加action参数和值。
renderURL和actionURL两个标签在诸如生成form表单的action等方面特别有用。
3.2.4 param标签
属性 值类型
name String
用在renderURL和actionURL标签内部,用来在生成的URL中增加参数和值。param标签不运行body内容存在。
3.2.5 namespace标签
为目前的Portlet产生一个唯一的Value,防止与其他Portlet或者Portal上面的Value冲突。
上述标签的具体属性及其约束,请参阅{PORTAL_HOME}/liferay/WEB-INF/tld/liferay-portlet.tld 。
第三节 Portal的对象
JSR168给Portal定义了几个特别的对象,用来操作Portal特有的信息。这些对象跟Servlet的对象有点类似,又有点不同。这些对象都封装在{PORTAL_HOME}/common/lib/ext/portlet.jar包中,具体支持实现要视Portal服务器而定。
3.3.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:
<%
PortletURL pu = renderResponse.createActionURL();
pu.setParameter("ACTION","LOGIN");
<form name="usrform" method="post" action="<%=pu.toString()%>">
%>
说明:表单提交最好使用Post方法而不是Get方法,因为某些Portal服务器可能会将内部状态编码到URL的Query字符串中。
使用renderURL:
<%
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方法中进行。比如:
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方法,再次传递一次.
3.3.2 Response对象
与Request对象一样,Response对象也有两种:RenderResponse和ActionResponse,分别用来封装对应的RenderRequest和ActionRequest的返回信息,比如重定向、窗口状态、Portlet模式等。他们两者的父类PortletResponse拥有serPorperty和getPorperty两个方法,用来传递信息给Portal容器。
ActionResponse主要用来处理以下功能:
a、 重定向
b、 改变窗口状态、Portlet模式
c、 传递parameter参数到RenderRequest中去
RenderResponse主要用来提供以下功能:
a、 设置ContentType
b、 得到OutputStream和Writer对象,用来输出页面内容
c、 Buffering缓冲
d、 设定Portlet的标题,但是必须在Portlet输出前调用,否则将被忽略
3.3.3 PortletConfig对象
和ServletConfig对象类似,PortletConfig对象提供对Portlet初始化信息以及PortletContext对象存取的方法。
和ServletConfig对象不同的是,PortletConfig对象提供对Portlet的标题等资源的I18N支持,可以通过设定不同的Resource Bundle文件以提供多种语言支持。
3.3.4 Session对象
由于容器不同,Portal的Session对象与Servlet的Session对象略有不同。
由于Portlet处于Portal服务器的缘故,Portlet的Session分为Application Scope和Portlet Scope。两者的区别在于:
①、Application Scope范围的Session中保存的对象,对于同一个Portlet应用范围内的所有Portlet都是可用的。
②、Portlet Scope范围的Session中保存的对象,只对本Portlet可用,其他Portlet即使在同一个应用中,也不可用。
但是对于Portlet应用来说,可以通过HttpSession来访问。毕竟Portlet应用也是Web应用。在使用Session对象的时候,最好能明确指出使用的是那个Scope范围的Session。比如:
<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对象。
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取得PortletSession。APPLICATION_SCOPE范围下的Session对象值。
HttpSession se = request.getSession();
if(se.getAttribute("PortletSession.AS")!=null){
app=se.getAttribute("PortletSession.AS");
}
3.3.5 Preference对象
Preference对象被设计用来实现用户的个性化设置,可以帮助用户对Portlet进行符合用户需求的显示定制和行为定制,可以替代部分的数据库功能。需要指出的是,Preference对象只是用来存取简单的配置信息,并不能完全替代数据库应用。
Preference对象对于配置信息采用键-值的形式存取,用户可以将需要的信息暂时保存在Preference中。
PortletPreference p= req.getPortletPreferences();
p.setValue("educhina.username","educhina");
p.store();
Preference对象用来存取用户的个性化信息,所以不同用户的Preference对象不能共享,这点跟Session不同。
可以在Portlet.xml中配置Preference信息,如下:
<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 的<complexType name="preferenceType">部分。
第四节 编写自己的Portlet类
Liferay Portal内部集成了78个Portlet,包括直接用PrintWriter输出的、调用JSP输出的、调用Servlet输出的,数据来源有直接从数据库取得的、通过Web Service取得的等等。这里,我们只讲述直接用PrintWriter输出的和调用JSP输出的,目的在于讲述如何编写自己的Portlet类。其他的与此类似,不赘述。
3.4.1 开发环境
IDE:Eclipse V3.0.1
JDK:V1.4.2_06
ANT:V1.6.2
Tomcat:V5.0(集成在Liferay Portal中)
Liferay Portal:liferay-portal-pro-3.6.0-tomcat
3.4.2 准备工作
①、安装JDK V1.4.2_06,在系统环境变量中增加变量JAVA_HOME,指向JDK安装目录。
②、安装ANT,在系统环境变量中增加变量ANT_HOME,指向ANT安装目录。
③、下载并启动Eclipse V3.0.1.
④、下载并解压缩liferay-portal-pro-3.6.0-tomcat.zip到某一文件夹,该文件夹即为{PORTAL_HOME}。
⑤、在Eclipse中新建一个Java项目,命名为TestPortal,路径为D:\TestPortal,将{PORTAL_HOME}\common\ext\portlet.jar以外部jar的形式添加到库中。下文中,D:\TestPortal将以{APP_HOME}代称。在{APP_HOME}下创建文件夹webapp、deploy、bak。项目缺省输出文件夹为{APP_HOME}\webapp\WEB-INF\classes 。
⑥、在{APP_HOME}\webapp\WEB-INF目录下创建web.xml,内容如下:
<?xml version="1。0"?>
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc。//DTD Web Application 2。3//EN" "http://java。sun。com/dtd/web-app_2_3。dtd">
<web-app>
<display-name>TestPortal</display-name>
</web-app>
⑦、在{APP_HOME}\webapp\WEB-INF下创建tld文件夹,将{PORTAL_HOME}\liferay\WEB-INF\tld/liferay-portlet.tld拷贝到创建的tld文件夹下,备用。
⑧、新建一个Java包com.educhina.portal 。
3.4.3 HelloWorldPortlet
HelloWorldPortlet类计划用单纯的PrintWriter输出Portlet标记片断。在包com.educhina.portal下新建Java类HelloWorldPortlet,这个类必须扩展自javax.Portlet.GenericPortlet类。设计让HelloWorldPortlet支持浏览和编辑两种模式,所以HelloWorldPortlet重写doView和doEdit方法。简单的代码如下:
package com.educhina.portal;
import java.io.IOException;
import javax.Portlet.GenericPortlet;
import javax.Portlet.PortletException;
import javax.Portlet.RenderRequest;
import javax.Portle.RenderResponse;
public class HelloWorldPortlet extends GenericPortlet{
public void doView(RenderRequest req, RenderResponse res)
throws IOException, PortletException {
res.setContentType("text/html");
res.getWriter().println("HelloWorld!");
}
public void doEdit(RenderRequest req,RenderResponse res)
throws IOException,PortletException {
res.setContentType("text/html");
res.getWriter().println("HelloWorld!");
}
}
doView和doEidt方法从RenderRequest取得PrintWriter对象,直接输出一个String字符“HelloWorld!”。这个String字符将作为HelloWorldPortlet的片断内容。
3.4.4 HelloJSPPortlet
HelloJSPPortlet类计划调用外部JSP输出。同样的,HelloJSPPortlet也要扩展自GenericPortlet类。HelloJSPPortlet调用getPortletConfig().getInitParameter("..")方法,取得在Portlet。xml中配置的view-jsp和edit-jsp参数值,以此确定JSP页面的具体位置。然后调用PortletRequestDispatcher的include方法,将JSP页面加载到RenderResponse。代码如下:
package com.educhina.portal;
import java.io.IOException;
import javax.Portlet.GenericPortlet;
import javax.Portlet.PortletException;
import javax.Portlet.PortletRequestDispatcher;
import javax.Portlet.RenderRequest;
import javax.Portlet.RenderResponse;
public class HelloJSPPortlet extends GenericPortlet{
public void doView(RenderRequest req, RenderResponse res)
throws IOException, PortletException {
res.setContentType("text/html");
String jspName = getPortletConfig().getInitParameter("view-jsp");
PortletRequestDispatcher rd = getPortletContext().getRequestDispatcher(jspName);
rd.include(req,res);
}
public void doEdit(RenderRequest req,RenderResponse res)
throws IOException,PortletException {
res.setContentType("text/html");
String jspName = getPortletConfig().getInitParameter("edit-jsp");
PortletRequestDispatcher rd = getPortletContext().getRequestDispatcher(jspName);
rd.include(req,res);
}
}
在{APP_HOME}/webapp目录下创建view.jsp和edit.jsp,view.jsp代码如下,edit.jsp类似:
<table cellpadding="8" cellspacing="0" width="100%">
<tr>
<td>
<font class="Portlet-font" style="font-size: x-small;">
This is a <b>Sample JSP Portlet</b> used in viewing model。 Use this as a quick way to include JSPs。
</font>
</td>
</tr>
</table>
JSP文件不能包含关于HTML的<head>、<body>、<html>的信息,只能包含原来位于<body></body>内部的HTML内容。那些<head>、<body>、<html>信息由Portal页面来提供。
只有在JSP页面中使用<%@ taglib uri="http://java.sun.com/portlet" prefix="portlet" %>和<portlet:defineObjects/>,JSP页面才可以直接操作Portlet的一些变量,比如:renderResponse、renderRequest、portletConfig。
第五节 修改Web部署描述文件
正如2.6.1所指出的那样,要保证Portlet能够在Liferay Portal成功部署,必须对web.xml进行必要的修改,添加Portlet监听器、Servlet映射、Portlet标签库。在先前web.xml的<display>节点下增加如下内容:
<listener>
<listener-class>com.liferay.portal.servlet.PortletContextListener</listener-class>
</listener>
<servlet>
<servlet-name>HelloWorldPortlet</servlet-name>
<servlet-class>com.liferay.portal.servlet.PortletServlet</servlet-class>
<init-param>
<param-name>Portlet-class</param-name>
<param-value>com.educhina.portal.HelloWorldPortlet</param-value>
</init-param>
<load-on-startup>0</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>HelloWorldPortlet</servlet-name>
<url-pattern>/HelloWorldPortlet/*</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>HelloJSPPortlet</servlet-name>
<servlet-class>com.liferay.portal.servlet.PortletServlet</servlet-class>
<init-param>
<param-name>Portlet-class</param-name>
<param-value>com.educhina.portal.HelloJSPPortlet</param-value>
</init-param>
<load-on-startup>0</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>HelloJSPPortlet</servlet-name>
<url-pattern>/HelloJSPPortlet/*</url-pattern>
</servlet-mapping>
<taglib>
<taglib-uri>http://java.sun.com/Portlet</taglib-uri>
<taglib-location>/WEB-INF/tld/liferay-Portlet.tld</taglib-location>
</taglib>
其中,<listener>节点是增加一个监听器,以便Liferay Portal监听所有针对Portlet的操作。<servlet>以及<servlet-mapping>是将上述两个Portlet类加入Servlet容器中。Portlet类实质上也是Servlet。<tablib>是将Liferay Portal标签库加入列表中,以便JSP调用。
第六节 创建Liferay Portal部署描述文件
修改完web.xml之后,还要创建2.6所说的三个Portlet部署描述文件:portlet.xml、liferay-portlet.xml、liferay-display.xml。
①、portlet.xml
portlet.xml定义Portlet的初始化信息。这里,我们在portlet.xml中增加两个Portlet节点,分别代表HelloWorldPortlet和HelloJSPPortlet。其中,HelloWorldPortlet支持PringWriter输出,HelloJSPPortlet支持JSP输出;两者都支持浏览和编辑两种模式。HelloJSPPortlet需要定义两个init参数,告诉系统JSP文件的位置。
<portlet>
<portlet-name>HelloWorldPortlet</portlet-name>
<display-name>HelloWorldPortlet</display-name>
<portlet-class>com.educhina.portal.HelloWorldPortlet</portlet-class>
<expiration-cache>0</expiration-cache>
<supports>
<mime-type>text/html</mime-type>
</supports>
<supports>
<mime-type>text/html</mime-type>
<Portlet-mode>edit</Portlet-mode>
</supports>
<portlet-info>
<title>HelloWorldPortlet</title>
<short-title>HelloWorldPortlet</short-title>
<keywords>HelloWorldPortlet</keywords>
</portlet-info>
<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>
<portlet-name>HelloJSPPortlet</portlet-name>
<display-name>HelloJSPPortlet</display-name>
<portlet-class>com。Educhina.portal.HelloJSPPortlet</portlet-class>
<init-param>
<name>view-jsp</name>
<value>/view。jsp</value>
</init-param>
<init-param>
<name>edit-jsp</name>
<value>/edit。jsp</value>
</init-param>
<expiration-cache>0</expiration-cache>
<supports>
<mime-type>text/html</mime-type>
</supports>
<supports>
<mime-type>text/html</mime-type>
<Portlet-mode>edit</Portlet-mode>
</supports>
<portlet-info>
<title>HelloJSPPortlet</title>
<short-title>HelloJSPPortlet</short-title>
<keywords>HelloJSPPortlet</keywords>
</portlet-info>
<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>
②、liferay-Portlet.xml
Liferay-Portlet.xml主要定义Portlet的模板、实例总数、是否允许重复定义等。同样的,我们增加了两个<Portlet>节点,代表HelloWorldPortlet和HelloJSPPortlet。
<?xml version="1。0"?>
<!DOCTYPE liferay-Portlet-app PUBLIC "-//Liferay//DTD Portlet Application 3。5。0//EN" "http://www。liferay。com/dtd/liferay-Portlet-app_3_5_0。dtd">
<liferay-portlet-app>
<portlet>
<Portlet-name>HelloWorldPortlet</Portlet-name>
<struts-path>HelloWorldPortlet</struts-path>
<use-default-template>true</use-default-template>
<instanceable>true</instanceable>
</portlet>
<portlet>
<Portlet-name>HelloJSPPortlet</Portlet-name>
<struts-path>HelloJSPPortlet</struts-path>
<use-default-template>true</use-default-template>
<instanceable>true</instanceable>
</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>
③、liferay-display.xml
liferay-display.xml定义Portlet所属类别。Liferay Portal默认定义了一个category.test类别,这里,我们将HelloWorldPortlet和HelloJSPPortlet归属到category.test。
<?xml version="1。0"?>
<!DOCTYPE display PUBLIC "-//Liferay//DTD Display 3。5。0//EN" "http://www。liferay。com/dtd/liferay-display_3_5_0。dtd">
<display>
<category name="category。test">
<Portlet id="HelloWorldPortlet" />
<Portlet id="HelloJSPPortlet" />
</category>
</display>
至此,一个简单的Portlet就开发完成了。接下来,我们把它部署到Liferay Portal上。
第三部分 Liferay Portal部署
本部分主要内容
Portlet部署 ANT 管理Portlet
第四章 部署自己的Portlet
Liferay Portal跟Tomcat5.0集成在一起,从本质上讲,liferay-portal-pro-3.6.0-tomcat.zip是一个Tomcat压缩包,只是其中将liferay作为默认应用,并将跟Portlet有关的操作都交给liferay应用处理而已。因此,Liferay Portal支持所有针对Tomcat5.0的部署方式,包括:手动部署、Ant部署,并且支持热部署。
第一节 手动部署
手动部署可以采用拷贝文件夹、war部署、编写部署文件三种方式:
①、拷贝文件夹:与单纯的Tomcat一样,我们可以将{APP_HOME}\webapp目录拷贝到{PORTAL_HOME}\webapps\下,该webapp目录名为TestPortal。启动Liferay Portal(双击{PORTAL_HOME}\bin\startup。bat)即可。
②、war部署:或者将{APP_HOME}\webapp打包成TestPortal.war,拷贝war到{PORTAL_HOME}\webapps\下,启动Liferay Portal,让Tomcat自动解压。在命令行模式下切换到{APP_HOME}\webapp目录,执行 jar cvf TestPortal.war * 。
③、编写部署文件:
{PORTAL_HOME}\conf\Catalina\localhost目录下,创建TestPortal.xml文件,内容如下:
<Context path="/TestPortal" docBase="D:\TestPortal\webapp" debug="0" reloadable="true" crossContext="true">
</Context>
部署成功后,登录Liferay Portal,可以在桌面底部的下拉列表中看到HelloWorldPortlet和HelloJSPPortlet两个Portlet。将它们添加到桌面中。
第二节 Ant自动部署
确保之前已经安装Apache Ant,并正确添加ANT_HOME到系统环境变量。
①、拷贝之前打包的TestPortlet.war到{APP_HOME}/deploy目录;
②、从http://prdownloads。sourceforge。net/lportal/Portlet-deployer-3。6。0。xml 下载Portlet-deployer-3.6.0.xml 到{APP_HOME}\deploy,改名为build。xml以便Ant自动加载;
③、确保JDK1.4.2和Ant 1.6安装成功,并配置到系统环境变量;
④、确保Tomcat或者其他服务器已经正确安装,或者Liferay Portal正常安装。
编辑build.xml,使其只想你的应用服务器或者Servlet容器。比如,如果你安装JBoss+Jetty到/opt/liferay目录,那么编辑build.xml,确保只有JBoss+Jetty部分没有被注释,修改app.server属性为/opt/liferay。
Build.xml默认是开启JBoss+Jetty部分,本文采用的是Tomcat集成包,所以将JBoss+Jetty部分注释掉,开始Tomcat部分。修改app.server.dir属性,指向{PORTAL_HOME}。如下图:
⑤、命令行切换到到{APP_HOME}/deploy目录,执行 ant deploy ,系统会自动将TestPortal。war解压,必要时修改web.xml、portlet.xml等部署文件,将解压后的TestPortal文件夹拷贝到{PORTAL_HOME}\webapps目录下。
启动Liferay Portal之前,建议先确认修改后的web.xml、portlet.xml等部署文件是否正确。
第三节 加入Liferay Portal自有列表
之前我们提到过,Liferay Portal集成了78个默认的Portlet应用。这些应用都通过{PORTAL_HOME}\liferay\WEB-INF\目录下的portlet.xml、liferay-portlet.xml、liferay-display。xml描述。我们只要更改这些描述文件,就可以将我们自己的应用加入到Liferay Portal的Portlet列表中了,效果跟手动部署和Ant自动部署一样。
①、拷贝{APP_HOME}\webapp目录的内容到{PORTAL_HOME}\liferay\html\Portlet目录下,更改文件夹名称为TestPortal。
②、将TestPortal\WEB-INF\classes文件夹剪切到{PORTAL_HOME}\liferay\WEB-INF目录下。
③、将TestPortal\WEB-INF\web。xml中<servlet>、<servlet-mapping>的内容合并到{PORTAL_HOME}\liferay\WEB-INF\web.xml中。删除TestPortal\WEB-INF\web.xml。
④、将TestPortal\WEB-INF\Portlet.xml中关于HelloWorldPortlet和HelloJSPPortlet的<portlet>的内容合并到{PORTAL_HOME}\liferay\WEB-INF\portlet.xml中。删除TestPortal\WEB-INF\ portlet.xml。
⑤、将TestPortal\WEB-INF\liferay-portlet.xml中关于HelloWorldPortlet和HelloJSPPortlet的<portlet>的内容合并到{PORTAL_HOME}\liferay\WEB-INF\liferay-portlet.xml中。删除TestPortal\WEB-INF\liferay-portlet.xml。
⑥、将TestPortal\WEB-INF\liferay-display.xml中关于HelloWorldPortlet和HelloJSPPortlet的<portlet>的内容合并到{PORTAL_HOME}\liferay\WEB-INF\liferay- display.xml中。删除TestPortal\WEB-INF\ liferay- display.xml。
这个方法比较复杂,而且不容易扩展和调试,通常不建议采用。
第四节 普通Java Web应用转化为Portlet应用
随着开发的深入,我们希望能够将原来的Java Web应用迁移到Liferay Portal,构建真正的企业门户。Liferay Portal灵活的二次开发机制,允许用户将各种各样的内容集成到Portal平台上来,消除信息孤岛。将一个Java Web应用转化为Portlet应用的步骤如下:
①、撰写扩展自GenericPortlet的Portlet和JSP页面。这个Portlet可以使用PrintWriter输出或者调用JSP页面输出方式。通常,如果Java Web应用是采用MVC三层模式,那么只需要更改View层就可以了。
②、修改web.xml,增加2。6。1所述的Portlet监听器和Portlet标签库,增加针对上步骤所写的servlet和servlet映射。
<servlet>
<servlet-name>yourPortlet</servlet-name>
<servlet-class>com.liferay.portal.servlet.PortletServlet</servlet-class>
<init-param>
<param-name>Portlet-class</param-name>
<param-value>full.name.of.yourPortlet</param-value>
</init-param>
<load-on-startup>0</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>yourPortlet</servlet-name>
<url-pattern>/yourPortlet/*</url-pattern>
</servlet-mapping>
③、创建portlet.xml,增加相应的Portlet定义信息,规范参考2.6.2。
④、创建liferay-portlet.xml,增加相应的Portlet定义信息,规范参考2.6.3。
⑤、创建liferay-display.xml,增加相应的Portlet类别定义信息,规范参考2.6.4。
⑥、拷贝portlet.jar和liferay-Portlet.tld到当前应用。其中,portlet.jar是Portlet API包,作用类似servlet-api.jar,位于{PORTAL_HOME}\common\lib\ext\liferay-portlet.tld是Liferay Portal提供的Portlet标签库。
⑦、选择适当的部署方式,将修改后的Java Web应用部署到Portlet平台上。
第四部分 附录
本部分主要内容
资源网站 Portlet范例 参考资料 后序
第五章 相关资源
作为一个开源的门户产品,Liferay Portal已经比较成熟,有比较齐全的文档。随着应用的深入,开源免费的中文化文档也在陆续出现。
第一节 资源网站
Liferay Portal 官方网站:http://www.liferay.com
Liferay Portal 中文网站:http://www.liferay.cn
Liferay Portal 论坛:http://forums.liferay.com
Tracker : http://support.liferay.com
邮件列表:http://sourceforge.net/mailarchive/forum.php?forum=lportal-development
JavaLobby专题:http://www.javalobby.org/articles/liferay/
OSQS专题:http://cstsolaris.cst.nait.ab.ca/ist410/gerry/liferay/index.jsp
Leonardsoko1专题:http://www.leonardsokol.com/liferay/
Developer专题:http://www.developer.com/java/web/article.php/10935_3372881_1
第二节 示例
Liferay Portal随程序包提供了丰富的documentation,其中的Portlet Examples对Portal内置的Hello World、IFrame、Calendar、Message Boards、Mail五个Portlet进行了比较详细的解说。启动Liferay Portal后,浏览这里:
http://localhost/web/guest/documentation/development/Portlet
另外,Liferay Portal还在官方网站上提供了Sample La
发表评论
-
4.Liferay Portal的桌面和品质
2010-09-17 22:28 1110第四节 Liferay Portal的桌面 2.4.1 什 ... -
3.Liferay Portal内容和布局
2010-09-17 22:27 1553第三节 Liferay Portal内容和布局 Portle ... -
2.Liferay Portal的用户策略
2010-09-17 22:26 1109第二节 Liferay Portal的用 ... -
1.Liferay Portal 架构解析
2010-09-17 22:24 1160序... 5 第一部分 Liferay Portal 架构解 ... -
jetspeed介绍
2010-09-17 22:20 1024综述 Apache开源组织的企业门户项目,现有两个版本: ...
相关推荐
《Liferay Portal 6.1.1源码部署在Eclipse中的详细步骤》 Liferay Portal是一款开源的企业级门户平台,具有高度可定制性。在本文中,我们将深入探讨如何将Liferay Portal 6.1.1的源码部署到Eclipse集成开发环境中,...
6. **部署描述符**:如liferay-plugin-package.xml,定义portlet的部署信息,如版本、依赖、资源引用等。 7. **资源权限**:Liferay支持细粒度的资源权限控制,开发者可以为portlet定义不同级别的访问权限。 8. **...
10. **部署和升级**:熟悉Liferay的部署过程,包括portlet、主题和布局的部署,以及版本升级和数据迁移的注意事项。 总的来说,"Packtpub.Liferay.User.Interface.Development.Nov.2010.rar" 的内容可能涵盖以上...
- `web.xml`:此文件是Web应用的部署描述符,用于配置Servlet和监听器等。在Liferay中,需要添加PortletContextListener监听器,以及引用Liferay的Portlet Tag Library(TLD): ```xml ... ...
Liferay Portal使用portlet.xml、liferay-portlet.xml和liferay-display.xml这三份配置文件来描述Portlet的基本信息和行为。portlet.xml包含了Portlet的基本设置,如portlet名称、显示名称、portlet类、初始化参数等...
如果你想让JAR包在部署后直接出现在Liferay的Tomcat目录下,可以修改工作区的`gradle.properties`文件,添加属性`liferay.workspace.home.dir`指向Liferay安装目录。 2. **Service Builder使用** - 创建一个新的...
Liferay Portal 的部署描述文件包括 web.xml、portlet.xml、liferay-Portlet.xml、liferay-display.xml 和 liferay-layout-templates.xml 等。这些文件负责描述 Liferay Portal 的配置和设置。 第三部分:Liferay ...
开发Portlet的步骤包括准备开发环境、编写Portlet代码、修改部署描述文件等。Liferay提供了示例代码,如`HelloWorldPortlet`和`HelloJSPPortlet`,帮助开发者快速上手。 #### 四、Liferay Portal 部署 部署Portlet...
portlet.xml文件是portlet部署描述符,它定义了portlet的基本信息,如portlet名称、显示名称、portlet类、初始化参数、缓存策略、支持的MIME类型、portlet元数据以及安全角色引用。开发者可以通过这个文件配置...
Liferay Portal是一个开源的企业级门户解决方案,它允许用户构建和部署Web应用程序和门户。它支持多种插件,包括Portlets(小应用程序)、主题、布局模板等,使得开发者能够灵活地创建企业级应用。 在描述中提到的...
##### 第六节 Liferay Portal 的部署描述文件 - **web.xml**: Web应用程序的核心配置文件。 - **portlet.xml**: 描述portlet元数据的XML文件。 - **liferay-portlet.xml**: Liferay特有的配置文件,用于定义portlet...
在 `portal/portal-impl/portal.properties` 文件中,你可以找到关于如何扩展 Liferay 的描述。例如,可以在 `ext/ext-impl/portal-ext.properties` 文件中添加自定义配置。 ### 三、集成 Spring 1. **配置 Spring...
根据描述中的信息,这里测试过的是Tomcat 5.x版本,但请确保你的版本与Liferay Portal的兼容性。 2. **解压Liferay**:获取Liferay Portal的war文件,将其解压到Tomcat的webapps目录下。通常,war文件名是`liferay-...
**3.6 创建 Liferay Portal 部署描述文件** 除了标准的部署描述文件外,还需要创建 Liferay 特有的部署描述文件,如 liferay-portlet.xml。 通过以上详尽的解析,我们可以看到 Liferay Portal 不仅具备强大的功能,...
只需要将定义好的TPL文件路径添加到部署描述文件中,Liferay在启动时就会自动加载这些自定义布局。这种方式大大增强了Liferay的可扩展性和个性化能力。 总之,**Liferay Portal的内容和布局管理**是构建高效、灵活...
##### 2.6 Liferay Portal 的部署描述文件 - **web.xml**:这是标准的 Java Web 应用程序部署描述文件。 - **portlet.xml**:Portlet 的部署描述文件,定义了 Portlet 的基本信息和行为。 - **liferay-portlet.xml*...
### WAS 7.0 上安装部署 Liferay Portal 步骤详解 #### 一、准备工作 在开始部署之前,需要确保已经完成了以下准备工作: 1. **安装 WAS 7.0**: - 安装 WebSphere Application Server (WAS) 7.0 并配置好应用...
5. **部署portlet**:将WAR文件上传到Liferay Portal服务器的deploy目录下,服务器会自动检测并部署portlet。 6. **测试和调试**:在Liferay Portal上查看和测试portlet的功能,根据需要进行调整。 **Portlet API...