??xml version="1.0" encoding="utf-8" standalone="yes"?>
]]>
]]>
]]>
]]>
]]>
]]>
]]>
]]>
作?Sunil Patil;observer
原文地址:http://www.onjava.com/pub/a/onjava/2005/10/19/challenging-java-dominance.html
中文地址:http://www.matrix.org.cn/resource/article/44/44029_Portlet.html
关键词:(x) Portlet Java
Portlets
“Portlets是一UWeblgQ就像servletsQ是专ؓ(f)合成页面里的内容聚集在一赯(g)设计的。通常h一个portal面?x)引发多个portlets被调用。每个portlet都会(x)生成标记D,q与别的portlets生成的标记段l合在一起嵌入到portal面的标记内。”(摘自Portlet规范QJSR 168Q?br />
本文探讨?jin)以下内容?x)
1. (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)Portal面的元?
2. (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)Portal是什么?
3. (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)Portlets是什么?
4. (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)开发“Hello World?Portlet
5. (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)在Pluto上部|HelloWorld Portlet
6. (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)如何创徏Portal面
7. (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)l束?
8. (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)资源
Portlet规范?yu)portlet定义ZU“基于Java技术的weblgQ由处理h和生成动态内容的portlet容器理”。这D话听v来是不是有些费解Q本文将说明portlets是什么以?qing)能用它们做什么?br />
?昄?jin)在讉K一个portal服务器时览器中面的样子?br />
? 典型的portal服务器的面Q点?yn)L看原图)(j)
如果仔细查看览器里的页面,׃(x)看到面是由不同的“窗口”组成的。一个窗口用于刷新天气,另一个用于新闻,q有一个用于刷新股P{等。这里的每一个窗口都代表?jin)一个portlets。如果看得再仔细些,q(sh)(x)发现每个H口都有一个标题条和一些按钮,包括最化和最大化按钮?br />
在系l里Q这些窗口是怺独立开发、各不同的应用。新闻portlet的开发者创建应用ƈ打包成war格式的文?随后portal服务器的理员在服务器上部v该war文gq创建页面,接下来每个用户会(x)选择在他的页面里有哪些应用。例如,如果用户对股价不感兴而对体育感兴,他可以用“体肜y(c)窗口替换“股价”窗口?br />
Portlet技术需要学?fn)许多新概念Q本文不可能全都늛Q因此本文分Z部分。在W一部分里我们详l说明portals和portletsQƈ开发一个简单的“Hello World”portletQ在W二部分我们探讨一些高U主题?br />
我们用Apache的Pluto服务器(Portlet API 1.0规范的参考实玎ͼ(j)来测试我们的CZportletsQ我们还?sh)(x)花些时间探讨如何安装和使用Pluto服务器?br />
Portal面的元?/span>
?昄?jin)Portal面的各U元素?br />
? portal面的元?br />
每个portlet面׃个或多个portletH口l成Q每个portletH口又分Z部分Q一个是外观Q它军_?jin)portletH口的标题条、控制和边界的样式;另一个是portletD,它由portlet应用填充?br />
Portal服务器决定了(jin)portal面的整体观感,像标识、标题条颜色、控制图标等。通过修改几个JSP和css模板文g可以改变portal的整个观感。我们将在“如何创建portal面”部分对此做深入讨论?br />
Portal是什么?
在了(jin)解portlet之前有必要先?jin)解portal。在Portlet规范里是q样讲的Q“portal是一Uweb应用Q通常用来提供个性化、单ơ登录、聚集各个信息源的内容,q作Z息系l表现层的宿丅R聚集是指将来自各个信息源的内容集成C个web面里的zd”?br />
Portal的功能可以分Z个主要方面:(x)
1. (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)Portlet容器QPortlet容器与servlet容器非常cMQ所有的portlet都部|在portlet容器里,portlet容器控制portlet的生命周期ƈ为其提供必要的资源和环境信息。Portlet容器负责初始化和销毁portletsQ向portlets传送用戯求ƈ合成响应?br />2. (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)内容聚集QPortlet规范中规定portal的主要工作之一是聚集由各种portlet应用生成的内容,我们在“如何创建Portal面”部分对此做q一步讨论?br />3. (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)公共服务Qportlet服务器的一个强Ҏ(gu)它所提供的一套公共服务。这些服务ƈ不是portlet规范所要求的,但portal的商业实现版本提供了(jin)丰富的公共服务以有别于它们的竞争者。在大部分实C都有望找到的几个公共服务有:(x)
(tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) o 单次dQ只需dportal服务器一ơ就可以讉K所有其它的应用Q这意味着你无需再分别登录每一个应用。例如一旦我d?jin)我的intranet|站Q我p讉Kmail应用、IM消息应用和其它的intranet应用Q不必再分别dq些应用?br /> Portal服务器会(x)Z分配一个通行证库。你只需要在mail应用里设定一ơ用户名和密码,q些信息以加密的方式存储在通行证库中。在你已d到intranet|站q要讉Kmail应用的时候,portal服务器会(x)从通行证库中读取你的通行证替你登录到mail服务器上。你对其它应用的讉K也将照此处理?br /> (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)o个性化Q个性化服务的基本实C用户能从两方面个性化她的面Q第一Q用户可以根据她的自w喜好决定标题条的颜色和控制图标。第二,用户可以军_在她的页面上有哪些portlets。例如,如果我是个体育迷Q我可能?x)用一个能提供我钟q队最C息的portlet来取代股和新闻portlets?br /> (tng) (tng) (tng) (tng) (tng) (tng) 一些在个性化服务斚w领先的商业实现版本允怽建立为用hCZ么样的应用所依据的标准(如收入和兴趣Q。在q种情况下,可以讑֮一些像“对M收入为X的用hC馈赠商品的portlet”和“对M收入为X的用hC打折商品的portlet”这L(fng)商业规则?br />
(tng) (tng) (tng) (tng) (tng) (tng)此外q有一些公共服务,比如机器译Q是由portal服务器将portlet生成的内容翻译ؓ(f)用户要求的语a。大部分的商业portal服务器都支持手持讑֤讉Kq具有针对不同的览l端生成不同内容的能力?br />
Portlets是什么?
与servletscMQportlets是部|在容器内用来生成动态内容的weblg。从技术角度讲portlet是一个实C(jin)javax.portlet.Portlet接口的类Q它被打包成war文g格式部v到portlet容器里?br />
Portlets在以下方面与servlets怼Q?br />1. (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)portletsq定的容器理?br />2. (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)portlets生成动态内宏V?br />3. (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)portlet的生命周期由容器理?br />4. (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)portlets通过h/响应模式与web客户端交互?br />
Portlets在以下方面与servlets相异Q?br />1. (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)portlets只能生成标记D,而不是整个文档?br />2. (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)portlets没有可供直接讉K的URL地址。不q你q是能够让别人通过URL讉K到portletQ你可以把包含该portlet的页面的URL发给他?br />3. (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)portlets不能随意地生成内容,q是因ؓ(f)portlet生成的内Ҏ(gu)l要成ؓ(f)portal面的一部分。如果portal服务器要求的是html/textcdQ那么所有的portlets都应生成html/textcd的内宏V再比方_(d)如果portal服务器要求的是WMLcdQ那么所有的portlets都应生成WMLcd的内宏V?br />
portletsq提供了(jin)一些附加的功能Q?br />1. (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)讄参数的持久化存储Qportlets提供?jin)一个PortletPreferences对象用来保存用户的设|参数。这些参数被存入一个持久化数据库,q样服务器重启后数据依然有效。开发者不必关?j)这些数据存储的具体实现机制?br />2. (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)h处理Qportlets提供?jin)更为细_度的请求处理。对于用户在portlet上动作时向该portlet发出的请?一U称为活跃期的状?Q或者因用户在其它portlet上动作而引发的h面hQPortal服务器提供了(jin)两种不同的回调方法来处理?br />3. (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)Portlet模式Qportlets用模式的概念来表C用户在做什么。在使用mail应用的时候,你可能会(x)用它来读信、写信或(g)查信件――这些都是mail应用的预定功能,Portlets通常以VIEW模式提供q些功能。但q有一些活动,像指定刷新时间或Q重斎ͼ(j)讄用户名和密码Q这些活动允许用户定制应用的行ؓ(f)Q因此它们用的是EDIT模式。Mail应用的帮助功能用的是HELP模式?br />
如果仔细x(chng)其实q里面ƈ没有什么新东西Q它们反而大部分都是普通的业务需求。Portlet规范的作用在于它提供?jin)一个抽象层Q这才是它对所有与之相关的人-最l用戗开发者和理员-的h(hun)值所在?br />
作ؓ(f)一个开发者,我会(x)所有与VIEW模式有关的业务逻辑攑օdoView()Ҏ(gu)Q将与应用配|有关的业务逻辑攑օdoEdit()Ҏ(gu)Q将与帮助有关的逻辑攑օdoHelp()Ҏ(gu)
q就化了(jin)理员对portlet应用的访问控制管理,因ؓ(f)他只需改变portlet的访问权限就能决定用戯做什么。例如,如果mail应用的一个用戯够在EDIT模式下设定用户名和密码,那么可以断定他hEDIT模式讉K权限?br />
不妨考虑q样一U情形:(x)我是一个intranet|站的管理员Q我的公怹?jin)一个能昄新闻信息的第三方portlet应用Q该应用允许用户指定跟踪新闻更新的URL地址Q我惛_助它ؓ(f)用户昄公司的内部新闅R另一个需求是我不惌用户通过该应用来跟踪M其它的新M息来源。作为管理员Q我可以为所有的用户指定一个用于内部新L新的URL地址Q同旉过改变portlet应用的部|描q符来取消其它h修改该地址的权限?br />
׃所有的portlet应用都具有相似的UI界面Q因此采用portlets可ɾ|站Ҏ(gu)l用h具吸引力。如果她想阅MQ何一个应用的帮助信息Q她可以点击帮助按钮Q她也知道点ȝ辑按钮能让她q入应用的配|屏。标准化的用L(fng)面你的portlet应用更引人?br />
4. (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)H口状态:(x)H口状态决定了(jin)portal面上留lportlet生成内容的空间。如果点?yn)L大化按钮Qportlet占据整个屏q,成ؓ(f)用户唯一可用的portletQ而在最化状态,portlet只显CZؓ(f)标题条。作为开发者应当根据可用空间的大小来定做内宏V?br />
5. (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)用户信息Q通常portlets向发?gu)求的用户提供个性化的内容,Z(jin)能更加行之有效,portlets需要访问用L(fng)属性信息,如姓名、email、电(sh)话等。Portlet API为此提供?jin)用户属性的概念Q开发者能够用标准的方式访问这些属性,q由理员负责在q些属性与真实的用户信息数据库Q通常是LDAP服务器)(j)之间建立映射关系?br />
我们在本文的第二部分深入讨些特点-h处理、用户信息和portlet模式?br />
开?Hello World" Portlet
现在我们来开发一个简单的HelloWorld portlet?br />1. (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)创徏一个名为HelloWorld的web目Q它与通常的servlet目cMQ有一?WEB-INF/web.xml文g作ؓ(f)目的部|描q符?br />
2. (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)在build path里加入portlet-api-1.0.jar文gQ该jar文g是Pluto发行包的一部分?br />
3. (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)在Source文g夹中按如下内容创建HelloWorld.java文gQ?br />public class HelloWorld extends GenericPortlet{
(tng) (tng)protected void doView(RenderRequest request,
(tng) (tng)RenderResponse response) throws
(tng) (tng)PortletException, IOException {
(tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)response.setContentType("text/html");
(tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)response.getWriter().println("Hello Portlet");
(tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)}
}
每个portlet都要实现Portlet接口Q该接口为portlet定义?jin)生命周期方法。由于不惌盖所有这些方法,我们只对GenericPortletc进行扩展,它是一个实C(jin)Portlet接口的适配器类。GenericPortletcL供了(jin)所有生命周期方法的默认实现Q所以我们只需实现我们所需要的Ҏ(gu)?br />
我们?HelloWorld portlet里要做的只是昄“Hello Portlet”,所以我们将覆盖GenericPortletcȝdoView()Ҏ(gu)Q该Ҏ(gu)以PortletRequest ?PortletResponse作ؓ(f)参数。在doView()Ҏ(gu)中首先调用response.setContentType()以通知portlet容器该portlet要生成何种cd的内容-如果不这样做׃(x)DIllegalStateException异常。一旦设|了(jin)内容的类型,可以从response对象中获得PrintWriterq开始写入?br />
4. (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)每个portlet应用?WEB-INF文g夹中都有一个portlet.xml文gQ它是portlet应用的部|描q符。按以下内容创徏portlet.xml文gQ?br /><portlet>
(tng) (tng)<description>HelloWorldDescription
(tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)</description>
(tng) (tng) (tng) (tng)<portlet-name>HelloWorld
(tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)</portlet-name>
(tng) (tng) (tng) (tng)<display-name>Hello World
(tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)</display-name>
(tng) (tng) (tng) (tng)<portlet-class>com.test.HelloWorld
(tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)</portlet-class>
(tng) (tng) (tng) (tng)<expiration-cache>-1
(tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)</expiration-cache>
(tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)<supports>
(tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)<mime-type>text/html</mime-type>
(tng) (tng) (tng) (tng) (tng) (tng)<portlet-mode>VIEW
(tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)</portlet-mode>
(tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)</supports>
(tng) (tng) (tng) (tng)<supported-locale>en
(tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)</supported-locale>
(tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)<portlet-info>
(tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)<title>Hello World</title>
(tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)<short-title>Hello World
(tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)</short-title>
(tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)<keywords>Hello,pluto</keywords>
(tng) (tng) (tng) (tng) (tng) (tng)</portlet-info>
</portlet>
<portlet-name>元素声明?jin)portlet的名字,<portlet-class>元素指定?jin)portlet的全限定cdQ?lt;expiration-cache>元素以秒为单位指定了(jin)内容期的时间。这里面有一炚w要注意:(x)你在portlet上的某些动作可能?x)导致内容刷斎ͼq与~存旉无关?br /> <supports>元素指定对于l定?lt;mime-type>有哪些模式可供支持。在CZ中我们假定HelloWorld只能生成text/htmlcd的内容,且只有view模式可支持该内容cd。如果要增加对其它内容类型的支持Q需要添加新?lt;support>元素q指定支持该MIMEcd的模式有哪些。通常portlet对于text/htmlcd有VIEW、EDIT和HELP模式可供支持Q而对于WML MIMEcd则只有VIEW模式?br /> q可以用<supported-locale>元素来指定portlet支持哪些本地化?lt;title>元素用来指定portlet的标题。如果要Ҏ(gu)题做国际化处理,可以用元?lt;resource-bundle>指定资源Q比例properties文gQ的文g名。在q种情况下,容器根据用h在的地区从适当的properties文g中选择标题?br />
5. (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)每个portlet应用都是一个web应用Q因此除?jin)portlet.xml文g之外q需要有web.xml文g?br /><web-app>
(tng) (tng)<display-name>Hello World Portlet
(tng) (tng)</display-name>
(tng) (tng)<welcome-file-list
(tng) (tng) (tng) (tng)<welcome-file>index.jsp
(tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)</welcome-file>
(tng) (tng)</welcome-file-list>
</web-app>
6. (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)接下来将q些文gq行~译q打包ؓ(f)war文g。你可以自己完成q些工作Q或者下载带有build.xml 的示例代码(参见“资源”部分)(j)来创建war文g?br />在Pluto上部|HelloWorld Portlet
Pluto处于开发阶D늚早期Q因此还没有一套易于用的理工具。ؓ(f)?jin)能使用Pluto服务器,需要将~译和源代码两个版本都下载。需要注意的是以下说明是针对Windowsq_的,Unix用户通过修改斜杠W号和执行sh shell脚本Q不是bat批命令文Ӟ(j)?x)得到类似的l果?br />
1. (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)创徏一个文件夹Q比如C:\PlutoInstallation?br />2. (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)从Pluto的网站下载pluto-1.0.1-rc1.zip和pluto-src-1.0.1-rc1.zip?br />3. (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)pluto-1.0.1-rc1.zip解压到C:\PlutoInstallation.文g夹,它应被解压到C:\PlutoInstallation\pluto-1.0.1-rc1文g夹下?br />4. (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)执行C:\PlutoInstallation\pluto-1.0.1-rc1\bin\startup.bat启动PlutoQ现在可以通过地址http://localhost:8080/pluto/portal讉KPluto服务器?br />5. (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)pluto-src-1.0.1-rc1.zip解压到C:\PlutoInstallation\PlutoSrc文g夏V?br />6. (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)q入C:\PlutoInstallation\PlutoSrc文g夹,执行maven distribute:all.Q编译ƈ下蝲q行常规理d所必需的相兌源文件。现在可以将HelloWorldPortlet.war作ؓ(f)portletq行安装?jin)?br />7. (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)首先HelloWorldPortlet.war文g拯到C:\PlutoInstallation\portlets目录Q如果没q个目录创建它?br />8. (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)C:\PlutoInstallation\plutosrc\build.properties.sample更名为build.properties?br />9. (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)~辑build.propertiesQ将maven.tomcat.home指向Pluto~译版的安装位置Q在本例中应改ؓ(f)maven.tomcat.home=C:/PlutoInstallation/pluto-1.0.1-rc1?br />10. (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)Z(jin)安装portletQ进入C:\plutoInstallation\plutosrc\deploy文g夹,执行maven deploy -Ddeploy=c:\PlutoInstallation\portlets\HelloWorldPortlet.warQ应能看到“build successful”信息?br />11. (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)在C:\PlutoInstallation\pluto-1.0.1-rc1\webapps文g夹下Q应该有一个HelloWorldPortlet文g夏V?br />12. (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)现在q入C:\PlutoInstallation\pluto-1.0.1-rc1\webapps\HelloWorld\WEB-INF\ folder文g夹,打开portlet的web.xml文gQ你?x)发现里面自动多了(jin)几行,如下所C:(x)<servlet>
(tng) (tng)<servlet-name>HelloWorld</servlet-name>
(tng) (tng) (tng) (tng) <display-name>HelloWorld Wrapper</display-name>
(tng) (tng) (tng) (tng) (tng) (tng)<description>Automated generated
(tng) (tng) (tng) (tng) (tng) (tng)Portlet Wrapper</description>
(tng) (tng) (tng) (tng) (tng) (tng)<servlet-class>org.apache.pluto.core.PortletServlet
(tng) (tng) (tng) (tng) (tng) (tng)</servlet-class>
(tng) (tng) (tng) (tng) (tng) (tng)<init-param>
(tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) <param-name>portlet-class</param-name>
(tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) <param-value>com.test.HelloWorld
(tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) </param-value>
(tng) (tng) (tng) (tng) (tng) (tng)</init-param>
(tng) (tng) (tng) (tng) (tng) (tng)<init-param>
(tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) <param-name>portlet-guid</param-name>
(tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) <param-value>HelloPluto.HelloWorld
(tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) </param-value>
(tng) (tng) (tng) (tng) (tng) (tng)</init-param>
</servlet>
13. (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)接下来我们将该portlet加到面里。进入C:\PlutoInstallation\pluto-1.0.1-rc1\webapps\pluto\WEB-INF\data文g夹,可以看到有两个XML文gQpageregistry.xml和portletentityregistry.xml?br />14. (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)portletentityregistry.xml包含?jin)portlet的定义,在该文g中加入以下几行:(x) <application id="5">
(tng) (tng) <definition-id>HelloWorld</definition-id>
(tng) (tng) (tng) (tng) <portlet id="1">
(tng) (tng) (tng) (tng) (tng) (tng) <definition-id>HelloWorld.HelloWorld</definition-id>
(tng) (tng) (tng) (tng) </portlet>
</application>
应用?lt;definition-id>应ؓ(f)web应用所在文件夹的名字,portlet?lt;definition-id>应与web.xml中生成的portlet-guid怸致?br />15. (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)pageregistry.xml定义?jin)页面中包含了(jin)哪些portletsQ对该文件做如下改动Q?br /> (tng) (tng)<fragment name="p2" type="portlet">
(tng) (tng) (tng) (tng)<property name="portlet" value="/blog/5.1"/>
</fragment>
16. (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)执行shutdown命o(h)和startup命o(h)重启Pluto服务器,q回到地址http://localhost:8080/pluto/portalq点几ZTest Link”-此时面中将出现我们?br />
HelloWorld portlet?/span>
?的右侧显CZ(jin)HelloWorld portlet看上ȝ样子?br />
? portlet的屏q截?br />
如何创徏Portal面
?昄?jin)portal容器如何分ȝportletsl装为页面?br />
? 创徏Portal面
大部分的portal服务器基本上都是部v于应用服务器上的web应用Q通过servlet来处理访问portal服务器的h。查看一下Pluto的安装目录就?x)发现Pluto不过是一个部|于Tomcat服务器上的一个普通web应用Q再看看C:\PlutoInstallation\pluto-1.0.1-rc1\webapps\pluto\WEB-INF\web.xml?x)发现所有发往Pluto服务器的h都被映射到org.apache.pluto.portalImpl.Servlet上?br />
在本文开始部分“Portal面的元素”中Q我们提到portal面׃部分l成。一部分是由面中的portlets生成的内容,另一部分是由portal服务器生成的内容?br />
在Pluto里,只要用户发出hQ就?x)由servletq行控制Q根据用hh的页面来定需要显C的portlets的列表。一旦生成了(jin)列表Qservlet将控制转给q些portletsU程q收集由它们生成的内宏V?br />
对于由portal服务器生成的内容Q像portal|站的观感及(qing)每个portlet的外观和控制之类Q则取决于C:\PlutoInstallation\pluto-1.0.1-rc1\webapps\pluto\WEB-INF\aggregation文g夹下的JSP文g。RootFragment.jsp是主JSP文gQ它军_?jin)整体的观感和对齐方式;它还包含了(jin)Heads以定义在生成的页面中?lt;HEAD>标签里的内容。TabNavigation.jsp用来选择在banner中该昄什么(默认情况下在banner昄列表中也包扩?jin)pluto.png囄Q。TabNavigation.jsp用来定portal|站的导航方案。这意味着只需改动该文件夹下少量的几个JSP文gQ就能改变整个portal|站的观感?br />
PlutoҎ(gu)pageregistry.xml中的讄定面中有多少行,q用RowFragment.jspd充。ColumnFragment.jsp用来填充每个栏目。PortletFragmentHeader.jsp用来填充每个portlet的页_(d)像标题条?qing)最大化和最化控制。footer.jsp用来填充JSP的页脚。如果去看一下portal面的HTML代码׃(x)发现每个portletH口无非都是嵌入<TD>标签的内容块?br />
l束?/span>
M一U新技术要惌得成功都应具备以下条Ӟ(x)首先Q它能提升现有技术;其次Q它能解决现有技术遇到的普遍问题Q再ơ,它能提供多于一个的抽象层(有h_(d)每抽象出一层,问题p决一半)(j)?br />
׃portlet与现有的应用服务器架构兼容,q对Portlet API来说是一ơ发展servlet技术的好机?x)。你可以从portlet里调用EJBQ或者用它启动和参与由应用服务器控制的全局性事务。换句话_(d)在以商业逻辑为核?j)的领域里,portlet完全可以做得和servlet一样好?br />
Portlets提供?jin)一个抽象层Q现在你不必再担?j)客L(fng)使用?jin)什么样的HTTPҎ(gu)Q也不必自己~写E序L获像点击按钮q样的客L(fng)事g。最后但l不是最ơ要的一Ҏ(gu)Qportlets以提供像单次d、个性化{服务的方式解决?jin)servlets不能解决的大部分问题?br />
资源
·本文的示例代?/a>
·JSR 168的首?http://www.jcp.org/en/jsr/detail?id=168
·Pluto的首?http://portals.apache.org/pluto/
·onjava.com:onjava.com
·Matrix-Java开发者社?http://www.matrix.org.cn
Sunil Patil从事J2EE技术工作已?q_(d)他感兴趣的领域包括对象关pL工兗UI框架以及(qing)portals?
]]>
以下是本版本的重要变化:(x)
现有工具的功能提?/span>
资源库、作业和日程表都引入组的概c(din)可以由教师控制组讉K。系l原有的所见即所得文本编辑器也从
HTMLArea
改ؓ(f)功能更ؓ(f)强大?/span>
FCKeditor
。在q行内容~辑Ӟ可以方便地进入资源库q行选择q插入图片和
Flash
动画Qƈ可即时上传图片到资源库?/span>
与开源电(sh)子档案袋目深度l合
开源电(sh)子档案袋Q?/span>
OSP
Q是另一个重量的教育开源项目,同样获得
Mellon
基金?x)的资助。现在,
OSP
的开发已l完全与
Sakai
同步?jin),q成?/span>
Sakai
的一个备选工兗用档案袋工具Q学生可以收集、整理、反思自己在学习(fn)q程中完成的作业和作品,通过有组l的设计、编排然后发布到|上供老师?/span>
同学、家长以?qing)未来的雇主览。此举能学生多q的学业成就充分展示出来Q对教师深入?jin)解学生、学生提高自q自信?j)均大有好处。教师也可以利用档案袋整
理自q教学资源Q回、反思自q教学l历。让学生和学校能更好C(jin)解自q教学理念和教学状c(din)档案袋已经在教育领域得到充分的研究和应用,q次?/span>
Sakai
的结合?/span>
Sakai
目在功能上有极大的提升?/span>
大量备选工h成?/span>
?/span> Sakai 中除?jin)通知、作业、资源库{标准工具外q存在大量由各大学负责开发的备选工兗这些工具都可以投入实际q用。备选工L(fng)出现使得 Sakai 在功能上更加?/span> 富多栗?/span> Melete Lesson Builder 是其中非帔R要的一个。该工具?/span> Foothill 学院负责开发,可以让教师在U编辑自q?sh)子讲义q按照章节有序编排。编辑时q可方便地插 ?/span> Word ?/span> Powerpoint {文Ӟ也可插入视频、音频等多媒体文Ӟ导入、导出符?/span> IMS 标准的电(sh)子讲义也在D手之间。编辑器使用 FCKeditor Q类?/span> Word 的操作将使教师运用自如?/span> Jforum 是著名的 JAVA 开源论坛Y件。同L(fng) Foothill 学院引入 Sakai 中,?/span> 业强大的功能使得师生的在U交更加顺畅、舒适?/span> UFP 站点l计工具使得教师能随时了(jin)解学生的在线学习(fn)情况Q学生在评站点中的操作在眼底。其它备选工 兯包括与课E开攄l?/span> EDUCommons 的连接、与数字资源?/span> Fedora 的连接、自动批量发布学生成l和评语?/span> Post'em 、由剑桥大学开发的c?/span> ?/span> Google 的站内搜索引擎等{?/span>