Portlet 2.0新特性介绍

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

Portlet 2.0新特性介绍
本系列文章专门针对具有JSR 168 Portlet开发基础,并且想了解JSR 286 Portlet新特性和开发流程的开发人员。

在学习完本系列后,您将了解相对于JSR 168 Portlet,JSR 286 Portlet 究竟提供了哪些增强功能,以及这些新增特性在实际开发中的应用。

第1 部分将简单回顾JSR 168 Portlet,并列出了JSR 286 Portlet的新增内容。

第2 部分和第3 部分将通过在Apache Pluto 2.0 平台上开发和部署Portlet应用程序,向读者介绍JSR 286 Portlet新特性的使用方法。

Portlet是部署在容器内用来生成动态内容的Web 组件,与servlet 类似,portlet的整个生命周期从init到destroy 的过程都在portlet容器中进行。

Java Portlet Specification 对portlet API、标准化用户数据、参数设置、portlet请求以及响应、部署、打包以及安全等方面都做了详细的规定,以此来实现portlet之间以及portlet与portlet容器之间的交互和协作。

Java Portlet Specification 1.0, 即Java Specification Request(JSR)168 发布于2003 年10 月。

JSR 286 及其新特性
JSR 168 目前在业界受到广泛支持,而且它由开放源码支持。

标准和产品的第一个版本存在一定的缺陷,仅支持最基本的用例,在功能上有一些限制。

而且Java Portlet Specification V1.0 也存在这种情况,因此,经过三年之后,大多数支持Java Portlet Specification V1.0 的门户产品都提供一些附加扩展,以支持更高级的用例,这些附加的扩展造成了各个门户产品的标准不统一,彼此间的交互协作成了不可避免的问题。

为了更好地规范portlet开发,以适应业界发展,并提供适应于最高级别用例的标准解决方案,从而为这些高级功能提供互操作性,在2005 年11 月开始了Java Portlet Specification V2.0(称为JSR 286)的开发,Java Portlet Specification V2.0 目前已经进入Final draft 的等待审批阶段,并计划在2008 年3 月正式发布。

JSR 286 最终草案兼容了JSR 168 ,并完善了JSR 168 的部分功能,并提供了诸多JSR 168 所没有的新特性,例如资源服务、事件、portlet过滤器、共享呈现参数及portlet窗口等。

与V1.0 类似,V2.0 也将基于J2EE 1.4,因此可让Portlet使用J2EE 1.4 增强(如JSP 2.0)。

下面是该新规范的一些主要功能及特性:
资源服务:一种新的通过portlet呈现资源的方式。

事件:通过发送事件和接收事件来实现portlet之间的通信。

Portlet过滤器:与servlet 过滤器类似,根据Portlet请求和响应动态的呈现内容的变换。

存在以下四种类型的portlet过滤器:
Action 过滤器
Render 过滤器
Resource 过滤器
Event 过滤器
共享呈现参数:除了portlet私有的呈现参数之外,新增了可以在portlet之间共享的呈现参数。

Portlet窗口:提供portlet窗口ID 供portlet使用。

下面我们将对JSR 286 所提供的这些新功能及其使用逐一做详细介绍。

资源服务
在JSR 168 中,Portlet服务于资源的方法只有两种:直接链接到资源,或者通过Portlet服务于资源。

两种方法分别适用于不同目的的需要,各有优缺点。

直接链接对于所有Portlet状态都相同的静态资源非常有效,但对于其他用例效果却不太好,因为需要考虑来自Portlet上下文的信息。

这样的示例包括基于Portlet模式、窗口状态、当前呈现参数或Portlet首选项呈现不同资源。

以一个JSP 文件test.jsp为例,如果要访问该资源,可以直接通过超链接访问该文件,如清单1 所示:
清单 1. 直接访问资源文件
<a href="<c:url value="/test.jsp"/>">test.jsp</a>
或者通过Servlet 转向,如清单2 和清单3 所示:
清单 2. 直接访问Servlet
<a href="<c:url value="/testServlet"/>">testServlet</a>
清单 3. Servlet 对资源文件的访问控制
public void service(ServletRequest request,ServletResponse response) throws ServletException,IOException{
...
在此添加访问控制等业务逻辑代码
...
RequestDispatcher rd=request.getRequestDispatcher("/WEB-INF/jsp/test.jsp");
rd.forward(request,response); //或者为rd.include(request,response);
}
从清单1、2、3 可以看到,直接链接到资源这种方式,无法访问到相关Portlet的信息,包括Portlet模式、窗口状态、当前呈现参数或Portlet首选项等。

而通过Portlet呈现资源的优势是可以通过门户访问资源,因此可以通过控制门户访问而对资源提供保护。

但是,这也带来了额外的门户请求开销,加重了门户服务器的负载。

为了更好的解决这两种方法的局限性,JSR 286 采用了一种新的资源服务方式——Portlet资源服务。

即JSR 286 引入了一个新的具有serveResource方法的可选生命周期接口ResourceServingPortlet,该接口可以由ResourceURL触发,Portlet可以通过PortletResponse.createResourceURL方法创建它。

资源URL 包含当前Portlet的瞬时状态(Portlet模式、窗口状态和呈现参数),但不能为此状态设置新值。

资源URL 可以有在资源URL 上设置的其他资源参数。

通过调用ResourceServingPortlet接口的serveResource() 方法,Portlet不仅可以通过控制门户访问而对资源进行保护,并且Portlet容器不会呈现任何除serveResource() 方法返回的内容之外的附加输出。

这样,用户由于可以直接通过操作响应对象而被赋予了更多的控制权限,并且没有额外门户请求的开销,减轻了门户服务的负载。

而Portal 服务器此时只是充当了一个代理服务器的作用。

JSR 286 资源服务的使用方法:
Portlet类需实现javax.portlet.Portlet和javax.portlet.ResourceServingPortlet接口并实现serveResource() 方法,如清单4 所示:
清单 4. Portlet对资源文件的访问控制
public class TestPortlet implements Portlet,ResourceServingPortlet
{
......
public void serveResource(ResourceRequest resourceRequest,
ResourceResponse resourceResponse)throws PortletException,
IOException{
...
在此添加访问控制等业务逻辑代码
...
PortletRequestDispatcher portletRequestDispatcher=portletConfig
.getPortletContext().getRequestDispatcher(
"/WEB- INF/jsp/TestPortletResource.jsp");
portletRequestDispatcher.include(resourceRequest,resourceResponse);
}
......
}
使用JSP 标签通过PortletResponse.createResourceURL方法创建RecourceURL:
清单 5. 创建资源访问URL
<a href="<portlet:resourceURL/>">Click me to request Resource URL</a>
所保护的访问资源,在此例中即为TestPortletResource.jsp。

<>
接下来,我们就可以充分体验JSR 286 资源服务新特性所带来的简单便捷以及高性能了。

对照该介绍,读者可参照本系列第2 部分对资源服务特性的实例开发加深对该部分相关内容的理解。

事件
JSR 286 定义的事件模型是一种松耦合的代理事件模型。

在此模型中,Portlet定义可以接收以及在Portlet部署描述符中公布的事件。

在运行时,门户管理员(或业务用户)可以将不同的Portlet连接在一起。

Portlet事件服务并不是一个可信任消息服务(例如JMS)的替代。

很多情况下Portlet事件并不能总是保证能够传送到目的地。

因此Portlet必须能够在部分或即使所有事件都不能正确接收的情况下仍然能够工作。

另外,有的时候Portlet为了响应某一个事件,也会向另外的Portlet发布新的事件,这样就形成了事件的衍生代。

这在一定程度上可能造成事件的死锁,JSR 286 本身没有对衍生代做出限制,但是很多Portlet容器会定义事件的最大衍生代以防止死锁的发生。

读者在开发相关应用时请注意其本身的限制。

对于一个事件的声明有两点需要注意:事件的名称和值的类型。

对于事件名称,JSR 286 既可以为事件定义默认的命名空间,其作用域为所有未声明QName的事件;也可以为事件单独定义自己的QName。

对于QName和命名空间的理解,请读者参考XML 规范的相关文档,本文不做详细介绍。

对于事件值的类型,既可以是简单的Java 对象,例如Integer,String 等,也可以是预先定义的Java 复杂对象,但是前提是该对象必须实现Serializable接口。

其中<event-definition>的具体格式如清单7 和清单8 所示:
清单7. 默认命名空间下事件定义声明
<default-namespace>/</default- namespace>
......
<event-definition>
<name>event-with-simple-value</name>
<value-type>ng.String</value-type>
</event-definition>
<event- definition>
<name>event-with-complex-value</name>
<value- type>com.ibm.jsr286.TestEventBean</value-type>
</event-definition>
清单8. 自定义QName下事件定义声明
<event-definition>
<qname xmlns:key="">event-with- simple-value</qname>
<value-type>ng.Integer</value-type>
</event- definition>
<event-definition>
<qname xmlns:key="">event-with- qname</qname>
<value-type>com.ibm.jsr286..TestEventBean</value-type>
</event- definition>
事件发布载体声明:事件的发布载体声明需要在portlet.xml 的<portlet>元素中用<supported-publishing-event>关键字。

对应事件声明格式,事件发布载体Portlet声明亦有默认命名空间和自定义命名空间以及简单对象和复杂对象的情况,见示例:
清单9. 默认命名空间下事件发布声明
<supported-publishing- event>
<name>event-with-simple-value</name>
</supported-publishing-event>
<supported-publishing-event>
<name>event-with-complex-value</name>
</supported- publishing-event>
清单10. 自定义QName下事件发布声明
<supported-publishing-event>
<qname xmlns:key="">event-with-simple-value</qname>
</supported-publishing- event>
<supported-publishing-event>
<qname xmlns:key="">event-with -complex-value</qname>
</supported-publishing-event>
事件接收载体声明与事件发布载体声明类似,事件的接收载体声明需要在portlet.xml 的<portlet>元素中用<supported-processing-event>关键字。

见示例清单11 和清单12:
清单11. 默认命名空间下事件接收载体声明
<supported-processing-event>
<name>event-with-simple-value</name>
</supported-processing-event>
<supported- processing-event>
<name>event-with-complex-value</name>
</supported-processing- event>
清单12: 自定义QName下事件接收载体声明
<supported-processing-event>
<qname xmlns:key="">event-with-simple-value</qname> </supported-processing- event>
<supported-processing-event>
<qname xmlns:key="">event-with -complex-value</qname> </supported-processing-event>
文章由重庆达内编辑整理,更多内容详情请咨询。

相关文档
最新文档