How IBM supports JSR 286 portlets within WebSphere Portal Server 6.1

Java portlets started to become popular after the first version of the Java Portlet Specification, the Java Specification Request (JSR) 168, was finished in 2003 at the Java Community Processes. Since then, nearly all the vendors in the Java portal space, both commercial and open-source vendors, have implemented this standard, and developers have written portlets using the Java Portlet API.The JSR 168, however, stopped at defining the overall UI component model and did not define any means for building integrated composite applications out of these components. This limitation, and many other things that didn't make it into V1.0 due to time constraints, is now addressed in V2.0.Work on JSR 286 started in January 2006, and the final version was submitted in February 2008.Please go through the following links to get yourself more familiar with JSR 286 features and specifications:

http://www.ibm.com/developerworks/websphere/library/techarticles/0803_hepper/0803_hepper.html
http://www.ibm.com/developerworks/websphere/library/techarticles/0809_hepper/0809_hepper.html

(The second link also provides you some of the recommendations to consider while developing JSR 286 Portlets).


Broadly speaking, JSR 286 (or v2.0) has the following key points:

  • Binary compatible with JSR-168 Java Portlet Specification V2.0 was designed to avoid breaking binary code compatibility with V1.0 and to maintain compatible behavior for all API methods. This design point means that all portlets written against the V1.0 specification should run unchanged on a V2.0 container. The only exceptions to this rule are the following slight behavior changes that normally should not break any portlets:
  1. RenderResponse.setContentType is no longer required before calling getWriter or getOutput-stream. Calling getWriter or getOutputstream without previously setting the content type no longer results in an IllegalStateException in V2.0.
  2. getProtocol for included servlets / JSPs no longer returns null, but instead returns HTTP/1.1 in V2.0.

    This backward compatibility statement also includes the deployment descriptor in which V2.0 added new entries, but did not change existing ones. This behavior means that you can turn most JSR 168 portlets into a JSR 286 portlet by changing the one line in the portlet deployment descriptor that references the schema to the new V2.0 portlet deployment descriptor schema.
  • Portlet Coordination (Event support) V2.0 provides additional coordination capabilities using Event paradigm as an extension to Property Broker (dynamic event declaration for sending events and static declaration for receiving events). Within action phase, portlets will have event handling step which should get over before rendering starts.
  • Public Render Parameters allow render parameters to be shared across portlets (using HTTP GET), may be across pages and not restricted to portlet application. Parameters are visible to the portal and allowed to be shared with other components. Public render parameters are defined in the portlet.xml.
  • Resource Serving: Resource serving via Portlet (implementing additional ResourceServingPortlet interface) is additional in JSR 286. It introduces new ResourceURLs that trigger a new lifecycle method serveResource and uses Resource serving APIs (JSP Tags and method calls etc).
  • AJAX driven use cases: Ajax patterns provide full access to portlet state via XmlHttpRequest and ResourceURLs.
  • Setting cookies and HTTP headers / HTML head attributes inside Portlets (JSR 286). Within Portlet code, headers / cookies needs to be set before the document body starts.
  • Portlet Filter: V2.0 introduces Portlet filters and request / response wrappers. Portlet filters are largely similar to Servlet filter, but can be restricted to specific portlet life cycle methods (e.g. render/action etc) in portlet.xml via filter-mapping element (similar to servlet filters). Portlet container calls the filter chain.
  • Extended Request Dispatcher capabilities (to support servlet-based frameworks on top of portlets). Request dispatch includes allowed in all lifecycle methods in v2.0. This will allow better integration with Servlet driven frameworks like Struts 2.0, Spring etc.
  • Added API based Caching control
  • New JSP Tag lib for resource URLs and more implicit variables (e.g. portletSession, portletPreferences etc) available.
  • Portlet Managed modes (allow portlets to specify their own application specific portlet modes)
  • Java 5 features (e.g. Annotations, Generics, back supportability with Java 1.4 based implementations)
  • WSRP 2.0 It is a standard protocol to access portlets as web service. Portlet developers need not know anything about it if they want to publish their portlets as a Web Service.
  1. JSR 286 - API Class Diagram - Request
  2. JSR 286 - API Class Diagram - Response
  3. JSR 286 - API Class Diagram - Portlet
  4. JSR 286 - Resource Serving
  • Producer/portlet acts as proxy to resources
    • Requests for resources (e.g. PDF documents) addressed within portlet API & WSRP protocol
    • WSRP 1.0 / JSR168 required out-of-band connection (e.g. HTTP to servlet)
  • Advantages
    • Consumers do not need full access to resources referenced by portlets
    • >> Resources do not have to be directly addressable by URLs
    • >> Producers / portlets can implement any back-end protocol to serve resources (e.g. from CMS)
    • Context information is passed directly over the API / protocol, i.e.
    • >> Same session
    • >> User context, Authentication, etc.
    • >> Resources become portal context aware
    • AJAX use cases are now better supported via the portlet
  • New lifecycle method "serveResource"
    • Addresses the portlet directly
    1. Portlet responsible to dispatch or write resource to output stream
    • In portal context
    1. Navigational state, current portlet mode, window state, session, preferences...)
  • New ResourceURLs trigger "serveResource" invocation
  • Resource addressing via resourceID
    • Set as optional ResourceURL parameter
    • Allows complete protocol abstraction
    • >> Resources can be served from virtually anywhere and brought to the browser
    • AJAX fragments can be served as resources
  • Portlet owned AJAX calls
    • Full access to the portlet state
      • Via XmlHttpRequest and ResourceURLs
      • Allowed to change portlet preferences and portlet-scoped session attributes
    • Functionality restricted:
      • No state changes for navigational state (portlet mode, window state, render parameters)
      • No support for events
  • Coordinated between portal and portlet
    • Not covered by JSR 286, but vendor specific solutions exist
    • Needs to include a client side library that the portlet can leverage
    • E.g. For allowing the portal to update the URLs on the page if the portlet sets new render parameters (e.g. XmlPortletRequest and XmlPortletResponse objects)
    • OpenAjax is working on a standardized solution for the future
      • Defining a generic client side gadget programming model
  • AJAX-enabled portlet reloads affected content using a resource request
    • JavaScript call points to the Portal Application
    • Portal Application dispatches resource serving call to portlet
5. Introduction Portlet Filters & features
The Java Portlet Specification has introduced concept of Portlet Filters based on Servlet Filters. The basic concept remains the same that Portlet Filter allows you to do some pre and/or post processing for every request. Note one important point that unlike servlets, portlet specification defines 4 different phases for handling user request and as result it defines 4 Filter interfaces that you can use.
  • ACTION_PHASE : If you want to perform filtering during action phase then you should implement class implementing javax.portlet.filter.ActionFilter interface
  • RENDER_PHASE : If you want to perform filtering during render phase then you should implement class implementing javax.portlet.filter.RenderFilter interface
  • EVENT_PHASE : If you want to perform filtering during event handling phase then you should implement class implementing javax.portlet.filter.EventFilter interface
  • RESOURCE_PHASE : If you want to perform filtering during resource serving phase then you should implement class implementing javax.portlet.filter.ResourceFilter interface

A portlet filter is a Java component that can be used to modify portlet request and response before/after any lifecycle method of the portlet is being executed. The concept of Portlet filter is same as that of servlet filter. The only difference is that a servlet has only one request handling method i.e. service() method and therefore there is only one type of the servlet filter. A portlet has four types of request handling methods and therefore there are 4 different types of portlet filters. The portlet API defines following interfaces for creating Portlet filter:
  • javax.portlet.filter.ResourceFilter (for serveResource method)
  • javax.portlet.filter.RenderFilter (for render method)
  • javax.portlet.filter.ActionFilter (for processAction method)
  • javax.portlet.filter.EventFilter (for processEvent method)

Each of the above filter interface contains a single doFilter (*Request, *Response, FilterChain chain) method which differs in the type of request and response object. For example, doFilter () method in ActionFilter takes ActionRequest and ActionResponse while doFilter () method of RenderFilter takes RenderRequest and RenderResponse objects. Each of the above filter interfaces extends a common base interface called javax.portlet.filter.PortletFilter. This common base interface contains init (javax.portlet.filter.FilterConfig filterConfig) and destroy () methods. The init (...) method makes sure that every Filter has access to a FilterConfig object from which it can obtain its initialization parameters, a reference to the PortletContext which it can use, for example, to load resources needed for filtering tasks. The init () and destroy () methods of a portlet filter are being called only once during their lifetime.

A single filter class can provide filter functionality for more than one lifecycle methods and also a single filter can provide filter functionality for more than one portlet. There can be multiple filters associated with one lifecycle method of a portlet. The javax.portlet.filter.FilterChain class (created by Portlet container) is used to invoke the sequence of filters applicable for a particular lifecycle method of a portlet. The doFilter () method of a portlet filter may create customized request and response objects by using *RequestWrapper and *ResponseWrapper classes and passing these wrappers to the doFilter () method of FilterChain.

In order to write a portlet filter, the developer is required to do the following 2 things:
  1. Write a filter class - A filter class should implement one or more of the above mentioned four interfaces and should provide a no argument public constructor. The filter class is also required to override init () and destroy () method of javax.portlet.filter.PortletFilter interface. Note: Rational Application Developer 7.5 Portal Toolkit does not have inbuilt support for developing Portlet Filters unlike Servlet Filters.
  2. Add entry of filter in portlet.xml - After writing a portlet filter class, it can be configured by adding following 2 xml fragments in portlet.xml.
The first xml fragment defines a filter by providing a logical name to it. It tell portlet container about the filter class and the lifecycle phases supported by it. You can specify initialization parameters also.

The Second xml fragment specifies the portlet(s) for which this filter will be applicable. You can specify a single portlet name or mapping to a group of portlets using the ‘*’ as a wildcard.

6. JSR 286 - Public Render Parameters
In JSR 168, the render parameters set in processAction method is only available in the render of the same portlet.With the Public Render Parameters feature, the render parameters set in the processAction method of one portlet will be available in render of other portlets also. Using public render parameters instead of events avoids the additional process event call.[GL] In order to allow coordination of render parameters with other portlets, within the same portlet application or across portlet applications, the portlet can declare public render parameters in its deployment descriptor using the public-render-parameter element in the portlet application section. Public render parameters can be viewed and changed by other portlets or components.In the portlet section each portlet can specify the public render parameters it would like to share via the supported-public-render-parameter element. The supported-public-render-parameter element must reference the identifier of a public render parameter defined in the portlet application section in a public-render-parameter element.In the code, the portlets should use the defined public render parameter identifier to access the public render parameter [GL]. Rational Application Developer 7.5 (RAD) Portal Toolkit has inbuilt support for public render parameter declarations and usage, hence you will not have to code or modify the deployment descriptor the way shown down below in example[GL].

Steps to create a portlet with the Render parameters:
  1. Declare the render parameters to be shared in the portlet.xml
  2. Specify the render parameter that the portlet would like to share in the portlet section
  3. Set the render parameter in the processAction () method
Coordination aka Inter-Portlet Communication
In most cases, portlets are self-contained and do not effect each other. Such portlets can be added/removed at will without affecting other portlets on a page. This decoupled nature makes portlet development and deployment easy. But the down side is that, for the end user, the UI looks less interesting. Silos are not the best way to present UI in a browser.

The JSR-286 and WSRP 2.0 specifications allow an exception to this. These specifications add ability for portlets to communicate with each other in a loosely-coupled manner. One of the key mechanisms for doing this is by using events. Events are named, and can optionally have a payload with them. Using this mechanism, based on some user interaction, one portlet could fire an event that other portlets can handle. Upon handling the event, those portlets can fire more events, and the chain can continue until some system limit occurs. In this model, portlets don’t send events directly to each other, and the portal acts as a coordinator for event distribution. During event processing, portlets can change their own state (e.g. change some back-end data). After the event chain completes, the portal renders each portlet with their latest state. In this way, portlets can still remain loosely coupled, and yet influence each other. In essence, events make it possible for a user interaction with one portlet to change the view of not just the portlet that the user is interacting with, but other portlets on a portal page as well. In some cases, the portal itself may want to handle some events, and its own markup may change.

Here is an example. Let’s say, a portal page is aggregating two portlets, viz. A and B. A submits an XMLHttpRequest to the server, which then invokes portlet A. As part of processing the request, A fires an event that B can handle. The portal dispatches the event to B. A then generates some JSON data to be returned via the responseText field of the XMLHttpRequest. While processing the event, portlet B changes its state, and its view in the browser becomes stale. The portal then needs to render B as well, and update its UI in the browser.
Portlet A’s script that started the XMLHttpRequest does not know much about portlet B, and hence the portal can not simply return portlet A’s JSON data and portlet B’s HTML view in the same response to portlet A. It needs do something special. Again, the XMLPortletRequest interface is designed to solve this problem such that (a) portlet A can receive its JSON data, and (b) the portal can update portlet B’s view independently. The approach is not limited to events. Depending on how the portal is implemented and the features it supports, it can update any part of the portal page when several fragments of a page need to be updated in response to a portlet are XMLHttpRequest.

XMLPortletRequest is a script interface, i.e. it is possible to implement this interface in JavaScript. This is unlike XMLHttpRequest which can only be implemented by browsers natively. Except for its name, XMLPortletRequest shares the same syntax and semantics with XMLHttpRequest. If a portlet wants to synchronously or asynchronously update its UI either through an action or a render URL, it would simply use XMLPortletRequest in stead of the XMLHttpRequest. Where as browsers implement the XMLHttpRequest interface, portals and similar aggregating applications implement the XMLPortletRequest interface, typically as a layer on top of the XMLHttpRequest.

Here is the XMLPortletRequest interface:
Wrapping XMLHttpRequest:
Note that the XMLPortletRequest can be implemented as a wrapper over XMLHttpRequest, and portals provide an implementation of the XMLPortletRequest. This gives the portal a chance to intercept both requests and response. It also gives portals a chance to ferry additional portal-specific data along with each request and response, and that is the key feature of the XMLPortletRequest. See figure below.
In the above, the XMLPortletRequest is implemented using XMLHttpRequest. When a portlet’s script submits an XMLPortletRequest, the implementation makes a request to the portal on behalf of the portlet. This request could contain any implementation specific data. The portal then wraps the portlet’s response (which in this case is some JSON data) in its own response payload and returns it to its implementation in the browser. The XMLPortletRequest implementation can then return portlet’s response to the portlet via its responseText or responseXML fields. In this process, it can also update other parts of the page, including UI generated by other portlets. That is the advantage of wrapping XMLHttpRequest with a semantically equivalent interface.


0 comments: