JSR 286 Portlet 的新特性,第 1 部分: Portlet 2.0 新特性介绍

JSR268门户标准 java门户标准,jsr168规范,jsr268规范,java门户标准,jsr168规范,jsr268规范 立即下载

关于本文

本文假定读者熟知 JSR 168 Portlet,并对 J2EE 基本常识有一定了解。本文主要以理论的方式向读者介绍 JSR 286 Portlet 的以下新增特性:

  • 资源服务
  • 事件
  • 共享呈现参数
  • Portlet 过滤器
  • Portlet 窗口

Portlet 和 JSR 168

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)。下面是该新规范的一些主要功能及特性:

  1. 资源服务:一种新的通过 portlet 呈现资源的方式。
  2. 事件:通过发送事件和接收事件来实现 portlet 之间的通信。
  3. Portlet 过滤器:与 servlet 过滤器类似,根据 Portlet 请求和响应动态的呈现内容的变换。存在以下四种类型的 portlet 过滤器:
    • Action 过滤器
    • Render 过滤器
    • Resource 过滤器
    • Event 过滤器
  4. 共享呈现参数:除了 portlet 私有的呈现参数之外,新增了可以在 portlet 之间共享的呈现参数。
  5. 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 资源服务的使用方法:

  1. 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);
        }
        ......
    }
    
  2. 使用 JSP 标签通过 PortletResponse.createResourceURL 方法创建 RecourceURL: 清单 5. 创建资源访问 URL
                            
    <a href="<portlet:resourceURL/>">Click me to request Resource URL</a>
    
  3. 所保护的访问资源,在此例中即为 TestPortletResource.jsp 。

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

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

事件

JSR 286 定义的事件模型是一种松耦合的代理事件模型。在此模型中,Portlet 定义可以接收以及在 Portlet 部署描述符中公布的事件。在运行时,门户管理员(或业务用户)可以将不同的 Portlet 连接在一起。

Portlet 事件服务并不是一个可信任消息服务(例如 JMS)的替代。很多情况下 Portlet 事件并不能总是保证能够传送到目的地。因此 Portlet 必须能够在部分或即使所有事件都不能正确接收的情况下仍然能够工作。

另外,有的时候 Portlet 为了响应某一个事件,也会向另外的 Portlet 发布新的事件,这样就形成了事件的衍生代。这在一定程度上可能造成事件的死锁,JSR 286 本身没有对衍生代做出限制,但是很多 Portlet 容器会定义事件的最大衍生代以防止死锁的发生。读者在开发相关应用时请注意其本身的限制。

事件声明

对于一个事件的声明包括三个部分,分别是事件的定义声明、事件的发布载体声明也就是发布该事件的 Portlet 声明、事件接收载体的 Portlet 声明。

  • 事件定义声明:我们需要在 portlet.xml 中使用 <event-definition> 元素对事件进行声明,并且该元素与 <portlet> 元素并列作为 <portlent-app> 的子元素。 清单 6. event-definition 声明
                            
    <portlet-app id="myPortletApp" version="2.0">
    	<portlet>
    	...
    	</portlet> 
    	<event-definition> . . .</event-definition>
    	...
    </portlet-app>
    

    对于一个事件的声明有两点需要注意:事件的名称和值的类型。对于事件名称,JSR 286 既可以为事件定义默认的命名空间,其作用域为所有未声明 QName 的事件;也可以为事件单独定义自己的 QName。对于 QName 和命名空间的理解,请读者参考 XML 规范的相关文档,本文不做详细介绍。对于事件值的类型,既可以是简单的 Java 对象,例如 Integer,String 等,也可以是预先定义的 Java 复杂对象,但是前提是该对象必须实现 Serializable 接口。其中 <event-definition> 的具体格式如 清单 7 和 清单 8 所示:

    清单 7. 默认命名空间下事件定义声明
                            
    <default-namespace>http://cn.ibm.com/</default-namespace>
    ......
    <event-definition>
        <name>event-with-simple-value</name>
        <value-type>java.lang.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="http://www.ibm.com">event-with-simple-value</qname>
        <value-type>java.lang.Integer</value-type>
    </event-definition>
    
    <event-definition>   
        <qname xmlns:key="http://www.ibm.com">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="http://www.ibm.com">event-with-simple-value</qname>
    </supported-publishing-event>   
    
    <supported-publishing-event>
        <qname xmlns:key="http://www.ibm.com">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="http://www.ibm.com">event-with-simple-value</qname>
    </supported-processing-event>
    
    <supported-processing-event> 
        <qname xmlns:key="http://www.ibm.com">event-with-complex-value</qname>
    </supported-processing-event>
    

事件发布接收与处理

  • 事件发布:我们可以在希望发布事件的 Portlet 的 processAction() 方法里,通过调用 ActionResponse 的 setEvent() 进行事件发布,setEvent() 方法的输入参数为事件的名称和对应的值,这些参数必须与我们前面在 portlet.xml 中的事件声明一致。 清单 13. 事件发布
    public class TestSenderPortlet implements Portlet
    
    {
    
        ......
    
        public void processAction(ActionRequest request,
    
            ActionResponse response) throws PortletException,
    
            IOException {
    
            ......
    
            response.setEvent(eventName, eventObject);
    
            ......
    
        }
    
        ......
    
    }
    
    
  • 事件接收:事件的接收 Portlet 必须实现 javax.Portlet.EventPortlet 接口,事件的接收处理则在该接口包含 processEvent() 方法中进行,JSR 286 定义该方法提供了两个输入参数: EventRequest 和 EventResponse,我们可以通过调用 EventRequest 实例的 getEvent() 方法来获得当前事件,该方法返回一个事件对象的实例,该实例封装了事件的唯一标识和对应的值。 清单 14: 事件接收
    public class TestReceiverPortlet implements Portlet,EventPortlet
    
    {
    
        ......
    
        public void processEvent(EventRequest request,
    
            EventResponse response) throws PortletException,
    
            IOException {
    
            ......
    
            Event event = request.getEvent();
    
            ......
    
        }
    
        ......
    
    }
    
    
  • 事件处理:获得事件对象后,我们也可以通过 getQNames() 方法或者 getName() 获得事件的名称。两种获得事件方法的区别是 getQNames() 可以得到事件的全称标识,而 getName() 只是取得本地标识名。而取得事件的值则可以通过事件的 getValue() 方法获得。 清单 15: 事件处理
    ......
    
    public void processEvent(EventRequest request,
    
        EventResponse response) throws PortletException,
    
        IOException {
    
        ......
    
        Event event = request.getEvent();
    
        String name = event.getName();// 或者 String qname = event.getQNames();
    
        String value = event.getValue();
    
        ......
    
    }
    
    ......
    
    

GenericPortlet API 的变化

在 JSR 168 Portlet 的开发中,开发者通常继承抽象类 javax.portlet.GenericPortlet 来实现自己的 Portlet 逻辑代码。 同 JSR 168 相比, JSR 286 的 GenericPortlet 增加了 javax.portlet.EventPortlet 和 javax.portlet.ResourceServingPortlet 接口的实现,从而增加了事件处理和资源服务的功能。读者可以从 类图 1 和 类图 2 看出 JSR 286 GenericPortlet API 的变化。

图 1. JSR 168 GenericPortlet 类图 JSR 168 GenericPortlet 类图 图 2. JSR 286 GenericPortlet 类图 JSR 286 GenericPortlet 类图

 

共享呈现参数

我们先来看一看共享呈现参数的官方介绍:共享呈现用于在 Portlet 之间共享呈现参数,从而创建一个页面上下文。共享呈现参数在 portlet.xml 文件中声明。如果这些参数不是空值,Portlet 将自动接收它们。与非共享呈现参数相比,如果应该更改值,Portlet 仅需要设置共享呈现参数。

共享呈现参数,顾名思义,就是指 Portlet 之间共享参数,每一个 Portlet 对该参数的修改都能够直接被另外支持该参数 Portlet 所获得。共享呈现参数与 JSR 168 中已经有私有呈现参数的区别就在于,私有呈现参数只为 Portlet 内部使用,而共享呈现参数则为多个 Portlet之间通信协作而设置。共享呈现参数与事件相比的优势就在于避免了事件处理过程调用的繁琐。

我们举一个简单的事例来说明共享呈现参数的优点。假如我们开发了一个关于天气的 Portlet, 这个 Portlet 可以根据选择的城市来显示该城市的天气情况。我们为这个 Portlet 定制了邮政编码这个共有呈现参数来表示用户选择的城市。这样,如果我们再开发一个也有这个共享呈现参数的 Portlet,例如显示该城市地图或者旅游信息的 Portlet。在这种情况下,当我们修改天气 Portlet 所选择的城市的话,地图以及旅游信息的 Portlet 也会自动做出相应变化。从而实现了不同 Portlet 之间的协作。

共享呈现参数的声明

对共享呈现参数的使用声明包括两个部分,对共享呈现参数定义的声明和支持共享呈现参数的 Portlet 声明。

  1. 共享呈现参数定义声明:对于共享呈现参数定义的声明必须在 portlet.xml 部署文件中使用 <public-render-parameter> 关键字,该元素与 <portlet> 元素并列为 <portlet-app> 的分支。 清单 16. 共享呈现参数定义声明
    <portlet-app ...>
    
        <portlet>
    
            <portlet-name>Portlet A</portlet-name>
    
        ...
    
        </portlet>
    
        ...
    
        <public-render-parameter>
    
            <identifier>public-render-param1</identifier>
    
        </public-render-parameter>
    
        <public-render-parameter>
    
            <identifier>public-render-param2</identifier>
    
        </public-render-parameter>
    
    </portlet-app>
    
    
  2. 支持共享呈现参数 Portlet 声明:对于支持共享呈现参数的 Portlet 的声明需要在 portlet.xml 中 <portlet> 元素中使用 <supported-public-render-parameter> 关键字。 清单 17. 共享呈现参数 Portlet 定义声明
    <portlet>
    
        <portlet-name>Portlet B</portle-name>
    
        ......
    
        <supported-public-render-parameter>
    
            <identifier>public-render-param1</identifier>
    
        </supported-public-render-parameter>
    
    </portlet>    
    
    
    
    <portlet>
    
        <portlet-name>Portlet C</portle-name>
    
        ......
    
        <supported-public-render-parameter>
    
            <identifier>public-render-param2</identifier>
    
        </supported-public-render-parameter>
    
    </portlet>
    
    

共享呈现参数的使用

与非共享呈现参数的使用方法相同,共享呈现参数可以通过 ActionResponse 的 setRenderParameter("标识","值") 方法设定,并通过 RenderRequest 的 getParameter("标识") 来获得。见 清单 18 和 清单 19

清单 18. Portlet A 设定共享呈现参数

                
...
public void processAction(ActionRequest actionRequest,
        ActionResponse actionResponse) throws PortletException, IOException {
    String publicRenderParamValue1 = actionRequest.getParameter("public-render-param1");
    actionResponse.setRenderParameter("public-render-param1", publicRenderParamValue1);
}
...
清单 19. Portlet B 获取共享呈现参数
                
...
public void render(RenderRequest renderRequest,
        renderResponse renderResponse) throws PortletException, IOException {
    ...
    String publicRenderParamValue1 = renderRequest.getParameter("public-render-param1");
    ...
}
......

Portlet 过滤器

Portlet 过滤器是 JSR 286 提供的有一个非常重要的新特性。事实上,在 JSR 286 之前,就已经有很多厂商(包括 IBM)自定义扩展了 JSR 168,提供了过滤器功能。由此可见,Portlet 过滤器的重要性。为了避免各种厂商不同 Portlet 过滤器的不兼容性,JCP(Java Community Process)对 JSR 286 定义了标准的过滤器实现。

什么是 Portlet 过滤器?

与 Servlet 相似,Portlet 过滤器可以使用户可以改变一个 request 和修改一个 response。Filter 不是一个 Portlet,它不能产生一个 response,它能够在一个 request 到达 Portlet 之前预处理 request,也可以在离开 Portlet 时处理 response。换句话说,过滤器其实是一个“Portlet chaining”(Portlet 链)。它能够实现的功能包括:

  1. 在 Portlet 被调用之前截获;
  2. 在 Portlet 被调用之前检查 servlet request;
  3. 根据需要修改 request 头和 request 数据;
  4. 根据需要修改 response 头和 response 数据;
  5. 在 Portlet 被调用之后截获;

 

Portlet 过滤器与 Servlet 过滤器

事实上,从宏观功能的角度看来,Portlet 过滤器和 Servlet 过滤器是很相似的。这是因为二者都可以声明性地嵌入,从而截获并修改请求和响应。但是理解它们之间存在着很大的不同是非常重要的。在一定程度上,它们之间的差异是与 Servlet 和Portlet 之间的差异相联系的:Servlet 过滤器是一个门户级过滤器,它可以修改由一些小的部分(来自页面上所有 Portlet 的响应)集合而成的整个门户页面;而 Portlet 过滤器只能用于那些小的部分。Servlet 过滤器(如果已经安装的话)是接收和修改客户端请求的第一个组件,同时也是修改对客户端的响应的最后一个组件(请参见图 3)。

图 3. 带有 Servlet 过滤器和 Portlet 过滤器的客户端请求事件序列 Portlet and Servlet workflow

如图 3 所示,Servlet 请求(步骤 1)在分派给一个或多个 Portlet 请求(步骤 3)之前首先通过一个 Servlet 过滤器链进行处理(步骤 2)。在结果集聚到一起(步骤 6 和 7)之前,Portlet 请求进一步转发到 Portlet 过滤器链进行处理(步骤 4)。接着,将集聚的结果发送回 Servlet 过滤器进行处理,之后,将集聚的结果最终显示给用户(步骤 9)。

另外一点需要注意的是,Servlet 过滤器比 Portlet 过滤器的优先级别要高,容器将首先进行 Servlet 过滤,其次是 Portlet 过滤。一个过滤器链包含一个或多个过滤器。在一个过滤器完成处理之后,新的请求和响应将传送到链上的下一个过滤器;链上的最后一个过滤器调用目标资源(Servlet 或 Portlet)。

Portlet 过滤器的工作原理

Portlet 过滤器可以放置在 V2.0 规范提供的任何生命周期方法调用的前面或者后面(processAction、processEvent、render、serveResource),而且还支持这些生命周期方法使用包装的请求和响应。与 Servlet 过滤器类似,Portlet 过滤器需要在 portlet.xml 部署描述符中进行定义,不同的是,servlet只有一个service()的请求处理方法,因此servlet只有一种类型的过滤器。而portlet却有四种请求处理方法,于是有四种类型的过滤器,包括:

  1. Action 过滤器
  2. Render 过滤器
  3. Resource 过滤器
  4. Event 过滤器

 

下面我们来介绍四种过滤器的工作原理。

JSR 286 为 Portlet 过滤器提供了接口类 PortletFilter,该接口提供了两个方法。

  1. void init(FilterConfig config) 容器调用一次这个方法来准备用于服务的过滤器。对象 filterConfig 使得过滤器能够访问配置参数以及对门户上下文的引用。
  2. void destroy() 这个方法是在将过滤器从服务移除之后调用的。这个方法使得过滤器能够清除任何存放的资源。

JSR 286 为四种过滤器分别定义了一个接口类,这四个接口类都继承 PortletFilter 类,并分别添加了各自 doFilter() 方法。关于这几个类之间的关系,请见下图:

 

图 4. Portlet 过滤器继承图 Portlet Filter继承图

四种过滤器分别对 Portlet 的四个方法进行拦截。用户自定义的过滤器必须实现相应的过滤器接口,通过其 doFilter() 方法来实现相应的动作。其对应关系见表 1:

表 1. 过滤器与拦截方法关系图

过滤器拦截方法
Action 过滤器processAction(ActionRequest request, ActionResponse response)
Render 过滤器render(RenderRequest request, RenderResponse response)
Resource 过滤器serveResource(ResourceRequest request, ResourceResponse response)
Event 过滤器processEvent(EventRequest request, EventResponse response)

Portlet 过滤器的部署声明

下面我们通过一个具体的 Portlet 过滤器部署实例来说明。参见清单 20: 清单 20. Portlet 过滤器声明

<portlet-app ...>

    ...

    <filter>

        <filter-name>TestRenderFilter</filter-name>     

        <filter-class>com.ibm.jsr286.TestRenderFilter</filter-class>

        <lifecycle>RENDER_PHASE</lifecycle>

    </filter>



    <filter>

        <filter-name>TestAllFilter</filter-name>

        <filter-class>com.ibm.jsr286.TestAllFilter</filter-class>

        <lifecycle>ACTION_PHASE</lifecycle>

        <lifecycle>RENDER_PHASE</lifecycle>

        <lifecycle>EVENT_PHASE</lifecycle>

        <lifecycle>RESOURCE_PHASE</lifecycle>

    </filter>



    <filter-mapping>    

        <filter-name>TestRenderFilter</filter-name>

        <portlet-name>DocumentPortlet</portlet-name>

        </filter-mapping>



    <filter-mapping>    

        <filter-name>TestAllFilter</filter-name>

        <portlet-name>Test*</portlet-name>

    </filter-mapping>

</portlet-app>

关于 Portlet 过滤器有几点需要声明的是:

  • 对于一个 Portlet 过滤器的声明亦包括两部分,过滤器的定义声明以及过滤器的映射声明。
  • 一个 Portlet 过滤器可以为多个 Portlet 服务,而且 一个 Portlet 可以同时有多个 Portlet 过滤器。
  • 一个 Portlet 过滤器可以有多个生命周期阶段,当然前提是该 Portlet 过滤器实现了相应过滤器接口。

Portlet 窗口

Portlet 窗口在 JSR 168 中仅间接地得到反映,并作为容器为 Portlet 范围的会话条目生成的前缀的一部分。JSR 286 规范现在使该 Portlet 窗口 ID 可通过请求供 Portlet 使用,简单的说就是,PortletRequest 新增了一个方法 getWindowID(),可以获得 Portlet 的窗口 ID,这个 ID 是由容器生成的。在 Portal 容器中布局同一个 Portlet 多次的情况下,windowID 可以用来区分同一个 Portlet 的不同窗口,从而可以使这些 Portlet 窗口缓存并呈现不同的数据。

Portlet 窗口支持的一个常见用例是在 Portlet 中缓存数据;例如,一个 Portlet,呈现所使用的数据是通过 web services 从远端服务器获得,而且网络调用速度比较慢,且呈现的数据为只读,这种情况下就可以把 web services 获得的数据和窗口 ID 关联并缓存起来,在频繁调用 Portlet 的时候,就不必频繁等待 web services 的返回。

portlet 规范和API(jsr 168/286) 目前最全的资源 jsr168 jsr286 中英文都有 还有API 立即下载

相关推荐

JSR286 portlet新特性

文章专门针对具有 JSR 168 Portlet 开发基础,并且想了解 JSR 286 Portlet 新特性和开发流程的开发人员。在学习完本系列后,您将了解相对于 JSR 168 Portlet,JSR 286 Portlet 究竟提供了哪些增强功能, 以及这些新增特性在实际开发中的应用。

JSR 286 Portlet 的新特性,第 2 部分: 资源服务、事件与共享呈现参数

关于本系列本系列 专门针对具有 JSR 168 Portlet 开发基础,并且想了解 JSR 286 Portlet 新特性和开发流程的开发人员。在学完本系列后,您将了解到相对于 JSR 168 Portlet,JSR 286 Portlet 究竟提供了哪些增强功能, 以及这些新增特性在实际开发中的应用。本系列的 第 1 部分 简单回顾了 JSR 168 Portlet, 并列出了 JSR

844

JSR 286 Portlet 的新特性,第 3 部分: Portlet 过滤器和 Portlet 窗口

NULL 博文链接:https://tyler-zhou.iteye.com/blog/680621

portlet 2.0_Java Portlet规范V2.0(JSR 286)中有哪些新功能?

Portlet是组件化的面向用户的应用程序,可创建某种标记。 该标记旨在与其他标记片段聚合到一个更大的应用程序中,例如,如图1所示的门户页面。 图1.一个样本门户页面 因此,可以将Portlet视为基于用户界面(UI)的服务,这些服务采用面向服务的体系结构(SOA)的方式一直到用户界面。 Java Portlet规范的第一个版本Java规范要求(JSR)168在2003年的Java...

cusi77914的博客 709

JSR286规范与API手册

JSR286规范与API手册 JSR286 Portlet 门户 portal portlet2.0开发必备

Portlet 2.0 新特性介绍(全)

系列文章专门针对具有 JSR 168 Portlet 开发基础,并且想了解 JSR 286 Portlet 新特性和开发流程的开发人员。在学习完本系列后,您将了解相对于 JSR 168 Portlet,JSR 286 Portlet 究竟提供了哪些增强功能, 以及这些新增特性在实际开发中的应用。

JSR286 Portlet开发:Portlet之间的Events通信

开发工具:Jdeveloper 11.1.1.7 1.创建Portlet Application a.选择File->New,在新建向导中选择WebCenter Portal - Portlet Producer Application,如下图: b.在向导中输入Application Name,如下图所示: c.其他配置默认即可,点击【Finish】完成。 2.

CQMKING的专栏 973

Dynamics CRM证书更换

  Dynamics CRM产品一般有两种认证方式。第一种是基于声明的内部访问也就是无证书单纯用账号密码验证。第二种就是联合身份认证,需要安装网站证书。   对于联合身份认证的情况因为需要安装证书,而且证书是有一个一年的有效期,所以运维人员每年都需要进行证书更换的操作。以下就是更换证书的方法及过程。 证书根据申请方式一般也分两种,第一种是自建证书,这种证书是没有机构认证的所以安装上之后网站因为没...

bzpfly的博客 877

JSR 286

 新规范的一些主要功能及特性:资源服务:一种新的通过 portlet 呈现资源的方式。事件:通过发送事件和接收事件来实现 portlet 之间的通信。Portlet 过滤器:与 servlet 过滤器类似,根据 Portlet 请求和响应动态的呈现内容的变换。存在以下四种类型的 portlet 过滤器: Action 过滤器Render 过滤器Res

yanghw0510的专栏 1103

学习笔记7--激光雷达标定

本系列博客包括6个专栏,分别为:《自动驾驶技术概览》、《自动驾驶汽车平台技术基础》、《自动驾驶汽车定位技术》、《自动驾驶汽车环境感知》、《自动驾驶汽车决策与控制》、《自动驾驶系统设计及应用》,笔者不是自动驾驶领域的专家,只是一个在探索自动驾驶路上的小白,此系列丛书尚未阅读完,也是边阅读边总结边思考,欢迎各位小伙伴,各位大牛们在评论区给出建议,帮笔者这个小白挑出错误,谢谢! 此专栏是关于《自动驾驶汽车环境感知》书籍的笔记。 2.激光雷达标定 2.1 概述 激光雷达内参标定:内部激光发射器坐标系与雷达本

FUXI_Willard 8025

利用ArcMap实现遥感图像语义分割标注的完整流程解析

本文详细解析了利用ArcMap进行遥感图像语义分割标注的完整工作流。从工程创建、数据导入、SHP文件创建,到实战勾画地物、要素转栅格,再到最终的裁剪对齐,提供了每一步的关键操作与避坑指南。该方法特别适合处理大尺寸、带地理坐标的遥感影像,能高效产出精准对齐的图像-标签对,为后续深度学习模型训练奠定可靠的数据基础。

gpu4optimizer的博客 1210

JSR 286 Portlet 的新特性 第 1 部分: Portlet 2.0 新特性介绍

关于本系列 本系列文章专门针对具有 JSR 168 Portlet 开发基础,并且想了解 JSR 286 Portlet 新特性和开发流程的开发人员。在学习完本系列后,您将了解相对于 JSR 168 Portlet,JSR 286 Portlet 究竟提供了哪些增强功能, 以及这些新增特性在实际开发中的应用。 第 1 部分将简单回顾 JSR 168 Portlet, 并列出了 JSR 286

墨者侠客 657

SkyWalking跨线程Trace传递实战:手把手教你用RunnableWrapper解决异步链路中断问题

本文深入解析了SkyWalking在异步编程场景下链路追踪中断的根源,并提供了使用RunnableWrapper等官方包装类的实战解决方案。通过详细的原理解析和代码示例,手把手指导开发者如何实现跨线程的Trace传递,确保分布式系统监控链路的完整性,有效解决异步任务导致的链路中断问题。

sand8的博客 493

JSR 286 Portlet 的新特性: Portlet 2.0 新特性介绍

关于本文本文假定读者熟知 JSR 168 Portlet,并对 J2EE 基本常识有一定了解。本文主要以理论的方式向读者介绍 JSR 286 Portlet 的以下新增特性:资源服务事件共享呈现参数Portlet 过滤器Portlet 窗口回页首Portlet

jianpingdu2009的专栏 1218

【雷达】一维和二维自适应波束形成(DBF))DBF附matlab代码

1 简介 数字波束形成技术是天线波束形成原理与数字信号处理技术相结合的产物,其广泛应用于阵列信号处理领域.由于电磁工作环境的恶化和大量射频干扰的存在,在极低的信干噪比(SINR)条件下进行目标检测和信息提取十分困难.对于阵列系统,往往采用自适应数字波束形成(ADBF)技术,来抑制强干扰和方向性干扰对有用信号的影响.介绍了数字波束形成器的基本原理及其DSP的实现结构.​ 2 完整代码 clc;clear all;close all;%%%%%%%%%%%%%%%%%一维DBF%%%%%%%%%%%%%

qq_59747472的博客 7265

制作3D地形图的方法-使用GlobalMapper和3ds Max软件

打开GlobalMapper软件,在菜单栏中选择“文件”>“打开数据文件”,然后选择相应的高程数据文件。在菜单栏中选择“渲染”>“渲染设置”,根据需要进行设置,如分辨率和输出格式。选择地形对象,点击菜单栏中的“渲染”>“材质编辑器”,然后根据需要调整材质属性,如颜色、纹理和光照等。在菜单栏中选择“工具”>“高程栅格和网格”>“创建地形网格”。在菜单栏中选择“文件”>“导出”>“导出栅格格式”。打开3ds Max软件,在菜单栏中选择“文件”>“导入”,然后选择之前导出的地形数据文件。步骤3:导出地形网格。

JqlScala的博客 1535

JSR 286 Portlet 的新特性: Portlet 2.0 新特性介绍(portlet协作、事件机制、数据共享)

  本文假定读者熟知 JSR 168 Portlet,并对 J2EE 基本常识有一定了解。本文主要以理论的方式向读者介绍 JSR 286 Portlet 的以下新增特性:  资源服务  事件  共享呈现参数  Portlet 过滤器  Portlet 窗口  Portlet 和 JSR 168  Portlet 是部署在容器内用来生成动态内容的 Web 组件,与 ser

jianpingdu2009的专栏 1078

【制作100个unity游戏之22】3DRPG游戏开发07——其他详细的设计

我们会有有很多单例,如果每个单例都去写会很麻烦,所以我们定义泛型单例模式 Singleton,我们将所有的单例都继承这个泛型单例,就省略很多重复的工作定义一个GameManager类,继承Singleton,控制整个游戏的进度,比如如果主角死了,广播,游戏结束调用。

向宇的博客,专注php/web全栈 unity游戏开发,欢迎大家评论纠错 2576

What's new in the Java Portlet Specification V2.0 (JSR 286)?

Portlets are componentized user-facing applications that create somekind of markup. This markup is intended to be aggregated with othermarkup fragments into a larger application, for example, a po

凭水横江 1243

NeRF-Pytorch(训练自己的数据集过程全记录+环境配置+COLMAP+问题解决)

写于2025/1/26,在用NeRF训练自己的数据集过程中该踩的坑都踩过了,发现网上并没有详细完整写这些问题解决过程的帖子,遂自己进行一个全记录和复盘。 整篇文章包括:NeRF训练环境配置;COLMAP三维重建过程(直接给出代码,规避一些bug);在训练时候出现的问题。 本篇文章仅针对llff格式数据集。

m0_62577716的博客 1774

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

上一篇: Java 理论与实践: 使用通配符简化泛型使用,理解通配符捕获
下一篇: JSR 286 Portlet 的新特性,第 2 部分: 资源服务、事件与共享呈现参数
phantomhu
博客等级 码龄23年 70粉丝 24原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值