NCV5Portlal技术红皮书Word文件下载.docx
《NCV5Portlal技术红皮书Word文件下载.docx》由会员分享,可在线阅读,更多相关《NCV5Portlal技术红皮书Word文件下载.docx(39页珍藏版)》请在冰点文库上搜索。
2.1用户资料来源20
2.2单点集成21
3.开发流程22
3.1IUserProvider的方法介绍23
3.2IWebAppLoginService接口的方法介绍23
3.3系统配置过程24
4.集成实例附录27
4.1与IUFO的集成27
4.2与BO的集成28
附录30
1.引用的技术文档30
第一章前言
1.什么是Portal
许多企业和组织需要为企业内部员工、外部客户群体量身定制有“价值”的企业信息,但是,一方面是好些有“价值”的企业信息获取并不是一件轻松的事情,信息部门需要整合来自不同的应用系统,不同数据源,不同平台的无数各种类型的数据和资源;
另一方面,如何轻松实现一个为所有的用户群体量身定制的系统构架也不是一件容易的事情。
传统技术整合这些资源的技术复杂度和成本都太高,许多企业无法负担如此的投入。
Portal技术的出现,带给人们解决这类难题的曙光。
Portal技术强调以用户为中心,提供个性化、单点登录、不同来源的内容整合功能,从而实现了信息的集中访问。
Portal从本质上来说就是一个内容聚集的平台。
2.NCPortal的简介
NCPortal是基于JSR168规范而实现的一套J2EE技术体系架构的Portal。
它构建于NC基础服务与NCRichClient基础组件之上,完美融合ajax技术与SpringMVC技术,提供了灵活而丰富的个性化和管理定制功能。
NCPortal允许多种安全认证方式和自选第三方系统用户来源,采取了基于角色访问控制(RBAC)的权限模型。
并提供了完善和通用的第三方系统集成框架和单点登录框架,NCPortal发版默认集成NC、IUFO、BO、自定义查询报表应用,实施SSO比商业Portal简单易用。
它提供的Portal管理功能,允许管理员在运行态对Portal进行定制,而无需重启甚至编码。
同时,内建的换肤机制使得实现自定义皮肤非常简单,只需完成相应图片的替换即可。
NCPortal提供了引入了一些通用的API,使得Portlet可轻松调用Ajax,json,以及使用NCRichClient组件。
第二章NCPortal容器
1.
NCPortal框架图
2.NCPortal的界面用语
在NCPortal中,每一个Tab控件页签对应着一个布局定义。
布局即一个tab页内容的
描述,它由多个列构成,每个列又由Portlets组成。
布局可由管理员动态定制,并可在运行时修改。
布局可嵌套布局,从而组成相对复杂的界面。
一个布局中的portlet不能重复。
布局和Portlet的访问控制,是由基于角色的权限控制模型定义的。
因此,管理员可在运行时,通过Portal管理Portlet,对各种资源进行安全管理。
3.NCPortal页面展现序列图
在NCPortal中,Portlet的展现是一个异步的过程。
因此一定要注意多个ajax异步请求操作潜在的对session的并发访问问题。
同时,NCPortal也提供了对Portlet内容的缓存方案(兼容JSR168规范),可设置全局缓存(针对所有用户一致的内容),按用户缓存(不同用户看到不同的内容),及细粒度的按状态缓存(比如只缓存视图状态而不缓存编辑状态)。
部署Portlet时可按照需要设置缓存,从而有效提高页面展现速度,减少对服务器端的压力。
4.NCPortal目录结构
5.NCPortal管理与应用
Portal数据源设置
Portal采用NC的数据源配置,只需在ierp/portal/portal.properties中配置对应NC的数据源名即可。
NCPortal开发环境配置
NCPortal的开发环境即NC5.0的开发环境,请参考相应文档。
6.Portal及Portlet的国际化
Portal容器及内置Portlet的多语化是基于NC的多语机制,并符合JSR168规范。
二次开发的Portlet需参照规范的方式实现自定义ResourceBundle,或者直接使用NCPortal的通用多语言资源绑定类,SpringResourceBundle。
有关NC的国际化机制请参考相应的文档。
这里需要提出的是,NCPortal针对JSP页面,封装了简单的多语化EL表达式,可直接在页面中调用${ml:
trans(‘keytotranslate’)}即可,java类中可直接调用LanguageUtil工具类中的相应方法进行。
1.NCPortal页面中一些工具类和预置对象。
SerurityUtil类是一个安全相关类。
可直接从此类中提取和用户有关的信息及权限信息。
StringPool类提供了常用的字符串常量定义。
GetterUtil类提供了相应的字符串操作方法。
ParamUtil提供了提取Http请求参数的工具方法。
每个页面中都包含了一个ThemeDisplay的实例,此实例是请求级别的,可从此实例中获得大多数当前请求信息。
具体每个类的操作方式请参考类自身定义和javadoc。
第三章Portlet开发
1.Portlet的介绍
一个Portlet就是一个独立的web应用。
它通过Portlet容器与Portal服务打交道。
从本质上来说,它是一个网页内容片段,众多portlet通过portal页面组织在一起而形成一个完整的页面。
因此,只要符合JSR168规范,这个Portlet就可以享受到所有符合此规范的Portal容器所带来的服务与功能。
对于一个Portlet,区分为多种状态(state)和多种模式(mode)。
在NCPortal中,支持Portlet的最大化(Maximized),最小化(Mininized)和正常(Normal)状态,以及支持视图(View),编辑(Edit)和帮助(Help)三种模式。
当然,一个Portlet具体拥有的模式和状态是通过配置而从这里面选取的子集。
完整的Portlet的定义请参阅JSR168规范的文档。
2.NCPortal的内置Portlet
2.1Portal管理Portlet
Portal管理Portlet提供了Portal容器的管理功能。
包括用户管理,角色管理,资源管理,布局定义等功能节点。
此Portlet利用了NCRichClient控件的灵活特性,使NCPortal可在运行时完成个性定制而无须重启服务器和重新编码。
2.2CMS管理Portlet
CMS管理Portlet提供了几个常用的Portlet,包括新闻管理,论坛管理,公司发文管理,公告管理及连接管理等。
新闻管理和连接管理提供了比较灵活的功能,配合其它Portlet可快速构建网页内容。
关于内容管理Portlet的使用,请参考NCPortal的用户使用文档。
2.3IframePortlet
IFramePortlet是一通用简单集成Portlet,既可用于用户个性化定制时引入外部网站的工具,也可用于管理员的静态定义。
此Portlet的使用可参考3.4小节。
2.4RssPortlet
RssPortlet是读取RSS站点内容的通用Portlet。
此Portlet的使用请参考用户使用文档。
需要注意的是,此Portlet在使用过程中可能会遇到浏览器的权限问题,这个问题可通过配置后台代理解决。
具体方式是在ierp/portal/system.properties中设置portal.rss.mode=1。
如果需要代理,可设置
#httpproxy
portal.proxy.host=
#httpproxyport
portal.proxy.port=
#httpproxyuser
portal.proxy.username=
#httpproxypassword
portal.proxy.password=
#httpproxydomain
portal.proxy.domain=
3.Portlet的开发实例
一个Portlet的开发,通常来说要走下面几步:
(1)按照规范实现javax.portlet.Portlet接口。
(2)编写相关的页面文件(任何Portal容器支持的视图技术)。
(3)在配置文件portlet.xml中配置此Portlet。
如果Portlet相对较复杂,可能还会选择不同的持久化技术(Hibernate,ibatis,jdo等),以及不同的mvc框架和视图框架的组合(sprint,struts,jsf,tapestry等)。
NCPortal针对基于JSP,JSF和基于springmvc技术的Portlet开发实现了一套基类。
大多数情况下无需重新实现Portlet接口,只需进行相关的流程类的编写即可。
在整个Portlet的编写过程中,我们推荐的组合是NCJdbcFramework(持久层)+NCIOC+springmvc+jsp技术(请参阅相应的文档)。
通过我们的开发环境以及NCPortal的内置支持,这种看似复杂的组合实现起来就比较简单了。
NCPortal为多种模版技术的Portlet开发提供了内置支持,并抽象出了相应的基类。
大大简化了Portlet的开发难度。
下面以几个简单的Portlet作为样例:
3.1基于JSP视图技术的Portlet的开发
JSPPortlet适用于业务流程简单,只作简单展现的Portlet。
以一个具有view和edit状态的简单Portlet为例。
我们可以直接采用NCPortal提供的JspPortlet作为Portlet接口的实现类。
针对各种状态,我们需要写出相应的JSP页。
首先建立视图状态下的jsp页面,helloworldview.jsp,内容如下:
<
%@includefile="
/html/common/init.jsp"
%>
portlet:
defineObjects/>
divstyle="
width:
100%;
height=200"
class="
portletframe_gradual"
>
<
center>
Hello,thisportletisinviewmode!
/center>
/div>
其中<
为NCPortal提供的常用Tag和类引用的定义。
推荐使用。
是JSR168规范要求的变量声明定义。
它将把renderRequest,renderResponse,及PortletConfig放置在此Page中,以供引用。
剩下的内容就是一个普通的html所具有的内容。
其中需要注意四点:
1.此部分内容只是一内容片段。
不能包含<
html>
body>
/body>
/html>
等信息。
2.推荐以<
div>
包裹整个内容片段。
这样可更清晰的区分整个Portlet内容的结构。
3.虽然基于jsp技术,但Portlet内容体不推荐使用request,response和session等区域变量。
应代之以renderRequest,renderResponse,portletSession等在<
中定义的页面变量。
4.页面允许script语法。
但是推荐放置于<
之外,如
…
script>
/script>
下面同理,建立一个helloworldedit.jsp,内容如下
这样就完成了Portlet两个状态页的定义。
下面需要在Portlet的定义文件WEB-INF/conf/portlet.xml中配置此Portlet.
在WEB-INF\conf\portlet.xml中,我们添加HelloworldPortlet的定义,此Portlet的
定义文件由JSR168规范定义
portlet>
<
description>
HelloworldPortlet<
/description>
portlet-name>
HelloworldPortlet<
/portlet-name>
//注意不能和已有的重复
display-name>
HelloworldPortlet<
/display-name>
init-param>
<
name>
view-jsp<
/name>
//指明View模式下的jsp页面
value>
/html/portlets/helloworld/helloworldview.jsp<
/value>
/init-param>
edit-jsp<
//指明Edit模式下的jsp页面
/html/portlets/helloworld/helloworldedit.jsp<
//是否需要Portlet外边框。
(推荐)
decorator<
true<
portlet-class>
nc.bs.portlet.JspPortlet<
/portlet-class>
//Portlet实现类。
统一使用此类
expiration-cache>
0<
/expiration-cache>
//是否启用缓存-1,永不过期。
0,不启用,>
0的数字,以分钟为单位指明缓存失效时间
supports>
//在html展现方案中支持集中模式。
此处支持view,edit
mime-type>
text/html<
/mime-type>
portlet-mode>
view<
/portlet-mode>
edit<
/supports>
supported-locale>
EN<
/supported-locale>
//支持的语言种类
resource-bundle>
nc.bs.portlet.SpringResourceBundle<
/resource-bundle>
//对应的多语言资源类,如果使用NC多语言机制,统一使用此类
portlet-info>
//Portlet其它信息定义
title>
HelloworldPortlet<
/title>
short-title>
Helloworld<
/short-title>
keywords>
hello,world<
/keywords>
/portlet-info>
portlet-preferences>
//Portlet可能会用到的属性定义
!
--<
preferences-validator>
<
/preferences-validator>
-->
/portlet-preferences>
security-role-ref>
role-name>
ROLE_ADMIN<
/role-name>
/security-role-ref>
/portlet>
定义完毕Portlet,我们还需要在Portlet的分类定义文件中定义此Portlet。
在WEB-INF/conf/display.xml中,在某一个category下,加上一条:
portletid="
HelloworldPortlet"
dynamic="
true"
/>
到此,Portlet的开发与定义完成。
重启服务器。
打开Portal页面,可以在个人设置或者Portal管理->
布局管理中添加此Portlet。
3.2基于SpringMVC框架的Portlet开发
Springmvc框架小巧,灵活,稳定,不会像其它MVC框架一样将流程绑的太死,这也是笔者推荐它的主要原因。
关于SpringMVC的使用,请参考Spring相关技术文档。
当然,在NCPortal中使用其它框架也是允许的。
此处仅介绍springmvc在NCPortal中的配置与应该注意的地方。
NCPortal针对SpringMVC提供了ActionPortlet的实现。
与JspPortlet相似,基于此Portlet的开发仅需要开发相应的页面流程即可。
下面以自定义链接Portlet作为样例,具体需求是这样的:
用户可在编辑模式下增加自己需要的链接地址,在视图模式下按照列表形式显示所
有链接。
我们按照下面的次序完成此Portlet:
a.建表并编写对应VO类。
createtablepub_mylink(pk_mylinkchar(20)primarykey,namevarchar(20)notnull,urlvarchar(100)notnull)
对应MylinkVO.java
packagenc.portlet.mylinks;
importnc.jdbc.framework.orm.IPersistenceObject;
importnc.vo.pub.portal.base.ValueObject;
publicclassMylinkVOimplementsValueObject,IPersistenceObject{
privateStringpk_mylink;
privateStringname;
privateStringurl;
publicStringgetPrimaryKey(){
return"
pk_mylink"
;
}
publicStringgetTableName(){
pub_mylink"
publicStringgetName(){
returnname;
publicvoidsetName(Stringname){
this.name=name;
publicStringgetPk_mylink(){
returnpk_mylink;
publicvoidsetPk_mylink(Stringpk_mylink){
this.pk_mylink=pk_mylink;
publicStringgetUrl(){
returnurl;
publicvoidsetUrl(Stringurl){
this.url=url;
b.编写BS接口类及实现。
查询服务接口ImylinkQueryService
importnc.vo.pub.BusinessException;
publicinterfaceIMylinkQueryService{
publicMylinkVO[]getAllLinks(StringuserId)throwsBusinessException;
插入服务接口IMylinkService
publicinterfaceIMylinkService{
publicStringinsertMylinkVO(MylinkVOvo)throwsBusinessException;
编写对应ActionUrl的处理类
importjavax.portlet.ActionRequest;
importjavax.portlet.ActionResponse;
importmon.NCLocator;
importmon.PortletBaseAction;
importnc.vo.pub.portal.exception.ServiceException;
publicclassMylinkEditAction_NextendsPortletBaseAction{
publicvoidprocessAction(ActionRequestreq,ActionResponseres)
throwsServiceException,Exception{
Stringname=req.getParameter("
name"
);
Stringurl=req.getParameter("
url"
MylinkVOvo=newMylinkVO();
vo.setName(name);