Documente Academic
Documente Profesional
Documente Cultură
Version 1.0
Stefan Hepper
IBM Corporation
sthepper@de.ibm.com
-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.
-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.
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
Portlet
(App)
HTML, WML, VoiceXML, ...
Portal
Portlet API
Portlet/Servlet
Web
HTTP
Container Portlet
Application (App)
Portlet Provider SPI
Portlet
(App)
-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.
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).
<Title> Edit ?
<Title> Edit ?
Portlet content
<Title> Edit ?
Portlet content
Markup Fragments
-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.
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.
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.
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.
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:
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:
-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:
However, the JSR 168 allows the portal to define additional window states.
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.
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.
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.
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.
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.
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).
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.
This section covers concepts that significantly differ between the IBM Portlet API and
the JSR 168.
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:
"portlet_1.1.dtd">
<portlet-app-def>
<portlet-app-name>Bookmark Application7</portlet-app-name>
- 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>
<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:
<!DOCTYPE web-app
"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:
<?xml version="1.0"encoding="UTF-8"?>
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>
<portlet-name>Bookmark Portlet7</portlet-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:
"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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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).
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.
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.
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.
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.
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.
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).
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.
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.
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.
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.
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
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.
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.
- 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.
WSRP Service
Proxy
Portlet
Portal WSRP Service
WSRP Service
Aggregated
HTML, WML, VoiceXML, Mark-Up Fragments
... over HTTP Transferred via WSRP
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.
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.
The basic programming model of the JSR 168 is the same as the one available in WP.
The cornerstones of the programming model are:
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.
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.
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.
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.
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.
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.
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.
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.
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:
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.
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.
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.
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.
- 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.
package com.ibm.wps.samples.wp5;
import java.io.*;
import java.util.*;
import org.apache.jetspeed.portlet.*;
import org.apache.jetspeed.portlet.event.*;
super.init(portletConfig);
- 36 -
public void doView(PortletRequest request, PortletResponse 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.
addURI.addAction("add");
request.setAttribute("addURI", addURI.toString());
request.setAttribute("cancelURI", cancelURI.toString());
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.
- 37 -
public void actionPerformed(ActionEvent event) throws PortletException {
if ( action!=null ) {
try {
if (action.equals("removeURI")) {
portData.removeAttribute(removeName);
portData.store();
if (action.equals("add")){
portData.setAttribute(name, value);
portData.store();
- 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.
package com.ibm.wps.samples.jsr;
import java.io.*;
import javax.portlet.*;
super.init(config);
response.setContentType("text/html");
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.
response.setContentType("text/html");
addUrl.setPortletMode(PortletMode.VIEW);
addUrl.setParameter("add","add");
request.setAttribute("addUrl",addUrl.toString());
cancelUrl.setPortletMode(PortletMode.VIEW);
request.setAttribute("cancelUrl",cancelUrl.toString());
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
try{
if (removeName != null){
prefs.reset(removeName);
prefs.store();
if (add != null){
prefs.setValue(name, value);
prefs.store();
catch ( PortletException pe ) {
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.
org.apache.jetspeed.portlet.*" session="false"%>
- 42 -
<portletAPI:init/>
bundle="nls.Text">Available Bookmarks</portletAPI:text></p>
<%
Enumeration e = prefs.getAttributeNames();
if (!e.hasMoreElements()) { // no bookmarks
%>
bookmarks</portletAPI:text></p>
<% }
else{
%>
<p class="wpsIndentMedium">
<% }
while (e.hasMoreElements()) {
%>
<%
%>
</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
com.ibm.wps.samples.wp5.*,org.apache.jetspeed.portlet.*" session="false"%>
<portletAPI:init/>
Bookmarks</portletAPI:text></h4>
<table class="wpsTable">
<tr class="wpsTableRow">
<td></td>
</tr>
<%
Enumeration e = prefs.getAttributeNames();
if (!e.hasMoreElements()) { // no bookmarks
%>
bookmarks</portletAPI:text></p>
<% }
else{
while (e.hasMoreElements()) {
- 44 -
String name = (String)e.nextElement();
%>
<tr class="wpsTableRow">
name='removeURI'/><portletAPI:URIParameter name='remove'
value='<%=name%>'/></portletAPI:createURI>">
</td>
</tr>
<%
%>
<tr class="wpsTableRow">
class="portlet-form-input-field"></td>
class="portlet-form-input-field"></td>
</tr>
</form>
</table>
- 45 -
<form action="<%=cancelURI%>" method="post">
</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.
<portletAPI:defineObjects />
<fmt:setBundle basename="nls.Text"/>
<%
%>
<h4><fmt:message key="available_bookmarks"/></h4>
<%
Enumeration e = prefs.getNames();
if (!e.hasMoreElements()) { // no bookmarks
%>
<p><fmt:message key="no_bookmarks"/></p>
- 46 -
<% }
else{
%>
<p>
<% }
while (e.hasMoreElements()) {
%>
<%
%>
</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.
- 47 -
<portletAPI:defineObjects/>
<%
%>
<fmt:setBundle basename="nls.Text"/>
<h4><fmt:message key="available_bookmarks"/></h4>
<table class="wpsTable">
<tr class="wpsTableRow">
<td></td>
</tr>
<%
Enumeration e = prefs.getNames();
if (!e.hasMoreElements()) { // no bookmarks
%>
<p><fmt:message key="no_bookmarks"/></p>
<% }
else{
while (e.hasMoreElements()) {
%>
<tr class="wpsTableRow">
- 48 -
<td> <portletAPI:actionURL var="removeUrl">
</portletAPI:actionURL>
</td>
</tr>
<%
%>
<tr class="wpsTableRow">
class="portlet-form-button"></td>
</tr>
</form>
</table>
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
- 51 -