Sunteți pe pagina 1din 51

Portlet API comparison white paper:

JSR 168 Java Portlet Specification


compared to the IBM Portlet API

Version 1.0

Stefan Hepper
IBM Corporation
sthepper@de.ibm.com

Published June 28, 2004

© Copyright International Business Machines Corporation 2004. All rights reserved.

-1-
Table of Contents
1 Introduction ...................................................................................................................... 4
2 JSR 168 and the Java Community Process ...................................................................... 5
3 Comparing concepts......................................................................................................... 6
3.1 Basic concepts ........................................................................................................... 6
3.1.1 Portal .................................................................................................................. 6
3.1.2 Portal page.......................................................................................................... 7
3.1.3 Portlet ................................................................................................................. 8
3.1.4 Portlet Container ................................................................................................ 8
3.2 Concepts that are the same ........................................................................................ 8
3.2.1 Portlet mode ....................................................................................................... 8
3.2.2 Window state...................................................................................................... 9
3.2.3 Portlet life cycle and request processing .......................................................... 10
3.2.4 URL encoding .................................................................................................. 11
3.2.5 Include servlets/JSPs ........................................................................................ 12
3.2.6 Portlet application packaging ........................................................................... 12
3.2.7 Expiration-based caching ................................................................................. 13
3.3 Concepts that differ ................................................................................................. 13
3.3.1 Portlet application entity .................................................................................. 13
3.3.2 Portlet entity ..................................................................................................... 18
3.3.3 Action and Render Request / Response objects ............................................... 18
3.3.4 Window concept............................................................................................... 18
3.3.5 Portlet API does not extend servlet API........................................................... 19
3.3.6 TAG libraries.................................................................................................... 19
3.4 Concepts new in the JSR 168.................................................................................. 19
3.4.1 Render parameter ............................................................................................. 20
3.4.2 Extension mechanisms ..................................................................................... 20
3.4.3 Web application session scope......................................................................... 21
3.4.4 Reuse of the HttpSession listeners ................................................................... 21
3.4.5 J2EE role support ............................................................................................. 21
3.4.6 Resource bundles.............................................................................................. 21
3.4.7 Multiple response content types....................................................................... 22
3.4.8 Redirect in action ............................................................................................. 22
3.4.9 Preference validator.......................................................................................... 22
3.4.10 Portal context.................................................................................................. 22
3.4.11 Localization support....................................................................................... 22
3.5 Concepts missing in the JSR 168 ............................................................................ 23
3.5.1 Eventing ........................................................................................................... 23
3.5.2 Additional lifecycle events............................................................................... 23
3.5.3 Property broker................................................................................................. 24
3.5.4 Portlet Menus ................................................................................................... 24
3.5.5 Portlet Services................................................................................................. 25
3.5.6 Invalidation-based caching............................................................................... 25
3.6 Alignment with WSRP............................................................................................ 26
4 Outlook for the next version of the JSR 168.................................................................. 28
5 Guidelines for programming IBM Portlet API portlets ................................................. 30

-2-
5.1 Similar Functionality............................................................................................... 30
5.1.1 Basic programming model ............................................................................... 30
5.1.2 Portlet private session....................................................................................... 30
5.1.3 User profile information................................................................................... 31
5.1.4 Persistent data................................................................................................... 31
5.1.5 Portlet modes and window states ..................................................................... 31
5.1.6 Expiration-based caching ................................................................................. 32
5.2 Slightly different functionality ................................................................................ 32
5.2.1 Sharing of data between portlets ...................................................................... 32
5.2.2 Session listeners ............................................................................................... 32
5.3 New JSR 168 functionality ..................................................................................... 32
5.3.1 Navigational state (render parameters) ............................................................ 33
5.4 Pitfalls...................................................................................................................... 33
5.4.1 Request / response objects for action and render phase ................................... 33
5.4.2 Include search path........................................................................................... 34
5.4.3 Form parameter encoding................................................................................. 34
5.4.4 Title setting....................................................................................................... 34
6 Examples ........................................................................................................................ 35
6.1 IBM Portlet API Portlet Code ................................................................................. 36
6.2 JSR 168 Portlet Code .............................................................................................. 39
6.3 IBM Portlet API JSPs.............................................................................................. 42
6.4 JSR 168 JSPs........................................................................................................... 46
7 Summary ........................................................................................................................ 51

NOTE: The information provided in this analysis is provided, "AS IS", without
warranty of any kind. The analysis is intended to be an informational tool only for
user.

© Copyright International Business Machines Corporation 2004. All rights reserved.

-3-
1 Introduction
With the emergence of an increasing number of enterprise portals, a variety of different
APIs for portal components, called portlets, has been created by different vendors. The
variety of incompatible interfaces creates problems for application providers, portal
customers and portal server vendors. To overcome these problems, the Java™ Portlet
Specification JSR 168 standard will provide interoperability between portlets and portals.

The goal of this document is to describe the differences between the new JSR 168 and the
IBM® WebSphere® Portal Version 5.0 Portlet API. We will explain the differences on
different levels, from conceptual down to concrete examples. Finally we will provide
advice how to program portlets under the IBM Portlet API to make them easy convertible
to the JSR 168 API.

NOTE: The IBM Portlet API will still be supported in the next WebSphere Portal
5 releases and the next major release WebSphere Portal Version 6 and possibly
beyond to give customers and partners a convenient migration window.

-4-
2 JSR 168 and the Java Community Process
The Java Standardization Request 168 (JSR 168) defines a Portlet Specification,
including a contract between the portlet container and the portlet. The JSR 168 is done in
the Java Community Process (JCP). Via the JCP everyone can work to extend the Java™
Language Specification. If there is functionality missing that you would like to see in the
JSR 168, please join the Expert Group or take part in the reviews. See http://jcp.org for
more details.
The JSR 168 was co-leaded between IBM and Sun and had a large Expert Group that
helped to create the final version now available. This Expert Group consisted of Apache
Software Foundation, Art Technology Group Inc.(ATG), BEA, Boeing, Borland, Citrix
Systems, Fujitsu, Hitachi, IBM, Novell, Oracle, SAP, SAS Institute, Sun, Sybase, Tibco,
Vignette. More details about this JSR can be found at http://jcp.org/en/jsr/detail?id=168.

-5-
3 Comparing concepts
This chapter compares the concepts between the IBM Portlet API and the JSR 168.
Fortunately basic concepts like page, portlet, portal, portlet container, stay the same
between JSR 168 and the IBM Portlet API.

3.1 Basic concepts

This section covers the concepts that define the basic portal architecture. These concepts
are the same between the IBM Portlet API and the JSR 168.

3.1.1 Portal

A portal is a web based application that –commonly – provides personalization, single


sign on, content aggregation from different sources and hosts the presentation layer of
Information Systems. Aggregation is the action of integrating content from different
sources within a web page. A portal may have sophisticated personalization features to
provide customized content to users. Portal pages may have different sets of portlets to
create content for different users.
Portlet Invoker API

Portlet
(App)
HTML, WML, VoiceXML, ...

Portal
Portlet API

Portlet/Servlet
Web
HTTP

Container Portlet
Application (App)
Portlet Provider SPI

Portlet
(App)

Figure 1: Basic portal architecture

-6-
Figure 1 depicts the basic architecture of a portal. The client request is processed by the
portal web application, which retrieves the portlets that appear on the current page for the
current user. The portal web application then calls the portlet container for each portlet to
retrieve its content. The portlet container provides the runtime environment for the
portlets and calls the portlets via the Portlet API.

3.1.2 Portal page

Figure 2 depicts the basic portal page components. The portal page itself represents a
complete markup document and aggregates several portlet windows. A portlet window
consists of a title bar with the title of the portlet, decorations, and the content produced by
the portlet (markup fragment). The decorations may include buttons to change the
window state of the portlet (e.g. maximize or minimize the portlet) and buttons to change
the mode of a portlet (e.g. show help or edit the predefined portlet settings).

Portal page Window states Portlet modes

<Title> Edit ?
<Title> Edit ?

Portlet Portlet content


windows

Portlet content
<Title> Edit ?

Portlet content

Markup Fragments

Figure 2: Basic portal page components

-7-
3.1.3 Portlet

A portlet is a Java technology based web component, managed by a portlet container, that
processes requests and generates dynamic content. Portlets are used by portals as
pluggable user interface components that provide a presentation layer to Information
Systems.

The content generated by a portlet is also called a fragment. A fragment is a piece of


markup (e.g. HTML, XHTML, WML) adhering to certain rules and can be aggregated
with other fragments to form a complete document, the portal page. The lifecycle of a
portlet is managed by the portlet container.

Web clients interact with portlets via a request/response paradigm implemented by the
portal. Normally, users interact with content produced by portlets, for example by
following links or submitting forms. This user interaction results in a portlet action being
received by the portal that is forwarded to the portlet targeted by the user's interactions.

The content generated by a portlet may vary from one user to another depending on the
user configuration for the portlet.

3.1.4 Portlet Container

A portlet container runs portlets and provides them with the required runtime
environment. A portlet container manages the portlet lifecycle. It also provides persistent
storage for portlet preferences. A portlet container receives requests from the portal to
execute requests on the hosted portlets.

A portlet container is not responsible for aggregating the content produced by the
portlets. It is the responsibility of the portal to handle the aggregation.

A portal and a portlet container can be built together as a single component of an


application suite or as two separate components of a portal application.

3.2 Concepts that are the same

This section will cover concepts that have not changed fundamentally from IBM Portlet
API to the JSR 168. Small changes between IBM Portlet API and JSR 168 are listed in
the corresponding sections.

3.2.1 Portlet mode

A portlet mode indicates the function a portlet is performing. Normally, portlets perform
different tasks and create different content depending on the function they are currently
performing. A portlet mode advises the portlet what task it should perform and what

-8-
content it should generate. When invoking a portlet, the portlet container provides the
current portlet mode to the portlet. Portlets can programmatically change their portlet
mode when processing an action request.

A small difference between the IBM Portlet API and JSR 168 are the predefined portlet
modes. The IBM Portlet API defines the following portlet modes:

• Edit – to display one or more personalization views that let the user personalize
portlet settings.
• Help – to display help views.
• View – to display the portlet output.
• Configure – to display one or more configuration views that let administrators
configure portlet settings valid for all users.

Whereas the JSR 168 splits portlet modes into three categories:

• required to support (same semantic as above)


o Edit
o Help
o View
• optional custom modes
o About – to display information on the portlets purpose, origin, version etc.
o Config – has the same semantic as the IBM Portlet API configure mode
o Edit_defaults – to set the default values for the modifiable preferences that
are typically changed in the EDIT screen.
o Preview – to render output without the need of having back-end
connections or user specific data available.
o Print – to display a view that is suitable for printing.
• portal vendor specific modes that are available only in a portal of a specific
vendor.

3.2.2 Window state

A window state indicates the amount of portal page space that will be assigned to the
content generated by a portlet. When invoking a portlet, the portlet container provides the
current window state to the portlet. The portlet may use the window state to decide how
much information it should render. Portlets can programmatically change their window
state when processing an action request.

A small difference between the IBM Portlet API and JSR 168 are the predefined window
states. The IBM Portlet API defines the following window states:

• Closed (deprecated) – to indicate that a window should be closed.


• Detached (deprecated) – to indicate that a window should be detached.
• Maximized – to indicate that a window has more real estate to render its output
then in normal window state.

-9-
• Minimized – to indicate that the portlet is minimized and cannot render any
output.
• Moving (deprecated) – to indicate that the portlet window has been moved.
• Normal – to indicate that the portlet is sharing its screen with other portlets on a
page.
• Resizing (deprecated) – to indicate that the portlet has been resized.
• Solo – to indicate that the portlet is the only portlet on the page.

Whereas the JSR 168 has only the following mandatory window states:

• Maximized – same as in the IBM Portlet API.


• Minimized – to indicate that the portlet should only render minimal or no output.
• Normal – same as in the IBM Portlet API.

However, the JSR 168 allows the portal to define additional window states.

3.2.3 Portlet life cycle and request processing

The basic portlet life cycle in both the IBM Portlet API and JSR 168 is:

• init – to initialize the portlet and put the portlet into service.
• handle requests – process different kinds of action and render requests.
• destroy – to put portlet out of service.

The portlet receives requests based on the user interaction with the portlet or portal page.
The request processing is divided into two major phases:

1. action processing
A click on a link a action link in the markup of a portlet triggers an action call for
this portlet. The action processing must be finished before any rendering of the
portlets on the page is started. In the action phase the portlet has the ability to
change state.
2. rendering content
In the render phase the portlet produces its markup to be sent back to the client.
Rendering should not change any state, allowing a page re-fresh without
modifying the portlet state. The rendering of all portlets on a page can be
performed in parallel.

- 10 -
Figure 3: Request flow from client to portlets
Figure 3 depicts the request flow from client to the portlets and shows the two different
phases action and render in more detail. In this example portlet A has received an action
and after this action is processed the render methods of all portlets on the page (A, B, C)
are called.

3.2.4 URL encoding

There are two types of URLs the portlet may want to include in its markup:

• portlet URLs
As part of its content, a portlet may need to create URLs that reference the portlet
itself. This functionality is encapsulated in a method call to allow different portal
implementations to create different URLs. In addition re-writing of URLs in the
remote case is possible. Different from the IBM Portlet API where only one
generic createURI method is available that can be turned into an action URL by
setting an action attribute, in JSR 168 two different methods, createActionURL
and createRenderURL, create URLs triggering an action or the short-cut of
setting new render parameters. Also the JSR 168 API allows creating URLs that
directly can change the portlet mode or window state.
• resource URLs
The portlet also may need to create URLs pointing to other resources. The portlet

- 11 -
should also use a specific method of creating URLs in the portlet API to allow the
portal to refine the URL.

3.2.5 Include servlets/JSPs

In both API’s it is possible to include content generated by servlets or JSPs in the portlet
output via including servlets or JSPs. In the IBM Portlet API the include method is
called directly on the portlet context.

IBM PORTLET API: JSP INCLUDE EXAMPLE

PortletContext context = getPortletConfig().getContext();

context.include(someJSP, request, response);

In the JSR 168 the include mechanism is the same as in the servlet API. Via the portlet
context a request dispatcher is retrieved for a given path. On this request dispatcher
object the include method is called.

JSR 168: JSP INCLUDE EXAMPLE

PortletRequestDispatcher rd = getPortletContext().getRequestDispatcher(someJSP);

rd.include(portletRequest, portletResponse);

The IBM Portlet API supports a search mechanism that is not present in the JSR 168 API
to support multiple devices and markups for the included JSP. Another difference is that
the session a JSP retrieves with HttpServetRequest.getSession() in the IBM Portlet
API the portlet session represents and not the original servlet session, whereas in the JSR
168 API the JSP will get the HttpSession as a return value. In order to use the portlet
scope in a JSP that is included via a JSR 168 portlet the JSP should use the portlet API
methods to retrieve the portlet session.

3.2.6 Portlet application packaging

All resources, portlets and the deployment descriptors are packaged together in one web
application archive (WAR file). In the case of portlet applications, there are two
deployment descriptors: one to specify the web application resources (web.xml) and one
to specify the portlet resources (portlet.xml). All web resources that are not portlets
must be specified in the web.xml deployment descriptor. All portlets and portlet related
settings must be specified in an additional file called portlet.xml.

- 12 -
Different from JSR 168 in the IBM Portlet API all portlets must also be listed in the
web.xml, as they are also servlets (see also 3.3.5 for examples of the deployment
descitptors).

3.2.7 Expiration-based caching

Both, IBM Portlet API and JSR 168, allow specifying a time for how long a specific
rendered markup is valid for the current user. This can either be done upfront in the
deployment descriptor or dynamically via an API call.

The API calls to set the expiration time are different between the IBM Portlet API and
JSR 168. The IBM Portlet API uses a polling mechanism where the portal queries the
portlet for how long the markup is still valid, whereas in the JSR 168 the portlet can
attach an expiration time to each created markup.

One feature, called sharing, supported by the IBM Portlet API but not the JSR 168, is
using the same cache entry for all users.

3.3 Concepts that differ

This section covers concepts that significantly differ between the IBM Portlet API and
the JSR 168.

3.3.1 Portlet application entity

Via the deployment descriptor the IBM Portlet API allows the definition of an abstract
portlet application with different instances as concrete portlet applications. Thus settings
of the abstract portlet application can be reused while the unique parts for each concrete
portlet application need to be replaced. Abstract portlet applications consist of abstract
portlets, including the references to the portlet servlet in the web.xml, and concrete
portlet applications of concrete portlets based on the abstract ones. The following
portlet.xml example shows these two different parts:

IBM PORTLET API: PORTLET.XML EXAMPLE

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE portlet-app-def PUBLIC "-//IBM//DTD Portlet Application 1.1//EN"

"portlet_1.1.dtd">

<portlet-app-def>

<portlet-app uid="com.myco.bookmark.1234" major-version="7" minor-version="24">

<portlet-app-name>Bookmark Application7</portlet-app-name>

<portlet id="Portlet_1" href="WEB-INF/web.xml#Servlet_1">

- 13 -
<portlet-name>Bookmark Portlet7</portlet-name>

<allows>

<maximized/>

<minimized/>

</allows>

<supports>

<markup name="html">

<view output="fragment"/>

<edit output="fragment"/>

</markup>

</supports>

</portlet>

</portlet-app>

<concrete-portlet-app uid="com.myco.bookmark.1234.1">

<portlet-app-name>ConcreteSamplets_Bookmark7</portlet-app-name>

<concrete-portlet href="#Portlet_1">

<portlet-name>Bookmark Portlet7</portlet-name>

<default-locale>en</default-locale>

<language locale="en">

<title>My Bookmarks7</title>

<title-short>Bookmarks7</title-short>

<description>Portlet showing your personalized bookmarks</description>

<keywords>bookmarks</keywords>

</language>

<config-param>

<param-name>url.1</param-name>

<param-value>http://www.google.com</param-value>

</config-param>

</concrete-portlet>

- 14 -
</concrete-portlet-app>

</portlet-app-def>

As portlets are servlets in the IBM Portlet API the portlet.xml has references for each
portlet to the servlet in the web.xml that represents the portlet. The web.xml for this
example is:

IBM PORTLET API: WEB.XML EXAMPLE

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE web-app

PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN"

"http://java.sun.com/j2ee/dtds/web-app_2.2.dtd">

<web-app id="WebApp_1">

<display-name>bookmark7</display-name>

<servlet id="Servlet_1">

<servlet-name>Bookmark7</servlet-name>

<servlet-class>com.myco.bookmark.BookmarkPortlet</servlet-class>

<init-param>

<param-name>jsp.view</param-name>

<param-value>bookmarkView.jsp</param-value>

</init-param>

<init-param>

<param-name>jsp.edit</param-name>

<param-value>bookmarkEdit.jsp</param-value>

</init-param>

</servlet>

<servlet-mapping>

<servlet-name>Bookmark7</servlet-name>

<url-pattern>/Bookmark7/*</url-pattern>

</servlet-mapping>

</web-app>

- 15 -
Another result of portlets being servlets is that the initialization parameters of the portlets
need to be specified in the servlet section of the web.xml and not in the portlet.xml.
In the JSR 168 the deployment descriptor is more like the web.xml deployment descriptor
and therefore has not the concept of abstract and concrete applications. The deployment
descriptor defines one portlet application and consists of the portlet definitions for this
application. The JSR 168 deployment descriptor is Schema-based, whereas the IBM
Portlet API deployment descriptor is DTD-based. The following example depicts how the
bookmark portlet.xml example would look like when using the JSR 168 deployment
descriptor format:

JSR 168: PORTLET.XML EXAMPLE

<?xml version="1.0" encoding="UTF-8"?>

<?xml version="1.0"encoding="UTF-8"?>

<portlet-app xmlns="http://java.sun.com/xml/ns/portlet/portlet-app_1_0.xsd" version="1.0"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://java.sun.com/xml/ns/portlet-app_1_0.xsd

http://java.sun.com/xml/ns/portlet/portlet-app_1_0.xsd">

<portlet>

<description xml:lang="EN">Portlet showing your personalized


bookmarks</description>

<portlet-name>Bookmark Portlet7</portlet-name>

<display-name xml:lang="EN">Bookmark Portlet</display-name>

<portlet-class>com.myco.bookmark.BookmarkPortlet</portlet-class>

<init-param>

<name>jsp.view</name>

<value>bookmarkView.jsp</value>

</init-param>

<init-param>

<name>jsp.edit</name>

<value>bookmarkEdit.jsp</value>

</init-param>

<supports>

<mime-type>text/html</mime-type>

<portlet-mode>view</portlet-mode>

- 16 -
<portlet-mode>edit</portlet-mode>

</supports>

<supported-locale>EN</supported-locale>

<portlet-info>

<title>My Bookmarks7</title>

<short-title>Bookmarks7</short-title>

<keywords>bookmarks</keywords>

</portlet-info>

<portlet-preferences>

<preference>

<name>url.1</name>

<value>http://www.google.com</value>

</preference>

</portlet-preferences>

</portlet>

</portlet-app>

Here the initialization parameters are directly specified in the portlet.xml, as portlets are
independent components in the JSR 168.
The following example represents the web.xml for the JSR 168 bookmark portlet:

JSR 168: WEB.XML EXAMPLE

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"

"http://java.sun.com/dtd/web-app_2_3.dtd">

<web-app>

<display-name>Bookmark Application7</display-name>

</web-app>

The only item that needs to be specified in the JSR 168 web.xml is the web application
name that is valid for the whole web application. In the IBM Portlet API example the
application name is specified in the portlet.xml as portlet application name, as there can
be several concrete instances of the same abstract application.

- 17 -
3.3.2 Portlet entity

In the IBM Portlet API there is one portlet object instance per portlet configuration in the
web deployment descriptor. There may be many PortletSettings objects
parameterizing the same portlet object according to the Flyweight pattern, provided on a
per-request basis. A concrete parameterization of a portlet object is referred to as a
concrete portlet in the IBM Portlet API and is defined in the concrete portlet application
(see section 3.3.1). These changes will apply for all portlet instances of this concrete
portlet. Additionally, a user can have personal views of concrete portlets that are rendered
by using the PortletData for customization of the output. Such a personalized concrete
portlet is called concrete portlet instance. The settings of concrete portlets may be
changed by administrators.

The JSR 168 has the concept of an entity that is created based on another entity or based
on the portlet definition in the deployment descriptor of the portlet application (see
section 3.3.1). The relation of entities that are created from other entities is not specified
in the first version of the portlet specification. The entity concept is one item on the list of
enhancements for one of the next JSR versions.

3.3.3 Action and Render Request / Response objects

In the IBM Portlet API the portlet programmer can expect the request / response object
the portlet receives in the render call to be the same as the one received in the action call.
It is therefore possible to set objects into the request in an action and retrieve them in the
sub-sequent render call.

This is no longer possible in the JSR 168. In the JSR 168 action request / response objects
are different from render request / response objects. This modification was done to
support the remote case, where the action and render calls are two distinct SOAP calls
and to enforce the programming pattern of rendering being re-playable. In the JSR 168
the portlet can set parameters that are available in the render call, for all other cases the
session should be used.

3.3.4 Window concept

The JSR 168 defines the concept of a portlet window that has the portlet mode, the
window state and the render parameters attached to it. This decoupling of the portlet
window from the portlet entity allows different windows pointing to the same portlet
instance/entity and these can be in different window states or portlet modes.

The IBM Portlet API only supports a one-to-one relation between the portlet window and
the portlet instance.

- 18 -
3.3.5 Portlet API does not extend servlet API

In the IBM Portlet API portlets extend servlets and all the major interfaces (Request,
Response, Session, …) extend the corresponding servlet interfaces. In the JSR 168
portlets are separate components that may be wrapped as servlets, but do not need to be
servlets.

This decision was made due to the different behavior and capabilities of portlets. As a
portlet is not a servlet in the JSR 168 it is possible to define a clear programming
interface and behavior for portlets.

However, in order to reuse as much as possible of the existing servlet infrastructure, the
JSR 168 leverages functionality provided by the Servlet Specification wherever possible.
This includes deployment, classloading, web applications, web application lifecycle
management, session management and request dispatching. Many concepts and parts of
the portlet API have been modeled like the servlet API.

3.3.6 TAG libraries


The TAG libraries differ significantly between the IBM Portlet API and the JSR 168. The
IBM Portlet API defines a lot of additional tags for internationalization, loops and other
utility functions that overlap with the new Java Standard Tag Library (JSTL). The
existence of JSTL was taken into account when specifying the TAG library for the JSR
168. Therefore the JSR 168 TAG library only consists of the following portlet API
specific tags:
• defineObjects tag – to define the basic portlet API objects RenderRequest,
RenderResponse, and PortletConfig.
• actionURL tag – to create an action URL.
• renderURL tag – to create a render URL.
• namespace tag – to namespace values for a specific portlet.
For all other purposes the JSTL library should be used.

One additional difference is that form parameters now must be not encoded for JSR 168
portlets. If portlets encode form parameters the portlet must also decode the form
parameters, which would lead to portlet code that need to distinguish between request
parameters that are form parameters and request parameters that are URL parameters and
don’t need decoding.

3.4 Concepts new in the JSR 168

The concepts in this section are newly introduced in the JSR 168 and have no counterpart
in IBM Portlet API.

- 19 -
3.4.1 Render parameter

Render parameters are attached to the render request that stay the same for every render
request until a new action occurs. This allows storing navigational state in the render
parameters instead of the session. The portlet should put all state information it needs to
redisplay itself correctly into render parameters (e.g. which screen to render). Render
parameters also enable bookmarkability and solve the browser back button problem.

Render parameters are being reset when the portlet is target of an action. In the action the
portlet can set new render parameters to represent the new navigational state after the
action was performed.

3.4.2 Extension mechanisms

In order to allow vendors to provide additional functionality beyond the current JSR 168,
extension mechanisms are defined in the specification. These extension mechanisms
allow the portlet to use extensions when they are available and still function as a plain
JSR 168 portlet in environments that do not support these extensions. A portlet can query
via the PortalContext object if an extension that it would like to use is supported by the
calling portal.

3.4.2.1 Custom window states

The JSR allows extending the pre-defined window states. In the deployment descriptor
the portlet can declare the custom window states it supports. At deployment time the
portal can map these custom portlet window states to its own custom window states, or it
can ignore them. Via the API the portlet can determine at runtime which custom window
states the portal supports and can adapt accordingly.

3.4.2.2 Custom portlet modes

Like the custom window states, the JSR 168 also allows to define custom portlet modes.
In contrary to the custom window states, the JSR 168 specification already defines a set
of custom portlet modes: About, Config, Edit_defaults, Preview, Print (see section 3.2.2).
A portal is free in defining any additional custom portlet modes.

The portlet can declare in the deployment descriptor the custom portlet modes it supports.
At deployment time the portal can map these custom portlet modes to its own custom
modes, or it can ignore them. Via the API the portlet can determine at runtime which
custom portlet modes the portal supports and can adapt accordingly.

3.4.2.3 Custom user info

In the JSR 168 a portlet can define in the deployment descriptor which user profile
information it wants to access. The specification proposes to use a list of standard P3P
attributes, however the portlet is free to request any additional user information that is not

- 20 -
covered by this attribute list. At deployment time the portal can map the requested user
profile attributes to the supported profile attributes or the portal can ignore the requested
attributes. At runtime the portlet can find out via the API which of the requested user
profile attributes are available.

3.4.2.4 Request / Response properties

Properties can be used by the portal/portlet container to send vendor specific information
to the portlet, and/or the portlet can send vendor specific information to the portal/portlet-
container. These properties are available in the action and the render request / response.
Properties are propagated for includes, but not between the action and render phase.
When including a servlet or JSP, the properties are mapped to headers in the servlet API.

3.4.3 Web application session scope

Both, the JSR 168 API and the IBM Portlet API, have the concept of a session that is
private to the portlet entity. In this scope the portlet can store information that is needed
across user requests. In addition to this session scope the JSR 168 API supports the web
application session scope. In this scope every component of the web application can
access the information. This can be used to share transient information between different
components of the same web application (e.g. between portlets, or between a portlet and
a servlet).

3.4.4 Reuse of the HttpSession listeners

As the JSR 168 reuses the HttpSession it also allows reusing all the session and
attribute listeners that the servlet 2.3 specification defines. The JSR 168 portlet API
provides a PortletSessionUtil class that allows decoding the attributes of the
HttpSession, as these are namespaced in the private portlet session case.

3.4.5 J2EE role support

The JSR 168 allows referencing J2EE roles of the web.xml deployment descriptor in the
portlet.xml deployment descriptor. It also allows checking the role of the user at run-time
and a different behavior depending on this role (e.g. displaying or not displaying a
column with the salary of an employee). Referencing the roles defined in the web.xml
allows using the same J2EE role mapping for portlets as well as for servlets.

3.4.6 Resource bundles

In order to provide localizations of resources like the portlet title, search keywords, or
preference names and descriptions the JSR 168 allows defining a resource bundle in the
deployment descriptor and access methods in the portlet config to access the resource
bundle at run-time.

- 21 -
3.4.7 Multiple response content types

The JSR 168 allows portals to send portlets a list of content types they can choose from
for their response. This allows portals to indicate to portlets that they have transcoding
capabilities. The portlet can retrieve this list via the
PortletRequest.getResponseContentTypes method.

Portlets will only receive content types that they have defined in the deployment
descriptor under the supports section. If the portlet declares support for content types
using wildcards (e.g. “text/*” or “*/*”) in the deployment descriptor, the portlet container
may also set these content types as response content type. Therefore portlets specifying
wildcard content types in the deployment should handle wildcard content types as
response content types accordingly.

3.4.8 Redirect in action

The JSR 168 API enables portlets to do a redirect to other web resources in the action
phase. This allows portlets to process the request from different resources (e.g. an
accounting servlet) in response to an action.

3.4.9 Preference validator

In order to always ensure that the preference set consists of valid values at any time the
portlet can provide a preference validator that needs to be defined in the deployment
descriptor. This validator could incorporate quite complex logic to check cross-
dependencies between different preference properties. The portlet container always calls
the validator before storing a preference set to ensure that only consistent preference sets
are stored.

3.4.10 Portal context

To allow portlets to adapt to the portal that is calling them, the portlet API provides the
PortalContext that can be retrieved from the request. This portal context provides
information such as the portal vendor, version, and specific portal properties. Thus the
portlet may use specific vendor extensions when being called by the vendor’s portal and
fall back to some simpler default behavior when being called by other portals. As the
portal context is attached to the request it may change from request to request. This can
be the case in the remote scenario, where one portlet (WSRP provider) may be called
from different portals (WSRP consumers).

3.4.11 Localization support

The JSR 168 provides means on different levels to allow localizations of deployment
descriptor values and portlet settings. On the deployment descriptor level all settings that
are intended to be viewed or changed by the web server administrator (portlet description,
initialization parameters, display name, etc.) consist of a xml:lang attribute, like the

- 22 -
servlet 2.4 deployment descriptor. Thus the same tag with descriptions in different
languages can be used (e.g. a display name in English, German, and Japan).

On the portlet level the specification allows to set a resource bundle class in the
deployment descriptor that contains the localized versions of the portlet title, short title
for graphically restricted devices, and keywords describing the functionality of the
portlets. In addition to this information the specification also recommends a notation for
localizing the preference attribute display names, values, and descriptions. The portlet
can access the resource bundle via the getResourceBundle method of the
PortletContext.

3.5 Concepts missing in the JSR 168

This section covers concepts that are currently present in the IBM Portlet API, but are not
supported by the JSR 168. Some of these concepts are considered for the next version of
the JSR (see section 4).

3.5.1 Eventing

The IBM Portlet API has the concepts of events. This event concept is based on the
JetSpeed event model, which is similar to the Java event model. The IBM Portlet API
provides the following events:

• ActionEvent
The action event maps to the action phase call in the JSR 168.
• MessageEvent
Message events can be used to send messages between portlets of the same portlet
application (PortletMessage object) or between portlets of different portlet
applications (Strings). Since IBM Portlet API of WebSphere Portal V5, the
recommended method for sending events has been the PropertyBroker service
(see below).
• PortletApplicationSettingsAttributeEvent,
PortletSettingsAttributeEvent
These are events that get fired when attributes for the application or of the portlet
settings change.
• WindowEvent
The portlet will register for window events to get notified if the portlet window is
changed via the window decorations.

3.5.2 Additional lifecycle events

The listener concept of the IBM Portlet API allows the portlet to get notifications not
only for events as described in the section above, but also for events related to the session
lifecycle, event phase lifecycle or render phase lifecycle. The IBM Portlet API provides
the following listeners to implement this functionality:

- 23 -
• PortletPageListener
The page listeners provides the portlet with events for the beginning of the page,
before any markup is written for this page (e.g. to write JavaScript at the
beginning of the page) and the end of the page, after all markup is written.
• PortletSessionListener
The session listener provides the portlet with events for the login and logout of the
user. The portlet can use these events to set up and free resources that are needed
during the whole session. As the JSR 168 is based on the HttpSession and
Servlet Specification 2.3 portlets can use the HttpSessionListeners to get
events when a session is created and destroyed. The main difference to the
PortletSessionListener of the IBM Portlet API is that the portlet session
listener provides the request as parameter for the login.
• EventPhaseListener
The event phase listener notifies the portlet of the beginning and end of the
event/action phase.

3.5.3 Property broker

The property broker service allows in a very generic way to wire together portlets by
using the Observer pattern. Portlets can register themselves to specific events and get
notified when another portlet raises this event, or can raise themselves events. This is a
much more powerful eventing concept than the one described above, where the portlet
needs to hard-code the recipient of the message in the portlet code.

3.5.4 Portlet Menus

The portlet menu service allows the portlet to contribute content to a menu bar to allow
users to easier navigate through portal pages. Figure 4 depicts an example of a portal
page with a menu bar on the left side to give users a fast path to portlets on a specific
page.

- 24 -
Figure 4: Portlet menu example

3.5.5 Portlet Services

The JSR 168 does not consist of the portlet service concept that allows IBM Portlet API
portlets to look-up portal-wide services. Therefore services like the content access service
or the credential vault service are not available for the JSR 168 portlets.

3.5.6 Invalidation-based caching

In IBM Portlet API the portlet can actively invalidate the cache using the invalidate
method on the portlet request as a result of an action. Thus a more fine grained cache
control can be achieved, as the portlet can decide if only the cache content for the current
portlet mode and markup is invalid as a result of this action or the markup for all modes
and markups.

The first version of the portlet specification does not have this fine grained cache control.
In the JSR 168 an action invalidates all cached markup.

- 25 -
3.6 Alignment with WSRP
Special emphasis has been taken by the JSR 168 Expert Group to align the concepts
between JSR 168 and the Web Service for Remote Portlets (WSRP) service.

Concept WSRP JSR 168 Comment


Portlet Mode: View, edit, help + custom view, edit, help + full alignment
indicates portlet in modes custom modes
what mode to
operate for a given
request
Window State: the minimized, normal, minimized, normal, full alignment (“solo” is
state of the window maximized, solo + maximized + missing in the JSR, but can
in which the portlet be implemented as a custom
output will be custom window states custom window state)
displayed states
URL encoding to defines how to create URLs encapsulates URL full alignment (the
allow re-writing to allow re-writing of the creation via a Java implementation of the Java
URLs created by URLs either on consumer or object object can implement the
the portlet producer side WSRP URL rewriting rules)
Namespace defines namespace prefixes provides a Java full alignment (the JSR
encoding to avoid for consumer and producer method to namespace namespace method can
that several portlets side namespacing a String implement the WSRP
on a page namespace behavior)
conflicting with
each other
User – portlet performBlockingInteraction: action: blocking full alignment (action
interaction blocking action processing action processing invocations carried through
operations performBlockingInteraction,
getMarkup: render the render: render the render carried through
markup makup getMarkup)
View state that navigational state render parameter full alignment (WSRP
allows the current navigational state maps to
portlet fragment to JSR render parameters)
be correctly
displayed in sub-
sequent render calls
Storing transient session state concept utilizes the Http web full alignment (the WSRP
state across request implemented via a application session sessionID can be used to
sessionID reference the JSR session)
Storing persistent allows to have properties of provides String-based full alignment (JSR String
state to personalize arbitrary types preferences preferences can be mapped
the rendering of the to WSRP properties)
portlet
Information about RegistrationData provide PortalContext full alignment (all data
the portal calling information of the consumer provide a Java represented through the
the portlet to the producer interface to access PortalContext to the JSR
information about the portlet are available in the
portal calling the RegistrationData)
portlet
Table 1: Comparison WSRP to JSR concepts

- 26 -
Table 1 shows important concepts in the portlet space and how they are realized by both,
the WSRP and JSR 168 specification. As can be seen from this table there is a mapping
of all these concepts between JSR and WSRP. This allows implementing JSR 168 portlet
containers that can be accessed via WSRP and therefore expose JSR 168 portlets as
WSRP services.

Use of WSRP Services in Portals


WSRP Producer
WSRP Consumer

WSRP Service
Proxy
Portlet
Portal WSRP Service

WSRP Service
Aggregated
HTML, WML, VoiceXML, Mark-Up Fragments
... over HTTP Transferred via WSRP

Portal sharing Portlets as WSRP Services


WSRP Consumer WSRP Producer

Server Portlet
Portals WSRP Portal
Portals
Portals Portlet
Portal Wrapper
Portlet
Huge number
Publishing Portal
of users

Figure 5: Integration of WSRP service in the Portal and publishing JSR 168 portlets as WSRP
services
Figure 5 depicts these two scenarios. The upper part shows how a JSR 168 proxy portlet
integrates WSRP services into a JSR 168 based portal. The lower part explains how JSR
168 portlets can be published as WSRP services.

- 27 -
4 Outlook for the next version of the JSR 168
The goal for the first version of the portlet API was to release as early as possible a
standard that supports the functionality needed by 60% of the portlets in the market. This
kept the first version of the portlet API simple and lean, however it also restricts the
portlet programmer in what she or he can do with this API. Especially when comparing
the JSR 168 API with the functionality rich IBM Portlet API the portlet programmer will
notice that a lot of functionality is missing that she or he was used to. Therefore the next
version of the JSR 168 will be submitted soon after JSR 168 finishes, trying to make this
gap smaller.
The following are some of the items currently discussed for the next versions of the JSR
168:
• portlet eventing
The by far most frequent comment the JSR 168 Expert Group received was that
eventing between portlets is missing. This will therefore be addressed by the
follow-on version of the JSR 168. Portlet eventing enables portlets to send events
to the portal and to register at the portal for specific events it is interested in. This
allows to link together portlets from different portlet applications.
• extending the action lifecycle
When eventing is introduced the action lifecycle needs to be extended to allow the
portlet receiving the events it has registered for. In addition to that it may also be
useful for the portlet to get notified when the action phase is starting and when the
action phase is ending to initialize or terminate required resources accordingly.
• portlet entity and portlet window concepts
As discussed previously there is currently no concept of an portlet entity in the
JSR 168. This means that a portlet does not know if it is part of a hierarchy when
it is created, copied, or cloned. For example, portlets may need to change settings
that are specific to an entity when being cloned or free resources when being
destroyed. Therefore introducing lifecycle listeners for the portlet entity and the
portlet window may be introduced with one of the next versions of the Portlet
Specification.
• include new standards
During the time period the JSR 168 was created some other standards evolved
that are of interest for the portlet programmer. JSR 188 was started to define Java
APIs for the CC/PP standard, allowing a portlet to query the client capabilities
and adopting its markup accordingly (e.g. screen size, browser). This API is likely
to be included in the next version of the portlet API.
Also J2EE 1.4 was finalized during this time period. J2EE 1.4 provides some
features that are very useful to portlet programmers, like enhanced logging
capabilities and new listener and filter capabilities. The next version of the JSR
168 will therefore be based on J2EE 1.4.
• caching
The first version of the JSR 168 API is limited to expiration-based caching (see
section 3.2.7). Therefore one goal for the next versions is to enhance the caching

- 28 -
functionality to support validation-based caching to be completely aligned with
WSRP and invalidation-based caching. Portlets then actively invalidate cached
content.
• extending the render lifecycle
In JSR 168 the portlet can contribute content only to the title as a text string and
markup to the portlet window. For some applications this is to restrictive. Portlets
may need to contribute to other parts of the portal page, like the HTTP header or a
navigation bar. Also the restriction to only allow the portlet to insert text in the
title bar is an issue that will be revisited, as portlets may also want to set
additional information, like icons or sound files, for the title.

- 29 -
5 Guidelines for programming IBM Portlet API portlets
The goal of this section is to provide guidelines to program portlets to the IBM Portlet
API and to be able to move these portlets later on to the JSR 168 API without changing
the controller logic.

5.1 Similar Functionality

This section lists functions that are similar between the JSR 168 and IBM Portlet API. By
sticking to this functionality when programming portlets, the migration from a IBM
Portlet API portlet to a JSR 168 portlet is simple and may be even done automatically.

5.1.1 Basic programming model

The basic programming model of the JSR 168 is the same as the one available in WP.
The cornerstones of the programming model are:

• portlets are components


Portlets are components that implement a specific function. Different functions
should be distributed to different portlets.
• distinction between action and render phase
There are two basic request phases: the action phase that processes user actions
and handles the controller logic and the render phase that only produces the
markup.
• usage of the MVC pattern
Use the Model-View-Controller pattern to decouple logic from generating the
markup. This can be done either by implementing the controller logic in the action
and include JSPs in render or by using additional frameworks like Struts or JSF.

5.1.2 Portlet private session

In the private session the portlet can store transient data required by the portlet over
several requests and that are only accessible from this portlet or included resources.

In IBM Portlet API the portlet programmer can directly use the PortletSession and set
an attribute in this session, as the session is portlet specific in the IBM Portlet API.

In JSR 168 the portlet programmer can set an attribute in the PortletSession using the
private scope or the setter method without any scope (like in IBM Portlet API) as per
default the private scope is assumed. However in the JSR 168 the portlet can also set
attributes with global scope that are then accessible for all components in this web
application.

- 30 -
For included JSPs that access the session the HttpServletRequest.getSession() call
in the JSPs called via the IBM Portlet API needs to be replaced when moving to JSR 168
portlets by the RenderRequest.getPortletSession() call. This is due to the fact that
JSPs included via the IBM Portlet API are provided with the portlet session and not the
original HttpSession, whereas JSPs included via the JSR 168 API calling
HttpServletRequest.getSession() will get the HttpSession and therefore need to
access the portlet session via the RenderRequest.

5.1.3 User profile information

The portlet can access user profile information, like name and address, in slightly
different forms in IBM Portlet API and JSR 168. In IBM Portlet API the portlet
programmer can access the user profile information via the User object, whereas in the
JSR 168 the profile information is stored in a map in the request and can be accessed via
the keys defined in P3P.

5.1.4 Persistent data

Portlets can store customization and personalization data persistently. Customization data
are related to the portlet and are valid for all users (e.g. the server name of a news server).
These data can be set via the config mode. One thing to note is that the config mode is
optional in the JSR 168 and may not be supported by every portal. Personalization data
are user specific and personalize the produced markup of the portlet (e.g. which news
topics are of interest).

In the IBM Portlet API customization and personalization data are stored using different
objects: the PortletSettings for customization data and PortletData for
personalization data. Both allow only String values to be stored.

In the JSR 168 customization and personalization data are stored using one object, the
PortletPreferences. If the same setting is defined on both levels, the user level takes
precedence. This has the advantage that in cases where this behavior is needed the portlet
programmer does not need to check in two objects if this setting is set. The drawback is
that the policy user-overwrites-customization-settings can not be changed.

5.1.5 Portlet modes and window states

The basic concepts of portlet modes and window states are the same for the IBM Portlet
API and JSR 168. Portlet modes define different functionalities the portal requests the
portlet to perform. Window states give the portlet hints about the real-estate available for
rendering its content.

The only difference to keep in mind is that in the JSR 168 the IBM Portlet API
CONFIGURE mode is an optional mode in the JSR 168 and may not be supported by all
portals.

- 31 -
Additional window states supported by the IBM Portlet API, like the solo window state,
can be used as custom portlet modes under JSR 168.

5.1.6 Expiration-based caching

Portlets can define either an expiration time for the produced content in the deployment
descriptor or programmatically. In the IBM Portlet API this can be set on a per user basis
or for all users in the deployment descriptor, whereas the JSR 168 only allows setting
expiration times on a per user basis. The programmatic way is slightly different between
the IBM Portlet API and JSR 168: in the IBM Portlet API the portlet gets called before
rendering the output via the getLastModified method and can return a time for how
long the last rendered output will be valid. In the JSR 168 the portlet can set an attribute
in the response declaring an expiration time for the produced response.

5.2 Slightly different functionality

The functionality described in this chapter is not the same, but can be mapped from IBM
Portlet API to the JSR 168 in some cases. Portlets using this functionality with care are to
still portable to the JSR 168.

5.2.1 Sharing of data between portlets

In IBM Portlet API portlets can share data with other portlets either via eventing or using
the property broker service (see chapters 3.5.1, 3.5.3). The portlets can share data with
portlets of the same portlet application or with portlets of different portlet applications.

In the first version of the JSR 168 sharing is very restricted. Portlets can share only data
with other portlets via using the application scope session attributes. Therefore sharing is
restricted to portlets within the same portlet application and portlets cannot notify other
portlets with changed data. Future versions of the portlet specification will enhance the
ability for portlets to share data.

5.2.2 Session listeners

The IBM Portlet API provides the PortletSesionListener to allow a portlet getting
notified when a user logs in or logs out. This functionality is covered in the JSR 168 by
reusing the servlet HttpSessionListener. The difference is that in the login case in
IBM Portlet API the portlet gets access to the request, while in the JSR 168 it gets only
access to the newly created session. If an IBM Portlet API portlet therefore does not use
any request specific methods in the processing of the login it can easily be converted into
a JSR 168 compliant portlet.

5.3 New JSR 168 functionality

This section describes new JSR 168 functionality that requires some re-writing when
portlets are migrated from IBM Portlet API to the JSR 168 API.

- 32 -
5.3.1 Navigational state (render parameters)

Navigational state, which is called render parameters in the JSR 168, should be used by
the portlet to store its transient state that it needs to render itself. This state is reapplied to
the portlet for each subsequent render request until the portlet receives an action. This
navigational state is typically encoded by portals in the URL. In the IBM Portlet API the
developer needs to store this information in the session. Storing the information in
session has the following disadvantages:

• no support of the back button in the browser.


• current state of the portlet is not bookmarkable.
• reduced scalability if a session is required to only store this information, or if the
portlet needs the session for additional data the session size is increased.
• is not compliant with WSRP that also defines the concept of navigational state.

The best way to program new IBM Portlet API portlets to later move to the concept of
navigational state is to decide at design time what the navigational state of this portlet is
and to mark this state information when implementing the portlet. This allows later on to
move to the JSR 168 render parameter concept that is used in the JSR to implement the
navigational state.

5.4 Pitfalls

There are some minor differences between the JSR 168 and the IBM Portlet API that may
lead to wrong behavior when not considered in the design of IBM Portlet API portlets
and later migrate to the JSR 168. These differences are described in this section.

5.4.1 Request / response objects for action and render phase

In the JSR 168 it is clearly stated that the request and response object that the portlet
receives in the action and the render phase may not be the same and that the portlet
programmer therefore should not code the portlet in a way assuming that these objects are
the same. To make this clear both phases get different named request / response objects:
ActionRequest / ActionResponse and RenderRequest / RenderResponse. In some
cases, like the remote case via WSRP, they most likely will be different.

In the IBM Portlet API the request is the same between the action and the render phase
and therefore portlet programmers may be tempted to use the request as a convenient way
to transfer data between the action and render phase. However, this is not only
problematic when migrating to the JSR 168, but also creates other problems, as this
information is no longer available in the next render call. Therefore IBM Portlet API
portlets should not depend on request / response objects being the same in the action and
render phase.

- 33 -
5.4.2 Include search path

The include method in the IBM Portlet API does support an extended search capability
that searches for the included resources by taking the current content type and locale into
account. The JSR 168 include method adheres to the functionality defined by the servlet
specification and therefore does not provide this capability. The IBM Portlet API portlets
that need to be migrated later on to the JSR 168 should therefore not depend on this
implicit search capability.

5.4.3 Form parameter encoding

In the IBM Portlet API form parameters in JSPs are required to be namespace encoded
and are automatically namespace decoded by the portal when the form is submitted. In
the JSR 168 this changed and the portal does no longer decode form parameters. As form
parameters of a POST request can be easily associated to the portlet receiving the action a
namespace encoding is not necessary for JSPs included by JSR 168 portlets.

5.4.4 Title setting

If a portlet wants to set a title dynamically it needs to implement a special listener in the
IBM Portlet API. This listener allows the portlet to write its title directly to the output
stream. The portlet therefore has the capability to produce any output it wants as title. In
the JSR 168 the portlets are bound to set titles as text strings for the first version of the
portlet specification. This should be taken into account when creating new portlets.

- 34 -
6 Examples
This section shows examples for both the IBM Portlet API and the JSR 168 API and
highlights the differences between both. First we’ll take a look at the running example in
order to show the functionality the example provides. The pictures show the JSR 168
example deployed on WebSphere Portal, however the pictures for the IBM Portlet
example would look the same.

Figure 6: View of the deployed Bookmark example


Figure 6 depicts the bookmark sample rendered in View mode after deploying it and
putting it on the page. The example provides two default links that were specified in the
deployment descriptor. When clicking on these links a new browser window is opened
and the URL of the clicked link is rendered in this new browser window. The bookmark
portlet also provides an Edit mode that can be accessed via the pencil button.

Figure 7: Edit mode of the Bookmark example


After clicking on the Edit mode button the portlet renders the Edit view shown in Figure
7.The user can now delete existing bookmarks or add new one. In this example we will
add a new bookmark called WSRP and provide the URL pointing to the WSRP web site
at OASIS.

- 35 -
Figure 8: View mode of the Bookmark portlet after adding the WSRP bookmark
After we press the “Add” button the portlet stores the new bookmark and changes back
from Edit to View mode. The new View mode is rendered and the result is shown in
Figure 8. As can be seen in this picture there is now a third bookmark called WSRP.

We will now show the code for this example for both, the IBM Portlet API and the JSR
168 API. The sample code shows explains how to
• use JSPs for rendering the output
• customize the portlet output taking user specific data into account
• handle actions to allow the user to change these data
We will start with the portlet code and highlight the differences and after that show the
JSPs used to render the View and Edit mode.

6.1 IBM Portlet API Portlet Code


The code will be split into three parts in order to make it easier to explain. The first part
will cover the class definition, init method and the doView method. The second part will
explain the doEdit method and the last part the actionPerformed method.

WP 5 BOOKMARK EXAMPLE - DOVIEW

package com.ibm.wps.samples.wp5;

import java.io.*;

import java.util.*;

import org.apache.jetspeed.portlet.*;

import org.apache.jetspeed.portlet.event.*;

public class IbmBookmark extends PortletAdapter implements ActionListener {

public void init(PortletConfig portletConfig) throws UnavailableException {

super.init(portletConfig);

- 36 -
public void doView(PortletRequest request, PortletResponse response)

throws PortletException, IOException {

String jspName = this.getPortletConfig().getInitParameter("jspView");

getPortletConfig().getContext().include(jspName, request, response);

In the first part the doView method is implemented. In doView the path to the View JSP
is taken from the init parameter defined in the portlet deployment descriptor and the JSP
is included via the include() call.

WP 5 BOOKMARK EXAMPLE - DOEDIT

public void doEdit(PortletRequest request, PortletResponse response)

throws PortletException, IOException {

PortletURI addURI = response.createReturnURI();

addURI.addAction("add");

request.setAttribute("addURI", addURI.toString());

PortletURI cancelURI = response.createReturnURI();

request.setAttribute("cancelURI", cancelURI.toString());

String jspName = this.getPortletConfig().getInitParameter("jspEdit");

getPortletConfig().getContext().include(jspName, request, response);

The second part shows the implementation of the doEdit method. As an example of how
to transfer data between the portlet and the included JSP the “cancel” and “add” URLs
are created inside the portlet and attached to the request before including the Edit JSP.
Both URLs are from type “ReturnURI” which will set the portlet into the portlet mode
before the user clicked on the Edit button. In a real-world application the JSP would
create these URLs.

WP 5 BOOKMARK EXAMPLE - ACTIONPERFORMED

- 37 -
public void actionPerformed(ActionEvent event) throws PortletException {

PortletRequest request = event.getRequest();

String action = event.getActionString();

PortletLog log = getPortletLog();

if ( action!=null ) {

try {

if (action.equals("removeURI")) {

String removeName = request.getParameter("remove");

PortletData portData = request.getData();

portData.removeAttribute(removeName);

portData.store();

if (action.equals("add")){

PortletData portData = request.getData();

String name = request.getParameter("name");

String value = request.getParameter("value");

portData.setAttribute(name, value);

portData.store();

catch ( AccessDeniedException ade ) {

log.error("AccessDeniedException occured when adding or deleting a bookmark.");

catch ( IOException ioe ) {

log.error("An IO error occured when trying to add or delete a bookmark.");

- 38 -
}

The third part shows the action handling. The actionPerformed method is called when the
user clicks on one of the buttons “add” or “delete”. In order to distinguish between these
two the portlet first retrieves the action string from the event and compares it two the two
different actions “add” or “removeURI”. If the user has clicked on the “remove” button
the corresponding link is removed from the portlet data, whereas if “add” was clicked the
data entered by the user is added to the portlet data.

6.2 JSR 168 Portlet Code


We have taken the above IBM Portlet API portlet and change it, so that it runs under the
JSR 168. The changed text is marked in bold.

JSR 168 BOOKMARK EXAMPLE - DOVIEW

package com.ibm.wps.samples.jsr;

import java.io.*;

import javax.portlet.*;

public class Bookmark extends GenericPortlet {

public void init(PortletConfig config) throws PortletException{

super.init(config);

public void doView(RenderRequest request, RenderResponse response)

throws PortletException, IOException{

response.setContentType("text/html");

String jspName = getPortletConfig().getInitParameter("jspView");

PortletRequestDispatcher rd = getPortletContext().getRequestDispatcher(jspName);

rd.include(request,response);

- 39 -
The JSR 168 bookmark example now extends the GenericPortlet that provides
similar functionality like the PortletAdapter from the IBM Portlet API. Implementing
a listener for receiving the action events is no longer required, as the action handling is
integrated into the base portlet interface. In the doView method two differences show up:
first the response content type is set. This is necessary in the JSR 168, as the portal can
provide the portlet a list of valid response content types and therefore the portlet need to
specify which of this list it has chosen. The second one is including of the JSP. The JSR
168 uses the concept of a request dispatcher for this in analogy to the servlet API.

JSR 168 BOOKMARK EXAMPLE - DOEDIT

public void doEdit(RenderRequest request, RenderResponse response)

throws PortletException, IOException{

response.setContentType("text/html");

PortletURL addUrl = response.createActionURL();

addUrl.setPortletMode(PortletMode.VIEW);

addUrl.setParameter("add","add");

request.setAttribute("addUrl",addUrl.toString());

PortletURL cancelUrl = response.createRenderURL();

cancelUrl.setPortletMode(PortletMode.VIEW);

request.setAttribute("cancelUrl",cancelUrl.toString());

String jspName = getPortletConfig().getInitParameter("jspEdit");

PortletRequestDispatcher rd = getPortletContext().getRequestDispatcher(jspName);

rd.include(request,response);

In the doEdit method there is besides the differences already mentioned in the doView
section a slightly different code section for creating the URLs. As mentioned before the
JSR 168 supports two different types of URLs: one that triggers the action processing and
one that only sets new navigational state. For the “add” button URL an action URL is
created as we need to store the user input of the add form persistently. For the “cancel”
button only a render URL is needed as here we only need to switch back to the View
mode.

- 40 -
JSR 168 BOOKMARK EXAMPLE - PROCESSACTION

public void processAction(ActionRequest request, ActionResponse response)

throws PortletException, IOException{

try{

String removeName = request.getParameter("remove");

if (removeName != null){

PortletPreferences prefs = request.getPreferences();

prefs.reset(removeName);

prefs.store();

String add = request.getParameter("add");

if (add != null){

PortletPreferences prefs = request.getPreferences();

String name = request.getParameter("name");

String value = request.getParameter("value");

prefs.setValue(name, value);

prefs.store();

catch ( IOException ioe ) {

getPortletContext.log("An IO error occured when trying to remove a bookmark.");

catch ( PortletException pe ) {

getPortletContext.log("A portlet exception was thrown when trying to remove a

bookmark.");

- 41 -
}

The main differences for the action handling are that first the JSR 168 portlet does not get
an action event, but an action request and an action response. Due to this, the portlet
needs to check if a specific action occurred by looking at the request parameters. Another
difference is that the portlet data of the IBM Portlet API are named portlet preferences in
the JSR 168 API and have different names for setting and removing values.

To summarize the major differences to the IBM Portlet API version of the portlet are:
• Portlet URLs
The JSR 168 API uses two types of portlet URLs (action and render URLs) to
which specific portlet modes can be assigned, whereas the IBM Portlet API uses
return URIs to create links to the previous portlet mode.
• Request dispatcher usage
The request dispatcher usage differs slightly between JSR 168 and WP, as the JSR
168 API uses the same mechanism as the servlet API to get a request dispatcher
from the context with the path as parameter.
• Persistent portlet data
The JSR 168 persistent data, PortletPreferences, have an API similar to the
JDK 1.4 Preferences and allows specifying a default value for the get methods.
The default value allows to get rid of the code parts that check for a null return
value and explicitly sets a default value. The JSR 168 only allows String and
String arrays as values of preferences and not arbitrary objects like the IBM
Portlet API.
• Action handling
The action handling in the JSR 168 is simplified and does not need specific action
objects to be created. By creating an action URL this URL automatically triggers
a call to the processAction method.
After covering the portlet code we will now take a look at the included JSPs and how
they differ.

6.3 IBM Portlet API JSPs


This section coves the View and Edit JSP that are include by the IBM Portlet API portlet
for the View mode and the Edit mode to produce the HTML markup for these views.

IBM PORTLET API VIEW JSP

<%@ page contentType="text/html" import="java.util.*, com.ibm.wps.samples.wp5.*,

org.apache.jetspeed.portlet.*" session="false"%>

<%@ taglib uri="/WEB-INF/tld/portlet.tld" prefix="portletAPI" %>

- 42 -
<portletAPI:init/>

<p class="wpsPortletHead"><portletAPI:text key="available_bookmarks"

bundle="nls.Text">Available Bookmarks</portletAPI:text></p>

<%

PortletData prefs = portletRequest.getData();

Enumeration e = prefs.getAttributeNames();

if (!e.hasMoreElements()) { // no bookmarks

%>

<p><portletAPI:text key="no_bookmarks" bundle="nls.Text">No

bookmarks</portletAPI:text></p>

<% }

else{

%>

<p class="wpsIndentMedium">

<% }

while (e.hasMoreElements()) {

String name = (String)e.nextElement();

String value = (String)prefs.getAttribute(name);

%>

<a href=<%=value%> target="_blank"><%=name%></a><br />

<%

%>

</p>

The View JSP first call portletAPI:init to get access to the portlet objects. After that it
starts to render the table with the bookmarks. The bookmark names and URLs are
retrieved from the portlet data. All text messages are localized using a specific IBM
Portlet API tag. Also the headings are created with specific IBM Portlet API tags.

- 43 -
IBM PORTLET API EDIT JSP

<%@ page contentType="text/html" import="java.util.*,

com.ibm.wps.samples.wp5.*,org.apache.jetspeed.portlet.*" session="false"%>

<%@ taglib uri="/WEB-INF/tld/portlet.tld" prefix="portletAPI" %>

<jsp:useBean id="addURI" class="java.lang.String" scope="request" />

<jsp:useBean id="cancelURI" class="java.lang.String" scope="request" />

<portletAPI:init/>

<h4><portletAPI:text key="available_bookmarks" bundle="nls.Text">Available

Bookmarks</portletAPI:text></h4>

<table class="wpsTable">

<tr class="wpsTableRow">

<th class="portlet-table-header"><portletAPI:text key="name" bundle="nls.Text"/></th>

<th class="portlet-table-header"><portletAPI:text key="url" bundle="nls.Text"/></th>

<td></td>

</tr>

<%

PortletData prefs = portletRequest.getData();

Enumeration e = prefs.getAttributeNames();

if (!e.hasMoreElements()) { // no bookmarks

%>

<p><portletAPI:text key="no_bookmarks" bundle="nls.Text">No

bookmarks</portletAPI:text></p>

<% }

else{

while (e.hasMoreElements()) {

- 44 -
String name = (String)e.nextElement();

String value = (String)prefs.getAttribute(name);

%>

<tr class="wpsTableRow">

<td> <%=name%> </td>

<td> <%=value%> </td>

<td> <a href="<portletAPI:createURI><portletAPI:URIAction

name='removeURI'/><portletAPI:URIParameter name='remove'

value='<%=name%>'/></portletAPI:createURI>">

(<portletAPI:text key="delete" bundle="nls.Text"/>)</a>

</td>

</tr>

<%

%>

<form action="<%=addURI%>" method="POST">

<tr class="wpsTableRow">

<td><input name="<portletAPI:encodeNamespace value='name'/>" type="text"

class="portlet-form-input-field"></td>

<td><input name="<portletAPI:encodeNamespace value='value'/>" type="text"

class="portlet-form-input-field"></td>

<td><input name="<portletAPI:encodeNamespace value='add'/>" type="submit"

value='<portletAPI:text key="add" bundle="nls.Text"/>' class="portlet-form-button"></td>

</tr>

</form>

</table>

- 45 -
<form action="<%=cancelURI%>" method="post">

<input name="<portletAPI:encodeNamespace value='cancel'/>" type="submit"

value="<portletAPI:text key="cancel" bundle="nls.Text"/>" class="portlet-form-button">

</form>

The Edit JSP also produces a table with the current bookmarks. However, this one
include the URL in the table and the last row has a “delete” button for which an URL
with the action “removeURI” is created with a portlet API specific tag. Finally on the
bottom the add from is added and the add URL is retrieved from the request. Also the
cancel URL is retrieved for the “cancel” button from the request.

6.4 JSR 168 JSPs


This section will show the JSR 168 View and Edit JSPs and highlight the difference in
regard to the JSPs for the IBM Portlet API.

JSR 168 VIEW JSP

<%@ page import="javax.portlet.*, java.util.*" session="false"%>

<%@ taglib uri="http://java.sun.com/portlet" prefix="portletAPI" %>

<%@ taglib prefix="fmt" uri="http://java.sun.com/jstl/fmt" %>

<portletAPI:defineObjects />

<fmt:setBundle basename="nls.Text"/>

<%

ResourceBundle myText = ResourceBundle.getBundle("nls.Text", request.getLocale());

%>

<h4><fmt:message key="available_bookmarks"/></h4>

<%

PortletPreferences prefs = renderRequest.getPreferences();

Enumeration e = prefs.getNames();

if (!e.hasMoreElements()) { // no bookmarks

%>

<p><fmt:message key="no_bookmarks"/></p>

- 46 -
<% }

else{

%>

<p>

<% }

while (e.hasMoreElements()) {

String name = (String)e.nextElement();

String value = prefs.getValue(name,"<"+myText.getString("undefined")+">");

%>

<a href=<%=value%> target="_blank"><%=name%></a><br />

<%

%>

</p>

The JSR 168 View JSP is slightly different from the IBM Portlet API View JSP. First it
does not use proprietary tags for the headings, but stick to the HTML tags for different
levels of headers. Second it uses the Java Standard Tag Library (JSTL) for localization.
And third the bookmarks are of course accessed via the portlet preferences API and not
the portlet data API of the IBM Portlet API. Of course the IBM Portlet API portlet could
have also used the JSTL library, which would result in the same tags fmt:message used
also in the IBM Portlet API portlet and the default HTML tags for headings. In this case
only the preferences access would have been different.

JSR 168 EDIT JSP

<%@ page import="javax.portlet.*, java.util.*" session="false" %>

<%@ taglib uri="http://java.sun.com/portlet" prefix="portletAPI" %>

<%@ taglib prefix="fmt" uri="http://java.sun.com/jstl/fmt" %>

<jsp:useBean id="addUrl" scope="request" class="java.lang.String" />

<jsp:useBean id="cancelUrl" scope="request" class="java.lang.String" />

- 47 -
<portletAPI:defineObjects/>

<%

ResourceBundle myText = ResourceBundle.getBundle("nls.Text", request.getLocale());

%>

<fmt:setBundle basename="nls.Text"/>

<h4><fmt:message key="available_bookmarks"/></h4>

<table class="wpsTable">

<tr class="wpsTableRow">

<th class="wpsTableHead"><fmt:message key="name"/></th>

<th class="wpsTableHead"><fmt:message key="url"/></th>

<td></td>

</tr>

<%

PortletPreferences prefs = renderRequest.getPreferences();

Enumeration e = prefs.getNames();

if (!e.hasMoreElements()) { // no bookmarks

%>

<p><fmt:message key="no_bookmarks"/></p>

<% }

else{

while (e.hasMoreElements()) {

String name = (String)e.nextElement();

String value = prefs.getValue(name,"<"+myText.getString("undefined")+">");

%>

<tr class="wpsTableRow">

<td> <%=name%> </td>

<td> <%=value%> </td>

- 48 -
<td> <portletAPI:actionURL var="removeUrl">

<portletAPI:param name="remove" value="<%=name%>"/>

</portletAPI:actionURL>

<a href="<%=removeUrl.toString()%>">(<fmt:message key="delete"/>)</a>

</td>

</tr>

<%

%>

<form action="<%=addUrl%>" method="POST">

<tr class="wpsTableRow">

<td><input name="name" type="text" class="portlet-form-input-field"></td>

<td><input name="value" type="text" class="portlet-form-input-field"></td>

<td><input name="add" type="submit" value='<fmt:message key="add"/>'

class="portlet-form-button"></td>

</tr>

</form>

</table>

<form action="<%=cancelUrl%>" method="post">

<input name="cancel" type="submit" value="<fmt:message key="cancel"/>" class="portlet-

form-button">

</form>

For the Edit JSP we assume that the IBM Portlet API Edit JSP would have also used the
standard HTML tags for headings and the JSTL tag library for localization and highlight
only the remaining differences. Besides differences in the preferences handling already
mentioned here another small difference shows up: in the JSR 168 preferences API you

- 49 -
can specify a default value, like in the JDK 1.4 preferences API, that is returned in case
no value for the requested key exists. As mentioned before the URL generation is
different for JSR 168 portlets. As the JSR 168 tag library was modeled after the JSTL tag
library it is also possible to assign the value of a tag to a variable as shown above.
Finally, as mentioned in the pitfalls sections, the form parameters do not need to be
encoded for JSPs included by JSR 168 portlets.

- 50 -
7 Summary
With the JSR 168 finally a standard Portlet API exists that enables programming portlets
independently from portal vendors and running the same portlet unchanged on different
portals. The concepts of the JSR 168 are closely aligned with the IBM Portlet API, but
have a more restricted functionality than the IBM Portlet API, as it is the first version.
Developers familiar with the IBM Portlet API should not have difficulties using the JSR
168 API quickly.

In order to support the existing IBM portlets and as the IBM Portlet API is more function
rich than the JSR 168 API, the IBM Portlet API will still be supported in future versions
of the IBM WebSphere Portal server. Therefore there is no need to migrate existing
portlets.

This whitepaper describes in detail the differences between both and how to get from the
IBM Portlet API to the JSR 168. My recommendation about which Portlet API to use is
two-fold: for existing portlets there is no need to migrate to the JSR 168 as the IBM
Portlet API will still be supported in future WebSphere Portal versions. A reason for
migrating existing portlets to the JSR 168 can be to provide this portlet also for other
portals.

For new portlets the recommendation would be to use the JSR 168 API when this
functionality is enough to implement the portlet, or when the portlet should be published
as Web Service for Remote Portlets (WSRP) service. As the JSR 168 and WSRP were
closely aligned it is possible to publish a JSR 168 portlet as WSRP service. If the portlet
needs more functionality then the JSR 168 can provide (e.g. eventing) the IBM Portlet
API still needs to be used.

Trademarks

• IBM, and WebSphere are trademarks or registered trademarks of IBM Corporation in


the United States, other countries, or both.
• Java and all Java-based trademarks and logos are trademarks or registered trademarks
of Sun Microsystems, Inc. in the United States, other countries, or both.
• Other company, product, and service names may be trademarks or service marks of
others.

IBM copyright and trademark information: http://www.ibm.com/legal/copytrade.phtml

- 51 -

S-ar putea să vă placă și