首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 软件管理 > 软件架构设计 >

Portal兑现原理

2012-11-16 
Portal实现原理Portal实现原理1.Portal用例读者可以在下面三个网站上注册自己的用户,体会Portal的功能。htt

Portal实现原理
Portal实现原理

1.Portal用例
读者可以在下面三个网站上注册自己的用户,体会Portal的功能。
http://my.msn.com
http://my.yahoo.com
http://my.liferay.com

My MSN的功能最灵活强大,用户可以任意拖放操作栏目(column)和内容版块(content)的位置和个数。
My Liferay只能选择固定的栏目(column)布局,但可以在本栏目(column)内移动内容版块(content)的位置。
My Yahoo只能选择固定的栏目(column)布局,而且不能移动内容版块(content)的位置。

Portal的结构分为三层。
(1) Page
(2) Column,或者称为Pane
(3) Content,或者称为Portlet

我们来看看Portal的整个操作流程。
(1) 每个Column的下方都有一个[Add Content]按钮,让用户选择加入自己喜欢的内容。
从这里,我们知道,Portal系统里面有一个公用的Common Portlet Repository,供用户选用。

JSR168 Portlet规范里面定义了Portlet Deployment Discriptor。Common Portlet Repository以这个Portlet Deployment Discriptor的格式存放。

开源项目JetSpeed的XReg文件用来存放Common Portlet Repository的定义。

(2) 加入Content之后,用户的Page和Column里面就多了这个Content。下次用户登陆的时候,就会看到自己订制的Portal版面。
从这里,可以看出,Portal系统会纪录用户的个人Portal配置信息 – User Portal Config。

开源项目JetSpeed的PSML文件用来存放User Portal Config的定义。

------- 综上。
Add Content的整个流程为:
Common Portlet Repository --> Add Content --> Personal Portal Config

Display Portal的整个流程为:
从Personal Portal Config读取用户配置的Portlet ID --> 根据Portlet ID,从Common Portlet Repository查找详细的Portlet定义 --> 根据这个详细的Portlet定义显示这个Portlet。

2.Portal实现
我们考虑如何用Java来实现Portal。

2.1 Dynamic Include
首先,我们采用最简单的思路,我们用100个JSP文件(1.jsp, 2.jsp, 3.jsp, … 100.jsp等),代表100个Portlet。
用户页面MyPage.jsp包含用户选定的多个Portlet。
现在,假设用户选取的Portlet为1.jsp, 3.jsp, 7.jsp等3个Portlet,那么我们如何在MyPage.jsp中显示这些Portlet?最直观的做法是,用jsp:include。比如:
<table>
<tr><td>
<jsp:include page=”1.jsp” />
</td></tr>
<tr><td>
<jsp:include page=”3.jsp” />
</td></tr>
<tr><td>
<jsp:include page=”7.jsp” />
</td></tr>
</table>
由于<jsp:include>只能指定固定的jsp文件名,不能动态指定jsp文件名。我们需要把<jsp:include>翻译为Java code – RequestDispatcher.include();
下面我们换成这种写法。

<table><tr><td><% request.getRequestDispatcher(”1.jsp”).include(request, response); /></td></tr><tr><td><% request.getRequestDispatcher(”3.jsp”).include(request, response); /></td></tr><tr><td><% request.getRequestDispatcher(”7.jsp”).include(request, response); /></td></tr></table>

进一步改进MyPage.jsp。
<% String[] fileNames = {“1.jsp”, “3.jsp”, “7.jsp”}; %><table><% for(int i = 0; i < fileNames.length; i++) {  String fileName = fileName s[i]; %><tr><td><% request.getRequestDispatcher(fileName).include(request, response); /></td></tr><% } // end for %></table>

其中的fileNames的内容可以各种各样,只要RequestDispatcher能够处理。
比如Velocity,fileNames = {“1.vm”, “3.vm”, “7.vm”};
比如URL,fileNames = {“/portlet1.do”, “/portlet3.do”, “/portlet4.do”};
我们可以看到,如果我们从用户配置中读取fileNames的内容,这就是一个简单的Portal实现。
<% String[] fileNames = (String[])session.getAttribute(“portlets.config”); %><table><% for(int i = 0; i < fileNames.length; i++) {  String fileName = fileNames[i]; %><tr><td><% request.getRequestDispatcher(fileName).include(request, response); /></td></tr><% } // end for %></table>

2.2 Portlet Interface
下面我们来扩展这个例子。
假设每个Portlet都规定实现一个Portlet接口。
interface Portlet {  void render(request, response);};MyPage.jsp如下:<% String[] portletClassNames = (String[])session.getAttribute(“portlets.config”); %><table><% for(int i = 0; i < portletClassNames.length; i++) {  String className = portletClassNames[i];  Portlet portlet = (Portlet)Class.forName(className).newInstance(); %><tr><td><% portlet. render (request, response); /></td></tr><% } // end for %></table>Portlet类的示例代码如下:public class Portlet7{  public void render(request, response){    request.getRequestDispatcher(“7.jsp”).include(request, response);  }};

上述代码是Portal显示Portlet的核心流程的一个简化版本。
JSR168 Portlet规范里面定义了真正的Portlet接口定义。

2.3 Portlet Action
Portlet的操作包括,最大化/最小化/恢复/关闭/编辑/帮助/上下移动,等等。
这些操作都有对应的Action类。
开源项目JetSpeed的module/actions/controls目录下面包含Maximize, Minimize, Close等Action类。
开源项目Liferay的portal/action目录下面包含Maximize, Minimize, Close等Action类。

Portal的操作不仅包括上述Portlet的操作,而且包括其它更高级别的操作。
比如,Add/Move Page, Add/Move Column, 换Layout, 换Skin,之类。

2.4 Portlet Cache
我们操作Portlet的时候,往往只操作某个特定的Portlet,或者只是变化Portlet的位置。这时候,页面中大多数的Porlet的内容是不变的,只有一小块Portlet变化。
我们需要把Portlet的内容缓存起来。Portlet接口有一个render(request, response)方法,我们可以订制定制response类,截获portlet的输出,保存到Portal系统的内容Cache当中。
比如,前面提到liferay开源项目,其StringServletResponse类把Portlet的输出保存到一个String当中。<a href="http://demo.liferay.net/c/portal/layout?p_l_id=1&p_p_id=10&p_p_action=1&p_p_state=maximized&p_p_mode=view&_10_struts_action=%2Faddress_book%2Fedit_contact">Add Contact</a>

我们看到,这个URL明显是和Liferay Portal Server绑定在一起的。
(且不说/portal/layout这个URL片断,就是p_l_id,p_p_id,p_p_action等参数也是liferay自己定义的。)
只有Liferay Portal Server才知道这个URL的含义,其他的Portal Server根本无法处理这个URL。

我们假设这样的过程,Portal Server遇到不归自己解释的请求,就直接转发给自己管理的portlet,让portlet自己去处理这些请求。
我们可以看到,这种情况也无法通过。参数里面有p_p_state=maximized。
Portal Server需要知道这个最大化的请求,才能够正确地布局,隐藏其他Portlet,只显示着一个Portlet。这就要求Portal Server必须了解p_p_state=maximized的含义。

Portlet的通用性是如何定义和实现的?我看了几款商业Portal Platform的评估(前面的连接),Oracle, Sybase, Sun, IBM, BEA 等,好像Porlet可以在很多J2EE Portal Server之间通用,有些需要加入一定的代码,有些不需要。 6 楼 buaawhl 2004-08-25   flyisland 写道呵呵,好像对Portal感兴趣的不是很多。

其实你提到的是Portal展现的这一部分,关于这一部分我的看法要更加复杂,等忙过这一阵子我也写写自己的看法。

http://www.blogbus.com/blogbus/blog/diary.php?diaryid=204304
http://www.blogbus.com/blogbus/blog/diary.php?diaryid=117666
http://www-900.ibm.com/developerWorks/cn/webservices/ws-wsrp/index.shtml

thanks flyisland. :-) 7 楼 BlueDavy 2004-08-25   呵呵,不会少吧,现在Portal技术已经从前几年的迷糊中渐渐走入明朗
目前正在做门户产品前期的工作,Portal由于其涉及面非常的广,应用的技术也是杂多.......
Portlet规范的推出自然使得Portlet部分的工作变得更为简单,但Portal本身的难点还是挺多,如权限设计,页面布局
在页面布局部分现在的考虑是做了一个View层解析框架,使得MVC的层次结构更为的清晰,也使得系统的可理解性增强,象Turbine的View层分层解析机制虽然做的也挺好,不过其具有一定的复杂性
Portal对于Portlet Container的衔接同样是Portal技术的重要一环
还有就是Portal的CMS部分、性能缓存部分、导航部分等等 8 楼 buaawhl 2004-08-25   BlueDavy 写道呵呵,不会少吧,现在Portal技术已经从前几年的迷糊中渐渐走入明朗
目前正在做门户产品前期的工作,Portal由于其涉及面非常的广,应用的技术也是杂多.......
Portlet规范的推出自然使得Portlet部分的工作变得更为简单,但Portal本身的难点还是挺多,如权限设计,页面布局
在页面布局部分现在的考虑是做了一个View层解析框架,使得MVC的层次结构更为的清晰,也使得系统的可理解性增强,象Turbine的View层分层解析机制虽然做的也挺好,不过其具有一定的复杂性
Portal对于Portlet Container的衔接同样是Portal技术的重要一环
还有就是Portal的CMS部分、性能缓存部分、导航部分等等

看了BlueDavy的Blog,你是使用Turbine控制页面布局吗?
我对Turbine只有一点了解,知道JetSpeed使用Turbine。

你提到了Portal的CMS部分,应该属于Portal的一个CMS Portlet吗?
我看了一些资料,很多Portal Platform提供了现成的Forum Portlet。
另外,导航部分是指哪部分?

:-) 看来应用、研究、实现Portal的程序员还是大有人在的。
我想把本论坛中的一些想实现Portal或已经实现Portal的帖子引用在下面。

magicgod 写道当然可以,我就做过一个,简单地jsp做的一个很简单实用的protal,页面单元的拖拉放,允许自定义栏目.
原来在netscape看过,不过它太复杂了,我总共就用了两个jsp,加上一个管理页面jsp,纯jsp实现,非常简单,曾经被省政府作为亮点,哈哈,看来技术不在复杂,而在应用啊.

但其余的帖子一时还搜不到,记得 冰云 在某个帖子里提到有实现这个大轮子的想法。 9 楼 buaawhl 2004-08-25   sayor 写道最近,我们组也要做一个Portal相关的东西,有问题可以和你们讨论一下。

Sayor应该是用Oracle 10G开发Portal吧。
我前面给出的连接。

Enterprise Portals Suites
Portal Power
http://www.networkcomputing.com/shared/article/printFullArticle.jhtml?articleID=18900467

这个评测根据该组织自己的使用经验,把Oracle Portal排在第一位。易用性,速度都不错。美中不足的是一些Portlet是用PL SQL写的。

Sayor有了第一手应用的经验,多交流交流。 10 楼 冰云 2004-08-25   buaawhl 写道
你提到了Portal的CMS部分,应该属于Portal的一个CMS Portlet吗?
我看了一些资料,很多Portal Platform提供了现成的Forum Portlet。

记得 冰云 在某个帖子里提到有实现这个大轮子的想法。

嘿嘿,我是有说。不过人手不够实现不了。
想想觉得实现一个简单可用的Portal感觉并不难。
我的理想是实现一个基于webstandards的portal
把界面的部分展现功能交由CSS来实现。

相当于:
Page -&gt; Skin -&gt; Panel -&gt; Portlet

另外属于Portal的一个CMS Portlet这种说法我觉得不准
应该说是属于CMS的一个CMS Portlet。

我考虑实现JSR170-JCR,然后再JCR的基础上建立一套CMS
例如ForumPortlet,实质是调用了JCR的一些存取检索方法
也就是说,JCR是相当于在Persistence和Business之间的一个隔离层 11 楼 BlueDavy 2004-08-26   呵呵,怎么说呢
我倒觉得你可以把CMS作为一个大的CMS Portlet去考虑,但Portal是支持嵌入的,基本上来说只要你把一个现成的CMS系统放进去就OK了
页面布局我现在用的是Turbine,由于公司的限制吧,不过在即将进行的Portal产品中不会采用,会偏向采用目前自己开发的一个View层解析框架,View层解析按照Page--&gt;Layout--&gt;Portlet的概念进行解析,而Portlet部分则交由Portlet容器部分处理
至于导航部分指的主要是页面的导航栏部分的控制,页面中各部分导航信息的控制,在Exo新的版本中它将这部分对于JSR168进行了扩展,提出了导航这部分,感觉设计挺合理的,值得学习
其实我觉得Portal从划分上来讲可以比较明确的划分为:
1. MVC框架
2. 服务框架
3. Domain Model 层
4. View层解析框架
5. Portal与Portlet Container的衔接层
6. Portlet Container层
7. 公共拦截器层,主要用于处理系统的缓存、校验等等
   部分

在我现在实际的项目中,还发现比较需要一个支持中断机制的事件处理框架,意思也就是我有一个事件队列需要执行,但执行到其中某个的时候需要返回Web界面获取一些数据,待用户提交后接着之前的队列执行,不知道大家对于这个有没有什么好的想法呢? 12 楼 Sayor 2004-08-26   oracle的portal主要由三个元素组成: page group, provider, data objects. 这三个元素分别构成portal应用的表示层,数据获取层和数据层。 provider 就是获取数据的程序,可以是pl sql,也可以是java程序。 而portlet并非是pl/sql写的,它只是表示了一个特定的页面,这个页面的结构和内容都保存在数据库表中,在需要的时候,动态产生该页面。 这两天,我们公司正好有portal 的培训,我只听了一课,然后就回上海了,可惜了。不过回公司后可以向同事们请教 13 楼 buaawhl 2004-08-27   BlueDavy 写道
至于导航部分指的主要是页面的导航栏部分的控制,页面中各部分导航信息的控制,在Exo新的版本中它将这部分对于JSR168进行了扩展,提出了导航这部分,感觉设计挺合理的,值得学习

多谢提供这个信息,有时间我也要研究一下Exo的导航功能。

BlueDavy 写道
页面布局我现在用的是Turbine,由于公司的限制吧,不过在即将进行的Portal产品中不会采用,会偏向采用目前自己开发的一个View层解析框架,View层解析按照Page--&gt;Layout--&gt;Portlet的概念进行解析,而Portlet部分则交由Portlet容器部分处理


冰云 写道
想想觉得实现一个简单可用的Portal感觉并不难。
我的理想是实现一个基于webstandards的portal
把界面的部分展现功能交由CSS来实现。

相当于:
Page -&gt; Skin -&gt; Panel -&gt; Portlet


展现部分,大家都提到 Page --&gt; Layout, Skin --&gt; (Panel) --&gt; Portlet的过程。下面给出我的理解。
Layout是一个包含TagLib(如Tiles等) 的一个框架JSP文件。
Skin是一些CSS文件,和一些颜色参数定义文件。
Panel 也应该是由对应的TagLib定义的(如JetSpeed:pane)。
Portlet就是一个Portlet接口实现类,和对应的模板文件组成(这个模板的类型限制就不那么严格了。JSP, Velocity, XSL都行)。
我上面的理解对不对?

我希望弄清楚地是,Layout这个代表Page的总体框架模板是否必须由JSP + TagLib来定义?
据我所知,JetSpeed, eXo, Liferay都是如此。而且似乎必须如此,别无他法。

但我不知道基于Cocoon的Portal是什么情况。
因为我不知道什么技术,能够让XSL模板引入其它的XML文件。
(XSL里面有一个Document命令,能够引入另外一个XML文件。但Portal需要动态引入动态内容,Document命令不适合) 14 楼 BlueDavy 2004-08-27   我觉得其实View层分层解析就是一个典型的OO的应用,将页面的View层按其共性抽出了诸如Layout、Skin、Portlet几类对象,各对象负责一个较为独立的功能,自然也就使得View层的改动尽量小的影响到彼此
这个最早好像就是由Turbine提出的
View层解析的好坏以及其简便操作的程度很大程度上影响到一个Portal的质量
另外一个应该就是Portal的权限系统,而且Portal的另外一个关键点在于允许别人能够轻易的剥离或替代其中的层次,如权限系统,象之前Turbine的权限系统要剥离真的是有些的难度 15 楼 stone 2006-09-26   谈portal还是应该从jsr168和jsr286谈起吧,我更关心portal规范的发展

热点排行