difference bw jsr168 and ibm

51
Portlet API comparison white paper: JSR 168 Java Portlet Specification compared to the IBM Portlet API Version 1.0 Stefan Hepper IBM Corporation [email protected] Published June 28, 2004 © Copyright International Business Machines Corporation 2004. All rights reserved. - 1 -

Upload: api-26781487

Post on 11-Apr-2015

433 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Difference Bw Jsr168 and Ibm

Portlet API comparison white paper JSR 168 Java Portlet Specification compared to the IBM Portlet API

Version 10

Stefan Hepper IBM Corporation

sthepperdeibmcom

Published June 28 2004

copy 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

31 Basic concepts 6 311 Portal 6 312 Portal page 7 313 Portlet 8 314 Portlet Container 8

32 Concepts that are the same 8 321 Portlet mode 8 322 Window state 9 323 Portlet life cycle and request processing 10 324 URL encoding 11 325 Include servletsJSPs 12 326 Portlet application packaging 12 327 Expiration-based caching 13

33 Concepts that differ 13 331 Portlet application entity 13 332 Portlet entity 18 333 Action and Render Request Response objects 18 334 Window concept 18 335 Portlet API does not extend servlet API 19 336 TAG libraries 19

34 Concepts new in the JSR 168 19 341 Render parameter 20 342 Extension mechanisms 20 343 Web application session scope 21 344 Reuse of the HttpSession listeners 21 345 J2EE role support 21 346 Resource bundles 21 347 Multiple response content types 22 348 Redirect in action 22 349 Preference validator 22 3410 Portal context 22 3411 Localization support 22

35 Concepts missing in the JSR 168 23 351 Eventing 23 352 Additional lifecycle events 23 353 Property broker 24 354 Portlet Menus 24 355 Portlet Services 25 356 Invalidation-based caching 25

36 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 -

51 Similar Functionality 30 511 Basic programming model 30 512 Portlet private session 30 513 User profile information 31 514 Persistent data 31 515 Portlet modes and window states 31 516 Expiration-based caching 32

52 Slightly different functionality 32 521 Sharing of data between portlets 32 522 Session listeners 32

53 New JSR 168 functionality 32 531 Navigational state (render parameters) 33

54 Pitfalls 33 541 Request response objects for action and render phase 33 542 Include search path 34 543 Form parameter encoding 34 544 Title setting 34

6 Examples 35 61 IBM Portlet API Portlet Code 36 62 JSR 168 Portlet Code 39 63 IBM Portlet API JSPs 42 64 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 copy 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 Javatrade 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 IBMreg WebSpherereg Portal Version 50 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 Javatrade 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 httpjcporg 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 httpjcporgenjsrdetailid=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

31 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

311 Portal

A portal is a web based application that ndashcommonly ndash 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

PortalWeb

ApplicationHTTP

HTML

WML

Voi

ceXM

L

Portl

et In

voke

r API Portlet

(App)Po

rtlet

API

Portlet(App)

Portlet(App)

PortletServletContainer

Portl

et P

rovid

er S

PI

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

312 Portal page

Figure 2

Figure 2 Basic portal page components

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 (eg maximize or minimize the portlet) and buttons to change the mode of a portlet (eg show help or edit the predefined portlet settings)

ltTitlegt Edit

Portlet content

Portal page

Portletwindows

Window states Portlet modes

Markup Fragments

ltTitlegt Edit

ltTitlegt Edit

Portlet content

Portlet content

- 7 -

313 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 (eg 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 requestresponse 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 users interactions

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

314 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

32 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

321 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

bull Edit ndash to display one or more personalization views that let the user personalize portlet settings

bull Help ndash to display help views bull View ndash to display the portlet output bull Configure ndash 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

bull required to support (same semantic as above) o Edit o Help o View

bull optional custom modes o About ndash to display information on the portlets purpose origin version etc o Config ndash has the same semantic as the IBM Portlet API configure mode o Edit_defaults ndash to set the default values for the modifiable preferences that

are typically changed in the EDIT screen o Preview ndash to render output without the need of having back-end

connections or user specific data available o Print ndash to display a view that is suitable for printing

bull portal vendor specific modes that are available only in a portal of a specific vendor

322 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

bull Closed (deprecated) ndash to indicate that a window should be closed bull Detached (deprecated) ndash to indicate that a window should be detached bull Maximized ndash to indicate that a window has more real estate to render its output

then in normal window state

- 9 -

bull Minimized ndash to indicate that the portlet is minimized and cannot render any output

bull Moving (deprecated) ndash to indicate that the portlet window has been moved bull Normal ndash to indicate that the portlet is sharing its screen with other portlets on a

page bull Resizing (deprecated) ndash to indicate that the portlet has been resized bull Solo ndash to indicate that the portlet is the only portlet on the page

Whereas the JSR 168 has only the following mandatory window states

bull Maximized ndash same as in the IBM Portlet API bull Minimized ndash to indicate that the portlet should only render minimal or no output bull Normal ndash same as in the IBM Portlet API

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

323 Portlet life cycle and request processing

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

bull init ndash to initialize the portlet and put the portlet into service bull handle requests ndash process different kinds of action and render requests bull destroy ndash 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

324 URL encoding

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

bull 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

bull 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

325 Include servletsJSPs

In both APIrsquos 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()

contextinclude(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)

rdinclude(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 HttpServetRequestgetSession() 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

326 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 (webxml) and one to specify the portlet resources (portletxml) All web resources that are not portlets must be specified in the webxml deployment descriptor All portlets and portlet related settings must be specified in an additional file called portletxml

- 12 -

Different from JSR 168 in the IBM Portlet API all portlets must also be listed in the webxml as they are also servlets (see also 335 for examples of the deployment descitptors)

327 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

33 Concepts that differ

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

331 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 webxml and concrete portlet applications of concrete portlets based on the abstract ones The following portletxml example shows these two different parts

IBM PORTLET API PORTLETXML EXAMPLE

ltxml version=10 encoding=UTF-8gt

ltDOCTYPE portlet-app-def PUBLIC -IBMDTD Portlet Application 11EN

portlet_11dtdgt

ltportlet-app-defgt

ltportlet-app uid=commycobookmark1234 major-version=7 minor-version=24gt

ltportlet-app-namegtBookmark Application7ltportlet-app-namegt

ltportlet id=Portlet_1 href=WEB-INFwebxmlServlet_1gt

- 13 -

ltportlet-namegtBookmark Portlet7ltportlet-namegt

ltallowsgt

ltmaximizedgt

ltminimizedgt

ltallowsgt

ltsupportsgt

ltmarkup name=htmlgt

ltview output=fragmentgt

ltedit output=fragmentgt

ltmarkupgt

ltsupportsgt

ltportletgt

ltportlet-appgt

ltconcrete-portlet-app uid=commycobookmark12341gt

ltportlet-app-namegtConcreteSamplets_Bookmark7ltportlet-app-namegt

ltconcrete-portlet href=Portlet_1gt

ltportlet-namegtBookmark Portlet7ltportlet-namegt

ltdefault-localegtenltdefault-localegt

ltlanguage locale=engt

lttitlegtMy Bookmarks7lttitlegt

lttitle-shortgtBookmarks7lttitle-shortgt

ltdescriptiongtPortlet showing your personalized bookmarksltdescriptiongt

ltkeywordsgtbookmarksltkeywordsgt

ltlanguagegt

ltconfig-paramgt

ltparam-namegturl1ltparam-namegt

ltparam-valuegthttpwwwgooglecomltparam-valuegt

ltconfig-paramgt

ltconcrete-portletgt

- 14 -

ltconcrete-portlet-appgt

ltportlet-app-defgt

As portlets are servlets in the IBM Portlet API the portletxml has references for each portlet to the servlet in the webxml that represents the portlet The webxml for this example is

IBM PORTLET API WEBXML EXAMPLE

ltxml version=10 encoding=UTF-8gt

ltDOCTYPE web-app

PUBLIC -Sun Microsystems IncDTD Web Application 22EN

httpjavasuncomj2eedtdsweb-app_22dtdgt

ltweb-app id=WebApp_1gt

ltdisplay-namegtbookmark7ltdisplay-namegt

ltservlet id=Servlet_1gt

ltservlet-namegtBookmark7ltservlet-namegt

ltservlet-classgtcommycobookmarkBookmarkPortletltservlet-classgt

ltinit-paramgt

ltparam-namegtjspviewltparam-namegt

ltparam-valuegtbookmarkViewjspltparam-valuegt

ltinit-paramgt

ltinit-paramgt

ltparam-namegtjspeditltparam-namegt

ltparam-valuegtbookmarkEditjspltparam-valuegt

ltinit-paramgt

ltservletgt

ltservlet-mappinggt

ltservlet-namegtBookmark7ltservlet-namegt

lturl-patterngtBookmark7lturl-patterngt

ltservlet-mappinggt

ltweb-appgt

- 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 webxml and not in the portletxml In the JSR 168 the deployment descriptor is more like the webxml 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 portletxml example would look like when using the JSR 168 deployment descriptor format

JSR 168 PORTLETXML EXAMPLE

ltxml version=10 encoding=UTF-8gt

ltxml version=10encoding=UTF-8gt

ltportlet-app xmlns=httpjavasuncomxmlnsportletportlet-app_1_0xsd version=10

xmlnsxsi=httpwwww3org2001XMLSchema-instance

xsischemaLocation=httpjavasuncomxmlnsportlet-app_1_0xsd

httpjavasuncomxmlnsportletportlet-app_1_0xsdgt

ltportletgt

ltdescription xmllang=ENgtPortlet showing your personalized

bookmarksltdescriptiongt

ltportlet-namegtBookmark Portlet7ltportlet-namegt

ltdisplay-name xmllang=ENgtBookmark Portletltdisplay-namegt

ltportlet-classgtcommycobookmarkBookmarkPortletltportlet-classgt

ltinit-paramgt

ltnamegtjspviewltnamegt

ltvaluegtbookmarkViewjspltvaluegt

ltinit-paramgt

ltinit-paramgt

ltnamegtjspeditltnamegt

ltvaluegtbookmarkEditjspltvaluegt

ltinit-paramgt

ltsupportsgt

ltmime-typegttexthtmlltmime-typegt

ltportlet-modegtviewltportlet-modegt

- 16 -

ltportlet-modegteditltportlet-modegt

ltsupportsgt

ltsupported-localegtENltsupported-localegt

ltportlet-infogt

lttitlegtMy Bookmarks7lttitlegt

ltshort-titlegtBookmarks7ltshort-titlegt

ltkeywordsgtbookmarksltkeywordsgt

ltportlet-infogt

ltportlet-preferencesgt

ltpreferencegt

ltnamegturl1ltnamegt

ltvaluegthttpwwwgooglecomltvaluegt

ltpreferencegt

ltportlet-preferencesgt

ltportletgt

ltportlet-appgt

Here the initialization parameters are directly specified in the portletxml as portlets are independent components in the JSR 168 The following example represents the webxml for the JSR 168 bookmark portlet

JSR 168 WEBXML EXAMPLE

ltxml version=10 encoding=UTF-8gt

ltDOCTYPE web-app PUBLIC -Sun Microsystems IncDTD Web Application 23EN

httpjavasuncomdtdweb-app_2_3dtdgt

ltweb-appgt

ltdisplay-namegtBookmark Application7ltdisplay-namegt

ltweb-appgt

The only item that needs to be specified in the JSR 168 webxml 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 portletxml as portlet application name as there can be several concrete instances of the same abstract application

- 17 -

332 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 331) 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 331) 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

333 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

334 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 instanceentity 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 -

335 Portlet API does not extend servlet API

In the IBM Portlet API portlets extend servlets and all the major interfaces (Request Response Session hellip) 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

336 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

bull defineObjects tag ndash to define the basic portlet API objects RenderRequest RenderResponse and PortletConfig

bull actionURL tag ndash to create an action URL bull renderURL tag ndash to create a render URL bull namespace tag ndash 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 donrsquot need decoding

34 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 -

341 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 (eg 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

342 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

3421 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

3422 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 322) 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

3423 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

3424 Request Response properties

Properties can be used by the portalportlet container to send vendor specific information to the portlet andor the portlet can send vendor specific information to the portalportlet-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

343 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 (eg between portlets or between a portlet and a servlet)

344 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 23 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

345 J2EE role support

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

346 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 -

347 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 PortletRequestgetResponseContentTypes 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 (eg ldquotextrdquo or ldquordquo) 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

348 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 (eg an accounting servlet) in response to an action

349 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

3410 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 vendorrsquos 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)

3411 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 xmllang attribute like the

- 22 -

servlet 24 deployment descriptor Thus the same tag with descriptions in different languages can be used (eg 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

35 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)

351 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

bull ActionEventThe action event maps to the action phase call in the JSR 168

bull MessageEventMessage 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)

bull PortletApplicationSettingsAttributeEventPortletSettingsAttributeEventThese are events that get fired when attributes for the application or of the portlet settings change

bull WindowEventThe portlet will register for window events to get notified if the portlet window is changed via the window decorations

352 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 -

bull PortletPageListener The page listeners provides the portlet with events for the beginning of the page before any markup is written for this page (eg to write JavaScript at the beginning of the page) and the end of the page after all markup is written

bull 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 23 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

bull EventPhaseListener The event phase listener notifies the portlet of the beginning and end of the eventaction phase

353 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

354 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 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

Figure 4

- 24 -

Figure 4 Portlet menu example

355 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

356 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 -

36 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 indicates portlet in what mode to operate for a given request

View edit help + custom modes

view edit help + custom modes

full alignment

Window State the state of the window in which the portlet output will be displayed

minimized normal maximized solo +

custom window states

minimized normal maximized +

custom window states

full alignment (ldquosolordquo is missing in the JSR but can be implemented as a custom state)

URL encoding to allow re-writing URLs created by the portlet

defines how to create URLs to allow re-writing of the URLs either on consumer or producer side

encapsulates URL creation via a Java object

full alignment (the implementation of the Java object can implement the WSRP URL rewriting rules)

Namespace encoding to avoid that several portlets on a page conflicting with each other

defines namespace prefixes for consumer and producer side namespacing

provides a Java method to namespace a String

full alignment (the JSR namespace method can implement the WSRP namespace behavior)

User ndash portlet interaction operations

performBlockingInteraction blocking action processing

getMarkup render the markup

action blocking action processing

render render the makup

full alignment (action invocations carried through performBlockingInteraction render carried through getMarkup)

View state that allows the current portlet fragment to be correctly displayed in sub-sequent render calls

navigational state render parameter full alignment (WSRP navigational state maps to JSR render parameters)

Storing transient state across request

session state concept implemented via a sessionID

utilizes the Http web application session

full alignment (the WSRP sessionID can be used to reference the JSR session)

Storing persistent state to personalize the rendering of the portlet

allows to have properties of arbitrary types

provides String-based preferences

full alignment (JSR String preferences can be mapped to WSRP properties)

Information about the portal calling the portlet

RegistrationData provide information of the consumer to the producer

PortalContext provide a Java interface to access information about the portal calling the portlet

full alignment (all data represented through the PortalContext to the JSR portlet are available in the RegistrationData)

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

Aggregated HTML WML VoiceXML

over HTTPMark-Up Fragments

Transferred via WSRP

Portal

WSRP Service

WSRP Service

WSRP Service

WSRP Consumer WSRP Producer

Use of WSRP Services in Portals

Portal sharing Portlets as WSRP Services

ServerPortalPortals

Huge numberof users Publishing Portal

WSRPWrapperPortalsPortalsPortal

Portlet

Portlet

Portlet

WSRP Consumer WSRP Producer

ProxyPortlet

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

bull 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

bull 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

bull 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

bull 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 CCPP standard allowing a portlet to query the client capabilities and adopting its markup accordingly (eg screen size browser) This API is likely to be included in the next version of the portlet API Also J2EE 14 was finalized during this time period J2EE 14 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 14

bull caching The first version of the JSR 168 API is limited to expiration-based caching (see section 327) 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

bull 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

51 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

511 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

bull portlets are components Portlets are components that implement a specific function Different functions should be distributed to different portlets

bull 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

bull 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

512 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 HttpServletRequestgetSession() call in the JSPs called via the IBM Portlet API needs to be replaced when moving to JSR 168 portlets by the RenderRequestgetPortletSession() 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 HttpServletRequestgetSession() will get the HttpSession and therefore need to access the portlet session via the RenderRequest

513 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

514 Persistent data

Portlets can store customization and personalization data persistently Customization data are related to the portlet and are valid for all users (eg 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 (eg 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

515 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

516 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

52 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

521 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 351 353) 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

522 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

53 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 -

531 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

bull no support of the back button in the browser bull current state of the portlet is not bookmarkable bull 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 bull 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

54 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

541 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 -

542 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

543 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

544 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 wersquoll 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

Figure 7After clicking on the Edit mode button the portlet renders the Edit view shown in

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

Figure 8

After we press the ldquoAddrdquo 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

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

bull use JSPs for rendering the output bull customize the portlet output taking user specific data into account bull 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

61 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 comibmwpssampleswp5

import javaio

import javautil

import orgapachejetspeedportlet

import orgapachejetspeedportletevent

public class IbmBookmark extends PortletAdapter implements ActionListener

public void init(PortletConfig portletConfig) throws UnavailableException

superinit(portletConfig)

- 36 -

public void doView(PortletRequest request PortletResponse response)

throws PortletException IOException

String jspName = thisgetPortletConfig()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 = responsecreateReturnURI()

addURIaddAction(add)

requestsetAttribute(addURI addURItoString())

PortletURI cancelURI = responsecreateReturnURI()

requestsetAttribute(cancelURI cancelURItoString())

String jspName = thisgetPortletConfig()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 ldquocancelrdquo and ldquoaddrdquo URLs are created inside the portlet and attached to the request before including the Edit JSP Both URLs are from type ldquoReturnURIrdquo 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 = eventgetRequest()

String action = eventgetActionString()

PortletLog log = getPortletLog()

if ( action=null )

try

if (actionequals(removeURI))

String removeName = requestgetParameter(remove)

PortletData portData = requestgetData()

portDataremoveAttribute(removeName)

portDatastore()

if (actionequals(add))

PortletData portData = requestgetData()

String name = requestgetParameter(name)

String value = requestgetParameter(value)

portDatasetAttribute(name value)

portDatastore()

catch ( AccessDeniedException ade )

logerror(AccessDeniedException occured when adding or deleting a bookmark)

catch ( IOException ioe )

logerror(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 ldquoaddrdquo or ldquodeleterdquo 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 ldquoaddrdquo or ldquoremoveURIrdquo If the user has clicked on the ldquoremoverdquo button the corresponding link is removed from the portlet data whereas if ldquoaddrdquo was clicked the data entered by the user is added to the portlet data

62 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 comibmwpssamplesjsr

import javaio

import javaxportlet

public class Bookmark extends GenericPortlet

public void init(PortletConfig config) throws PortletException

superinit(config)

public void doView(RenderRequest request RenderResponse response)

throws PortletException IOException

responsesetContentType(texthtml)

String jspName = getPortletConfig()getInitParameter(jspView)

PortletRequestDispatcher rd = getPortletContext()getRequestDispatcher(jspName)

rdinclude(requestresponse)

- 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

responsesetContentType(texthtml)

PortletURL addUrl = responsecreateActionURL()

addUrlsetPortletMode(PortletModeVIEW)

addUrlsetParameter(addadd)

requestsetAttribute(addUrladdUrltoString())

PortletURL cancelUrl = responsecreateRenderURL()

cancelUrlsetPortletMode(PortletModeVIEW)

requestsetAttribute(cancelUrlcancelUrltoString())

String jspName = getPortletConfig()getInitParameter(jspEdit)

PortletRequestDispatcher rd = getPortletContext()getRequestDispatcher(jspName)

rdinclude(requestresponse)

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 ldquoaddrdquo button URL an action URL is created as we need to store the user input of the add form persistently For the ldquocancelrdquo 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 = requestgetParameter(remove)

if (removeName = null)

PortletPreferences prefs = requestgetPreferences()

prefsreset(removeName)

prefsstore()

String add = requestgetParameter(add)

if (add = null)

PortletPreferences prefs = requestgetPreferences()

String name = requestgetParameter(name)

String value = requestgetParameter(value)

prefssetValue(name value)

prefsstore()

catch ( IOException ioe )

getPortletContextlog(An IO error occured when trying to remove a bookmark)

catch ( PortletException pe )

getPortletContextlog(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

bull 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

bull 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

bull Persistent portlet data The JSR 168 persistent data PortletPreferences have an API similar to the JDK 14 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

bull 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

63 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

lt page contentType=texthtml import=javautil comibmwpssampleswp5

orgapachejetspeedportlet session=falsegt

lt taglib uri=WEB-INFtldportlettld prefix=portletAPI gt

- 42 -

ltportletAPIinitgt

ltp class=wpsPortletHeadgtltportletAPItext key=available_bookmarks

bundle=nlsTextgtAvailable BookmarksltportletAPItextgtltpgt

lt

PortletData prefs = portletRequestgetData()

Enumeration e = prefsgetAttributeNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltportletAPItext key=no_bookmarks bundle=nlsTextgtNo

bookmarksltportletAPItextgtltpgt

lt

else

gt

ltp class=wpsIndentMediumgt

lt

while (ehasMoreElements())

String name = (String)enextElement()

String value = (String)prefsgetAttribute(name)

gt

lta href=lt=valuegt target=_blankgtlt=namegtltagtltbr gt

lt

gt

ltpgt

The View JSP first call portletAPIinit 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

lt page contentType=texthtml import=javautil

comibmwpssampleswp5orgapachejetspeedportlet session=falsegt

lt taglib uri=WEB-INFtldportlettld prefix=portletAPI gt

ltjspuseBean id=addURI class=javalangString scope=request gt

ltjspuseBean id=cancelURI class=javalangString scope=request gt

ltportletAPIinitgt

lth4gtltportletAPItext key=available_bookmarks bundle=nlsTextgtAvailable

BookmarksltportletAPItextgtlth4gt

lttable class=wpsTablegt

lttr class=wpsTableRowgt

ltth class=portlet-table-headergtltportletAPItext key=name bundle=nlsTextgtltthgt

ltth class=portlet-table-headergtltportletAPItext key=url bundle=nlsTextgtltthgt

lttdgtlttdgt

lttrgt

lt

PortletData prefs = portletRequestgetData()

Enumeration e = prefsgetAttributeNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltportletAPItext key=no_bookmarks bundle=nlsTextgtNo

bookmarksltportletAPItextgtltpgt

lt

else

while (ehasMoreElements())

- 44 -

String name = (String)enextElement()

String value = (String)prefsgetAttribute(name)

gt

lttr class=wpsTableRowgt

lttdgt lt=namegt lttdgt

lttdgt lt=valuegt lttdgt

lttdgt lta href=ltportletAPIcreateURIgtltportletAPIURIAction

name=removeURIgtltportletAPIURIParameter name=remove

value=lt=namegtgtltportletAPIcreateURIgtgt

(ltportletAPItext key=delete bundle=nlsTextgt)ltagt

lttdgt

lttrgt

lt

gt

ltform action=lt=addURIgt method=POSTgt

lttr class=wpsTableRowgt

lttdgtltinput name=ltportletAPIencodeNamespace value=namegt type=text

class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=ltportletAPIencodeNamespace value=valuegt type=text

class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=ltportletAPIencodeNamespace value=addgt type=submit

value=ltportletAPItext key=add bundle=nlsTextgt class=portlet-form-buttongtlttdgt

lttrgt

ltformgt

lttablegt

- 45 -

ltform action=lt=cancelURIgt method=postgt

ltinput name=ltportletAPIencodeNamespace value=cancelgt type=submit

value=ltportletAPItext key=cancel bundle=nlsTextgt class=portlet-form-buttongt

ltformgt

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 ldquodeleterdquo button for which an URL with the action ldquoremoveURIrdquo 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 ldquocancelrdquo button from the request

64 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

lt page import=javaxportlet javautil session=falsegt

lt taglib uri=httpjavasuncomportlet prefix=portletAPI gt

lt taglib prefix=fmt uri=httpjavasuncomjstlfmt gt

ltportletAPIdefineObjects gt

ltfmtsetBundle basename=nlsTextgt

lt

ResourceBundle myText = ResourceBundlegetBundle(nlsText requestgetLocale())

gt

lth4gtltfmtmessage key=available_bookmarksgtlth4gt

lt

PortletPreferences prefs = renderRequestgetPreferences()

Enumeration e = prefsgetNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltfmtmessage key=no_bookmarksgtltpgt

- 46 -

lt

else

gt

ltpgt

lt

while (ehasMoreElements())

String name = (String)enextElement()

String value = prefsgetValue(namelt+myTextgetString(undefined)+gt)

gt

lta href=lt=valuegt target=_blankgtlt=namegtltagtltbr gt

lt

gt

ltpgt

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 fmtmessage 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

lt page import=javaxportlet javautil session=false gt

lt taglib uri=httpjavasuncomportlet prefix=portletAPI gt

lt taglib prefix=fmt uri=httpjavasuncomjstlfmt gt

ltjspuseBean id=addUrl scope=request class=javalangString gt

ltjspuseBean id=cancelUrl scope=request class=javalangString gt

- 47 -

ltportletAPIdefineObjectsgt

lt

ResourceBundle myText = ResourceBundlegetBundle(nlsText requestgetLocale())

gt

ltfmtsetBundle basename=nlsTextgt

lth4gtltfmtmessage key=available_bookmarksgtlth4gt

lttable class=wpsTablegt

lttr class=wpsTableRowgt

ltth class=wpsTableHeadgtltfmtmessage key=namegtltthgt

ltth class=wpsTableHeadgtltfmtmessage key=urlgtltthgt

lttdgtlttdgt

lttrgt

lt

PortletPreferences prefs = renderRequestgetPreferences()

Enumeration e = prefsgetNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltfmtmessage key=no_bookmarksgtltpgt

lt

else

while (ehasMoreElements())

String name = (String)enextElement()

String value = prefsgetValue(namelt+myTextgetString(undefined)+gt)

gt

lttr class=wpsTableRowgt

lttdgt lt=namegt lttdgt

lttdgt lt=valuegt lttdgt

- 48 -

lttdgt ltportletAPIactionURL var=removeUrlgt

ltportletAPIparam name=remove value=lt=namegtgt

ltportletAPIactionURLgt

lta href=lt=removeUrltoString()gtgt(ltfmtmessage key=deletegt)ltagt

lttdgt

lttrgt

lt

gt

ltform action=lt=addUrlgt method=POSTgt

lttr class=wpsTableRowgt

lttdgtltinput name=name type=text class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=value type=text class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=add type=submit value=ltfmtmessage key=addgt

class=portlet-form-buttongtlttdgt

lttrgt

ltformgt

lttablegt

ltform action=lt=cancelUrlgt method=postgt

ltinput name=cancel type=submit value=ltfmtmessage key=cancelgt class=portlet-

form-buttongt

ltformgt

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 14 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 -

- 51 -

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 (eg eventing) the IBM Portlet API still needs to be used Trademarks bull IBM and WebSphere are trademarks or registered trademarks of IBM Corporation in

the United States other countries or both bull 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 bull Other company product and service names may be trademarks or service marks of

others IBM copyright and trademark information httpwwwibmcomlegalcopytradephtml

  • Introduction
  • JSR 168 and the Java Community Process
  • Comparing concepts
    • Basic concepts
      • Portal
      • Portal page
      • Portlet
      • Portlet Container
        • Concepts that are the same
          • Portlet mode
          • Window state
          • Portlet life cycle and request processing
          • URL encoding
          • Include servletsJSPs
          • Portlet application packaging
          • Expiration-based caching
            • Concepts that differ
              • Portlet application entity
              • Portlet entity
              • Action and Render Request Response objects
              • Window concept
              • Portlet API does not extend servlet API
              • TAG libraries
                • Concepts new in the JSR 168
                  • Render parameter
                  • Extension mechanisms
                    • Custom window states
                    • Custom portlet modes
                    • Custom user info
                    • Request Response properties
                      • Web application session scope
                      • Reuse of the HttpSession listeners
                      • J2EE role support
                      • Resource bundles
                      • Multiple response content types
                      • Redirect in action
                      • Preference validator
                      • Portal context
                      • Localization support
                        • Concepts missing in the JSR 168
                          • Eventing
                          • Additional lifecycle events
                          • Property broker
                          • Portlet Menus
                          • Portlet Services
                          • Invalidation-based caching
                            • Alignment with WSRP
                              • Outlook for the next version of the JSR 168
                              • Guidelines for programming IBM Portlet API portlets
                                • Similar Functionality
                                  • Basic programming model
                                  • Portlet private session
                                  • User profile information
                                  • Persistent data
                                  • Portlet modes and window states
                                  • Expiration-based caching
                                    • Slightly different functionality
                                      • Sharing of data between portlets
                                      • Session listeners
                                        • New JSR 168 functionality
                                          • Navigational state (render parameters)
                                            • Pitfalls
                                              • Request response objects for action and render phase
                                              • Include search path
                                              • Form parameter encoding
                                              • Title setting
                                                  • Examples
                                                    • IBM Portlet API Portlet Code
                                                    • JSR 168 Portlet Code
                                                    • IBM Portlet API JSPs
                                                    • JSR 168 JSPs
                                                      • Summary
Page 2: Difference Bw Jsr168 and Ibm

Table of Contents 1 Introduction 4 2 JSR 168 and the Java Community Process 5 3 Comparing concepts 6

31 Basic concepts 6 311 Portal 6 312 Portal page 7 313 Portlet 8 314 Portlet Container 8

32 Concepts that are the same 8 321 Portlet mode 8 322 Window state 9 323 Portlet life cycle and request processing 10 324 URL encoding 11 325 Include servletsJSPs 12 326 Portlet application packaging 12 327 Expiration-based caching 13

33 Concepts that differ 13 331 Portlet application entity 13 332 Portlet entity 18 333 Action and Render Request Response objects 18 334 Window concept 18 335 Portlet API does not extend servlet API 19 336 TAG libraries 19

34 Concepts new in the JSR 168 19 341 Render parameter 20 342 Extension mechanisms 20 343 Web application session scope 21 344 Reuse of the HttpSession listeners 21 345 J2EE role support 21 346 Resource bundles 21 347 Multiple response content types 22 348 Redirect in action 22 349 Preference validator 22 3410 Portal context 22 3411 Localization support 22

35 Concepts missing in the JSR 168 23 351 Eventing 23 352 Additional lifecycle events 23 353 Property broker 24 354 Portlet Menus 24 355 Portlet Services 25 356 Invalidation-based caching 25

36 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 -

51 Similar Functionality 30 511 Basic programming model 30 512 Portlet private session 30 513 User profile information 31 514 Persistent data 31 515 Portlet modes and window states 31 516 Expiration-based caching 32

52 Slightly different functionality 32 521 Sharing of data between portlets 32 522 Session listeners 32

53 New JSR 168 functionality 32 531 Navigational state (render parameters) 33

54 Pitfalls 33 541 Request response objects for action and render phase 33 542 Include search path 34 543 Form parameter encoding 34 544 Title setting 34

6 Examples 35 61 IBM Portlet API Portlet Code 36 62 JSR 168 Portlet Code 39 63 IBM Portlet API JSPs 42 64 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 copy 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 Javatrade 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 IBMreg WebSpherereg Portal Version 50 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 Javatrade 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 httpjcporg 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 httpjcporgenjsrdetailid=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

31 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

311 Portal

A portal is a web based application that ndashcommonly ndash 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

PortalWeb

ApplicationHTTP

HTML

WML

Voi

ceXM

L

Portl

et In

voke

r API Portlet

(App)Po

rtlet

API

Portlet(App)

Portlet(App)

PortletServletContainer

Portl

et P

rovid

er S

PI

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

312 Portal page

Figure 2

Figure 2 Basic portal page components

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 (eg maximize or minimize the portlet) and buttons to change the mode of a portlet (eg show help or edit the predefined portlet settings)

ltTitlegt Edit

Portlet content

Portal page

Portletwindows

Window states Portlet modes

Markup Fragments

ltTitlegt Edit

ltTitlegt Edit

Portlet content

Portlet content

- 7 -

313 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 (eg 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 requestresponse 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 users interactions

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

314 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

32 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

321 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

bull Edit ndash to display one or more personalization views that let the user personalize portlet settings

bull Help ndash to display help views bull View ndash to display the portlet output bull Configure ndash 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

bull required to support (same semantic as above) o Edit o Help o View

bull optional custom modes o About ndash to display information on the portlets purpose origin version etc o Config ndash has the same semantic as the IBM Portlet API configure mode o Edit_defaults ndash to set the default values for the modifiable preferences that

are typically changed in the EDIT screen o Preview ndash to render output without the need of having back-end

connections or user specific data available o Print ndash to display a view that is suitable for printing

bull portal vendor specific modes that are available only in a portal of a specific vendor

322 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

bull Closed (deprecated) ndash to indicate that a window should be closed bull Detached (deprecated) ndash to indicate that a window should be detached bull Maximized ndash to indicate that a window has more real estate to render its output

then in normal window state

- 9 -

bull Minimized ndash to indicate that the portlet is minimized and cannot render any output

bull Moving (deprecated) ndash to indicate that the portlet window has been moved bull Normal ndash to indicate that the portlet is sharing its screen with other portlets on a

page bull Resizing (deprecated) ndash to indicate that the portlet has been resized bull Solo ndash to indicate that the portlet is the only portlet on the page

Whereas the JSR 168 has only the following mandatory window states

bull Maximized ndash same as in the IBM Portlet API bull Minimized ndash to indicate that the portlet should only render minimal or no output bull Normal ndash same as in the IBM Portlet API

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

323 Portlet life cycle and request processing

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

bull init ndash to initialize the portlet and put the portlet into service bull handle requests ndash process different kinds of action and render requests bull destroy ndash 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

324 URL encoding

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

bull 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

bull 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

325 Include servletsJSPs

In both APIrsquos 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()

contextinclude(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)

rdinclude(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 HttpServetRequestgetSession() 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

326 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 (webxml) and one to specify the portlet resources (portletxml) All web resources that are not portlets must be specified in the webxml deployment descriptor All portlets and portlet related settings must be specified in an additional file called portletxml

- 12 -

Different from JSR 168 in the IBM Portlet API all portlets must also be listed in the webxml as they are also servlets (see also 335 for examples of the deployment descitptors)

327 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

33 Concepts that differ

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

331 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 webxml and concrete portlet applications of concrete portlets based on the abstract ones The following portletxml example shows these two different parts

IBM PORTLET API PORTLETXML EXAMPLE

ltxml version=10 encoding=UTF-8gt

ltDOCTYPE portlet-app-def PUBLIC -IBMDTD Portlet Application 11EN

portlet_11dtdgt

ltportlet-app-defgt

ltportlet-app uid=commycobookmark1234 major-version=7 minor-version=24gt

ltportlet-app-namegtBookmark Application7ltportlet-app-namegt

ltportlet id=Portlet_1 href=WEB-INFwebxmlServlet_1gt

- 13 -

ltportlet-namegtBookmark Portlet7ltportlet-namegt

ltallowsgt

ltmaximizedgt

ltminimizedgt

ltallowsgt

ltsupportsgt

ltmarkup name=htmlgt

ltview output=fragmentgt

ltedit output=fragmentgt

ltmarkupgt

ltsupportsgt

ltportletgt

ltportlet-appgt

ltconcrete-portlet-app uid=commycobookmark12341gt

ltportlet-app-namegtConcreteSamplets_Bookmark7ltportlet-app-namegt

ltconcrete-portlet href=Portlet_1gt

ltportlet-namegtBookmark Portlet7ltportlet-namegt

ltdefault-localegtenltdefault-localegt

ltlanguage locale=engt

lttitlegtMy Bookmarks7lttitlegt

lttitle-shortgtBookmarks7lttitle-shortgt

ltdescriptiongtPortlet showing your personalized bookmarksltdescriptiongt

ltkeywordsgtbookmarksltkeywordsgt

ltlanguagegt

ltconfig-paramgt

ltparam-namegturl1ltparam-namegt

ltparam-valuegthttpwwwgooglecomltparam-valuegt

ltconfig-paramgt

ltconcrete-portletgt

- 14 -

ltconcrete-portlet-appgt

ltportlet-app-defgt

As portlets are servlets in the IBM Portlet API the portletxml has references for each portlet to the servlet in the webxml that represents the portlet The webxml for this example is

IBM PORTLET API WEBXML EXAMPLE

ltxml version=10 encoding=UTF-8gt

ltDOCTYPE web-app

PUBLIC -Sun Microsystems IncDTD Web Application 22EN

httpjavasuncomj2eedtdsweb-app_22dtdgt

ltweb-app id=WebApp_1gt

ltdisplay-namegtbookmark7ltdisplay-namegt

ltservlet id=Servlet_1gt

ltservlet-namegtBookmark7ltservlet-namegt

ltservlet-classgtcommycobookmarkBookmarkPortletltservlet-classgt

ltinit-paramgt

ltparam-namegtjspviewltparam-namegt

ltparam-valuegtbookmarkViewjspltparam-valuegt

ltinit-paramgt

ltinit-paramgt

ltparam-namegtjspeditltparam-namegt

ltparam-valuegtbookmarkEditjspltparam-valuegt

ltinit-paramgt

ltservletgt

ltservlet-mappinggt

ltservlet-namegtBookmark7ltservlet-namegt

lturl-patterngtBookmark7lturl-patterngt

ltservlet-mappinggt

ltweb-appgt

- 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 webxml and not in the portletxml In the JSR 168 the deployment descriptor is more like the webxml 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 portletxml example would look like when using the JSR 168 deployment descriptor format

JSR 168 PORTLETXML EXAMPLE

ltxml version=10 encoding=UTF-8gt

ltxml version=10encoding=UTF-8gt

ltportlet-app xmlns=httpjavasuncomxmlnsportletportlet-app_1_0xsd version=10

xmlnsxsi=httpwwww3org2001XMLSchema-instance

xsischemaLocation=httpjavasuncomxmlnsportlet-app_1_0xsd

httpjavasuncomxmlnsportletportlet-app_1_0xsdgt

ltportletgt

ltdescription xmllang=ENgtPortlet showing your personalized

bookmarksltdescriptiongt

ltportlet-namegtBookmark Portlet7ltportlet-namegt

ltdisplay-name xmllang=ENgtBookmark Portletltdisplay-namegt

ltportlet-classgtcommycobookmarkBookmarkPortletltportlet-classgt

ltinit-paramgt

ltnamegtjspviewltnamegt

ltvaluegtbookmarkViewjspltvaluegt

ltinit-paramgt

ltinit-paramgt

ltnamegtjspeditltnamegt

ltvaluegtbookmarkEditjspltvaluegt

ltinit-paramgt

ltsupportsgt

ltmime-typegttexthtmlltmime-typegt

ltportlet-modegtviewltportlet-modegt

- 16 -

ltportlet-modegteditltportlet-modegt

ltsupportsgt

ltsupported-localegtENltsupported-localegt

ltportlet-infogt

lttitlegtMy Bookmarks7lttitlegt

ltshort-titlegtBookmarks7ltshort-titlegt

ltkeywordsgtbookmarksltkeywordsgt

ltportlet-infogt

ltportlet-preferencesgt

ltpreferencegt

ltnamegturl1ltnamegt

ltvaluegthttpwwwgooglecomltvaluegt

ltpreferencegt

ltportlet-preferencesgt

ltportletgt

ltportlet-appgt

Here the initialization parameters are directly specified in the portletxml as portlets are independent components in the JSR 168 The following example represents the webxml for the JSR 168 bookmark portlet

JSR 168 WEBXML EXAMPLE

ltxml version=10 encoding=UTF-8gt

ltDOCTYPE web-app PUBLIC -Sun Microsystems IncDTD Web Application 23EN

httpjavasuncomdtdweb-app_2_3dtdgt

ltweb-appgt

ltdisplay-namegtBookmark Application7ltdisplay-namegt

ltweb-appgt

The only item that needs to be specified in the JSR 168 webxml 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 portletxml as portlet application name as there can be several concrete instances of the same abstract application

- 17 -

332 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 331) 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 331) 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

333 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

334 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 instanceentity 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 -

335 Portlet API does not extend servlet API

In the IBM Portlet API portlets extend servlets and all the major interfaces (Request Response Session hellip) 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

336 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

bull defineObjects tag ndash to define the basic portlet API objects RenderRequest RenderResponse and PortletConfig

bull actionURL tag ndash to create an action URL bull renderURL tag ndash to create a render URL bull namespace tag ndash 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 donrsquot need decoding

34 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 -

341 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 (eg 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

342 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

3421 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

3422 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 322) 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

3423 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

3424 Request Response properties

Properties can be used by the portalportlet container to send vendor specific information to the portlet andor the portlet can send vendor specific information to the portalportlet-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

343 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 (eg between portlets or between a portlet and a servlet)

344 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 23 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

345 J2EE role support

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

346 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 -

347 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 PortletRequestgetResponseContentTypes 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 (eg ldquotextrdquo or ldquordquo) 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

348 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 (eg an accounting servlet) in response to an action

349 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

3410 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 vendorrsquos 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)

3411 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 xmllang attribute like the

- 22 -

servlet 24 deployment descriptor Thus the same tag with descriptions in different languages can be used (eg 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

35 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)

351 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

bull ActionEventThe action event maps to the action phase call in the JSR 168

bull MessageEventMessage 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)

bull PortletApplicationSettingsAttributeEventPortletSettingsAttributeEventThese are events that get fired when attributes for the application or of the portlet settings change

bull WindowEventThe portlet will register for window events to get notified if the portlet window is changed via the window decorations

352 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 -

bull PortletPageListener The page listeners provides the portlet with events for the beginning of the page before any markup is written for this page (eg to write JavaScript at the beginning of the page) and the end of the page after all markup is written

bull 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 23 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

bull EventPhaseListener The event phase listener notifies the portlet of the beginning and end of the eventaction phase

353 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

354 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 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

Figure 4

- 24 -

Figure 4 Portlet menu example

355 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

356 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 -

36 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 indicates portlet in what mode to operate for a given request

View edit help + custom modes

view edit help + custom modes

full alignment

Window State the state of the window in which the portlet output will be displayed

minimized normal maximized solo +

custom window states

minimized normal maximized +

custom window states

full alignment (ldquosolordquo is missing in the JSR but can be implemented as a custom state)

URL encoding to allow re-writing URLs created by the portlet

defines how to create URLs to allow re-writing of the URLs either on consumer or producer side

encapsulates URL creation via a Java object

full alignment (the implementation of the Java object can implement the WSRP URL rewriting rules)

Namespace encoding to avoid that several portlets on a page conflicting with each other

defines namespace prefixes for consumer and producer side namespacing

provides a Java method to namespace a String

full alignment (the JSR namespace method can implement the WSRP namespace behavior)

User ndash portlet interaction operations

performBlockingInteraction blocking action processing

getMarkup render the markup

action blocking action processing

render render the makup

full alignment (action invocations carried through performBlockingInteraction render carried through getMarkup)

View state that allows the current portlet fragment to be correctly displayed in sub-sequent render calls

navigational state render parameter full alignment (WSRP navigational state maps to JSR render parameters)

Storing transient state across request

session state concept implemented via a sessionID

utilizes the Http web application session

full alignment (the WSRP sessionID can be used to reference the JSR session)

Storing persistent state to personalize the rendering of the portlet

allows to have properties of arbitrary types

provides String-based preferences

full alignment (JSR String preferences can be mapped to WSRP properties)

Information about the portal calling the portlet

RegistrationData provide information of the consumer to the producer

PortalContext provide a Java interface to access information about the portal calling the portlet

full alignment (all data represented through the PortalContext to the JSR portlet are available in the RegistrationData)

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

Aggregated HTML WML VoiceXML

over HTTPMark-Up Fragments

Transferred via WSRP

Portal

WSRP Service

WSRP Service

WSRP Service

WSRP Consumer WSRP Producer

Use of WSRP Services in Portals

Portal sharing Portlets as WSRP Services

ServerPortalPortals

Huge numberof users Publishing Portal

WSRPWrapperPortalsPortalsPortal

Portlet

Portlet

Portlet

WSRP Consumer WSRP Producer

ProxyPortlet

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

bull 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

bull 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

bull 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

bull 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 CCPP standard allowing a portlet to query the client capabilities and adopting its markup accordingly (eg screen size browser) This API is likely to be included in the next version of the portlet API Also J2EE 14 was finalized during this time period J2EE 14 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 14

bull caching The first version of the JSR 168 API is limited to expiration-based caching (see section 327) 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

bull 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

51 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

511 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

bull portlets are components Portlets are components that implement a specific function Different functions should be distributed to different portlets

bull 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

bull 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

512 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 HttpServletRequestgetSession() call in the JSPs called via the IBM Portlet API needs to be replaced when moving to JSR 168 portlets by the RenderRequestgetPortletSession() 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 HttpServletRequestgetSession() will get the HttpSession and therefore need to access the portlet session via the RenderRequest

513 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

514 Persistent data

Portlets can store customization and personalization data persistently Customization data are related to the portlet and are valid for all users (eg 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 (eg 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

515 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

516 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

52 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

521 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 351 353) 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

522 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

53 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 -

531 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

bull no support of the back button in the browser bull current state of the portlet is not bookmarkable bull 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 bull 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

54 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

541 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 -

542 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

543 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

544 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 wersquoll 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

Figure 7After clicking on the Edit mode button the portlet renders the Edit view shown in

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

Figure 8

After we press the ldquoAddrdquo 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

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

bull use JSPs for rendering the output bull customize the portlet output taking user specific data into account bull 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

61 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 comibmwpssampleswp5

import javaio

import javautil

import orgapachejetspeedportlet

import orgapachejetspeedportletevent

public class IbmBookmark extends PortletAdapter implements ActionListener

public void init(PortletConfig portletConfig) throws UnavailableException

superinit(portletConfig)

- 36 -

public void doView(PortletRequest request PortletResponse response)

throws PortletException IOException

String jspName = thisgetPortletConfig()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 = responsecreateReturnURI()

addURIaddAction(add)

requestsetAttribute(addURI addURItoString())

PortletURI cancelURI = responsecreateReturnURI()

requestsetAttribute(cancelURI cancelURItoString())

String jspName = thisgetPortletConfig()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 ldquocancelrdquo and ldquoaddrdquo URLs are created inside the portlet and attached to the request before including the Edit JSP Both URLs are from type ldquoReturnURIrdquo 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 = eventgetRequest()

String action = eventgetActionString()

PortletLog log = getPortletLog()

if ( action=null )

try

if (actionequals(removeURI))

String removeName = requestgetParameter(remove)

PortletData portData = requestgetData()

portDataremoveAttribute(removeName)

portDatastore()

if (actionequals(add))

PortletData portData = requestgetData()

String name = requestgetParameter(name)

String value = requestgetParameter(value)

portDatasetAttribute(name value)

portDatastore()

catch ( AccessDeniedException ade )

logerror(AccessDeniedException occured when adding or deleting a bookmark)

catch ( IOException ioe )

logerror(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 ldquoaddrdquo or ldquodeleterdquo 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 ldquoaddrdquo or ldquoremoveURIrdquo If the user has clicked on the ldquoremoverdquo button the corresponding link is removed from the portlet data whereas if ldquoaddrdquo was clicked the data entered by the user is added to the portlet data

62 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 comibmwpssamplesjsr

import javaio

import javaxportlet

public class Bookmark extends GenericPortlet

public void init(PortletConfig config) throws PortletException

superinit(config)

public void doView(RenderRequest request RenderResponse response)

throws PortletException IOException

responsesetContentType(texthtml)

String jspName = getPortletConfig()getInitParameter(jspView)

PortletRequestDispatcher rd = getPortletContext()getRequestDispatcher(jspName)

rdinclude(requestresponse)

- 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

responsesetContentType(texthtml)

PortletURL addUrl = responsecreateActionURL()

addUrlsetPortletMode(PortletModeVIEW)

addUrlsetParameter(addadd)

requestsetAttribute(addUrladdUrltoString())

PortletURL cancelUrl = responsecreateRenderURL()

cancelUrlsetPortletMode(PortletModeVIEW)

requestsetAttribute(cancelUrlcancelUrltoString())

String jspName = getPortletConfig()getInitParameter(jspEdit)

PortletRequestDispatcher rd = getPortletContext()getRequestDispatcher(jspName)

rdinclude(requestresponse)

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 ldquoaddrdquo button URL an action URL is created as we need to store the user input of the add form persistently For the ldquocancelrdquo 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 = requestgetParameter(remove)

if (removeName = null)

PortletPreferences prefs = requestgetPreferences()

prefsreset(removeName)

prefsstore()

String add = requestgetParameter(add)

if (add = null)

PortletPreferences prefs = requestgetPreferences()

String name = requestgetParameter(name)

String value = requestgetParameter(value)

prefssetValue(name value)

prefsstore()

catch ( IOException ioe )

getPortletContextlog(An IO error occured when trying to remove a bookmark)

catch ( PortletException pe )

getPortletContextlog(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

bull 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

bull 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

bull Persistent portlet data The JSR 168 persistent data PortletPreferences have an API similar to the JDK 14 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

bull 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

63 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

lt page contentType=texthtml import=javautil comibmwpssampleswp5

orgapachejetspeedportlet session=falsegt

lt taglib uri=WEB-INFtldportlettld prefix=portletAPI gt

- 42 -

ltportletAPIinitgt

ltp class=wpsPortletHeadgtltportletAPItext key=available_bookmarks

bundle=nlsTextgtAvailable BookmarksltportletAPItextgtltpgt

lt

PortletData prefs = portletRequestgetData()

Enumeration e = prefsgetAttributeNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltportletAPItext key=no_bookmarks bundle=nlsTextgtNo

bookmarksltportletAPItextgtltpgt

lt

else

gt

ltp class=wpsIndentMediumgt

lt

while (ehasMoreElements())

String name = (String)enextElement()

String value = (String)prefsgetAttribute(name)

gt

lta href=lt=valuegt target=_blankgtlt=namegtltagtltbr gt

lt

gt

ltpgt

The View JSP first call portletAPIinit 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

lt page contentType=texthtml import=javautil

comibmwpssampleswp5orgapachejetspeedportlet session=falsegt

lt taglib uri=WEB-INFtldportlettld prefix=portletAPI gt

ltjspuseBean id=addURI class=javalangString scope=request gt

ltjspuseBean id=cancelURI class=javalangString scope=request gt

ltportletAPIinitgt

lth4gtltportletAPItext key=available_bookmarks bundle=nlsTextgtAvailable

BookmarksltportletAPItextgtlth4gt

lttable class=wpsTablegt

lttr class=wpsTableRowgt

ltth class=portlet-table-headergtltportletAPItext key=name bundle=nlsTextgtltthgt

ltth class=portlet-table-headergtltportletAPItext key=url bundle=nlsTextgtltthgt

lttdgtlttdgt

lttrgt

lt

PortletData prefs = portletRequestgetData()

Enumeration e = prefsgetAttributeNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltportletAPItext key=no_bookmarks bundle=nlsTextgtNo

bookmarksltportletAPItextgtltpgt

lt

else

while (ehasMoreElements())

- 44 -

String name = (String)enextElement()

String value = (String)prefsgetAttribute(name)

gt

lttr class=wpsTableRowgt

lttdgt lt=namegt lttdgt

lttdgt lt=valuegt lttdgt

lttdgt lta href=ltportletAPIcreateURIgtltportletAPIURIAction

name=removeURIgtltportletAPIURIParameter name=remove

value=lt=namegtgtltportletAPIcreateURIgtgt

(ltportletAPItext key=delete bundle=nlsTextgt)ltagt

lttdgt

lttrgt

lt

gt

ltform action=lt=addURIgt method=POSTgt

lttr class=wpsTableRowgt

lttdgtltinput name=ltportletAPIencodeNamespace value=namegt type=text

class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=ltportletAPIencodeNamespace value=valuegt type=text

class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=ltportletAPIencodeNamespace value=addgt type=submit

value=ltportletAPItext key=add bundle=nlsTextgt class=portlet-form-buttongtlttdgt

lttrgt

ltformgt

lttablegt

- 45 -

ltform action=lt=cancelURIgt method=postgt

ltinput name=ltportletAPIencodeNamespace value=cancelgt type=submit

value=ltportletAPItext key=cancel bundle=nlsTextgt class=portlet-form-buttongt

ltformgt

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 ldquodeleterdquo button for which an URL with the action ldquoremoveURIrdquo 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 ldquocancelrdquo button from the request

64 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

lt page import=javaxportlet javautil session=falsegt

lt taglib uri=httpjavasuncomportlet prefix=portletAPI gt

lt taglib prefix=fmt uri=httpjavasuncomjstlfmt gt

ltportletAPIdefineObjects gt

ltfmtsetBundle basename=nlsTextgt

lt

ResourceBundle myText = ResourceBundlegetBundle(nlsText requestgetLocale())

gt

lth4gtltfmtmessage key=available_bookmarksgtlth4gt

lt

PortletPreferences prefs = renderRequestgetPreferences()

Enumeration e = prefsgetNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltfmtmessage key=no_bookmarksgtltpgt

- 46 -

lt

else

gt

ltpgt

lt

while (ehasMoreElements())

String name = (String)enextElement()

String value = prefsgetValue(namelt+myTextgetString(undefined)+gt)

gt

lta href=lt=valuegt target=_blankgtlt=namegtltagtltbr gt

lt

gt

ltpgt

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 fmtmessage 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

lt page import=javaxportlet javautil session=false gt

lt taglib uri=httpjavasuncomportlet prefix=portletAPI gt

lt taglib prefix=fmt uri=httpjavasuncomjstlfmt gt

ltjspuseBean id=addUrl scope=request class=javalangString gt

ltjspuseBean id=cancelUrl scope=request class=javalangString gt

- 47 -

ltportletAPIdefineObjectsgt

lt

ResourceBundle myText = ResourceBundlegetBundle(nlsText requestgetLocale())

gt

ltfmtsetBundle basename=nlsTextgt

lth4gtltfmtmessage key=available_bookmarksgtlth4gt

lttable class=wpsTablegt

lttr class=wpsTableRowgt

ltth class=wpsTableHeadgtltfmtmessage key=namegtltthgt

ltth class=wpsTableHeadgtltfmtmessage key=urlgtltthgt

lttdgtlttdgt

lttrgt

lt

PortletPreferences prefs = renderRequestgetPreferences()

Enumeration e = prefsgetNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltfmtmessage key=no_bookmarksgtltpgt

lt

else

while (ehasMoreElements())

String name = (String)enextElement()

String value = prefsgetValue(namelt+myTextgetString(undefined)+gt)

gt

lttr class=wpsTableRowgt

lttdgt lt=namegt lttdgt

lttdgt lt=valuegt lttdgt

- 48 -

lttdgt ltportletAPIactionURL var=removeUrlgt

ltportletAPIparam name=remove value=lt=namegtgt

ltportletAPIactionURLgt

lta href=lt=removeUrltoString()gtgt(ltfmtmessage key=deletegt)ltagt

lttdgt

lttrgt

lt

gt

ltform action=lt=addUrlgt method=POSTgt

lttr class=wpsTableRowgt

lttdgtltinput name=name type=text class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=value type=text class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=add type=submit value=ltfmtmessage key=addgt

class=portlet-form-buttongtlttdgt

lttrgt

ltformgt

lttablegt

ltform action=lt=cancelUrlgt method=postgt

ltinput name=cancel type=submit value=ltfmtmessage key=cancelgt class=portlet-

form-buttongt

ltformgt

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 14 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 -

- 51 -

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 (eg eventing) the IBM Portlet API still needs to be used Trademarks bull IBM and WebSphere are trademarks or registered trademarks of IBM Corporation in

the United States other countries or both bull 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 bull Other company product and service names may be trademarks or service marks of

others IBM copyright and trademark information httpwwwibmcomlegalcopytradephtml

  • Introduction
  • JSR 168 and the Java Community Process
  • Comparing concepts
    • Basic concepts
      • Portal
      • Portal page
      • Portlet
      • Portlet Container
        • Concepts that are the same
          • Portlet mode
          • Window state
          • Portlet life cycle and request processing
          • URL encoding
          • Include servletsJSPs
          • Portlet application packaging
          • Expiration-based caching
            • Concepts that differ
              • Portlet application entity
              • Portlet entity
              • Action and Render Request Response objects
              • Window concept
              • Portlet API does not extend servlet API
              • TAG libraries
                • Concepts new in the JSR 168
                  • Render parameter
                  • Extension mechanisms
                    • Custom window states
                    • Custom portlet modes
                    • Custom user info
                    • Request Response properties
                      • Web application session scope
                      • Reuse of the HttpSession listeners
                      • J2EE role support
                      • Resource bundles
                      • Multiple response content types
                      • Redirect in action
                      • Preference validator
                      • Portal context
                      • Localization support
                        • Concepts missing in the JSR 168
                          • Eventing
                          • Additional lifecycle events
                          • Property broker
                          • Portlet Menus
                          • Portlet Services
                          • Invalidation-based caching
                            • Alignment with WSRP
                              • Outlook for the next version of the JSR 168
                              • Guidelines for programming IBM Portlet API portlets
                                • Similar Functionality
                                  • Basic programming model
                                  • Portlet private session
                                  • User profile information
                                  • Persistent data
                                  • Portlet modes and window states
                                  • Expiration-based caching
                                    • Slightly different functionality
                                      • Sharing of data between portlets
                                      • Session listeners
                                        • New JSR 168 functionality
                                          • Navigational state (render parameters)
                                            • Pitfalls
                                              • Request response objects for action and render phase
                                              • Include search path
                                              • Form parameter encoding
                                              • Title setting
                                                  • Examples
                                                    • IBM Portlet API Portlet Code
                                                    • JSR 168 Portlet Code
                                                    • IBM Portlet API JSPs
                                                    • JSR 168 JSPs
                                                      • Summary
Page 3: Difference Bw Jsr168 and Ibm

51 Similar Functionality 30 511 Basic programming model 30 512 Portlet private session 30 513 User profile information 31 514 Persistent data 31 515 Portlet modes and window states 31 516 Expiration-based caching 32

52 Slightly different functionality 32 521 Sharing of data between portlets 32 522 Session listeners 32

53 New JSR 168 functionality 32 531 Navigational state (render parameters) 33

54 Pitfalls 33 541 Request response objects for action and render phase 33 542 Include search path 34 543 Form parameter encoding 34 544 Title setting 34

6 Examples 35 61 IBM Portlet API Portlet Code 36 62 JSR 168 Portlet Code 39 63 IBM Portlet API JSPs 42 64 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 copy 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 Javatrade 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 IBMreg WebSpherereg Portal Version 50 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 Javatrade 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 httpjcporg 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 httpjcporgenjsrdetailid=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

31 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

311 Portal

A portal is a web based application that ndashcommonly ndash 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

PortalWeb

ApplicationHTTP

HTML

WML

Voi

ceXM

L

Portl

et In

voke

r API Portlet

(App)Po

rtlet

API

Portlet(App)

Portlet(App)

PortletServletContainer

Portl

et P

rovid

er S

PI

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

312 Portal page

Figure 2

Figure 2 Basic portal page components

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 (eg maximize or minimize the portlet) and buttons to change the mode of a portlet (eg show help or edit the predefined portlet settings)

ltTitlegt Edit

Portlet content

Portal page

Portletwindows

Window states Portlet modes

Markup Fragments

ltTitlegt Edit

ltTitlegt Edit

Portlet content

Portlet content

- 7 -

313 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 (eg 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 requestresponse 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 users interactions

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

314 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

32 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

321 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

bull Edit ndash to display one or more personalization views that let the user personalize portlet settings

bull Help ndash to display help views bull View ndash to display the portlet output bull Configure ndash 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

bull required to support (same semantic as above) o Edit o Help o View

bull optional custom modes o About ndash to display information on the portlets purpose origin version etc o Config ndash has the same semantic as the IBM Portlet API configure mode o Edit_defaults ndash to set the default values for the modifiable preferences that

are typically changed in the EDIT screen o Preview ndash to render output without the need of having back-end

connections or user specific data available o Print ndash to display a view that is suitable for printing

bull portal vendor specific modes that are available only in a portal of a specific vendor

322 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

bull Closed (deprecated) ndash to indicate that a window should be closed bull Detached (deprecated) ndash to indicate that a window should be detached bull Maximized ndash to indicate that a window has more real estate to render its output

then in normal window state

- 9 -

bull Minimized ndash to indicate that the portlet is minimized and cannot render any output

bull Moving (deprecated) ndash to indicate that the portlet window has been moved bull Normal ndash to indicate that the portlet is sharing its screen with other portlets on a

page bull Resizing (deprecated) ndash to indicate that the portlet has been resized bull Solo ndash to indicate that the portlet is the only portlet on the page

Whereas the JSR 168 has only the following mandatory window states

bull Maximized ndash same as in the IBM Portlet API bull Minimized ndash to indicate that the portlet should only render minimal or no output bull Normal ndash same as in the IBM Portlet API

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

323 Portlet life cycle and request processing

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

bull init ndash to initialize the portlet and put the portlet into service bull handle requests ndash process different kinds of action and render requests bull destroy ndash 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

324 URL encoding

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

bull 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

bull 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

325 Include servletsJSPs

In both APIrsquos 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()

contextinclude(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)

rdinclude(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 HttpServetRequestgetSession() 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

326 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 (webxml) and one to specify the portlet resources (portletxml) All web resources that are not portlets must be specified in the webxml deployment descriptor All portlets and portlet related settings must be specified in an additional file called portletxml

- 12 -

Different from JSR 168 in the IBM Portlet API all portlets must also be listed in the webxml as they are also servlets (see also 335 for examples of the deployment descitptors)

327 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

33 Concepts that differ

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

331 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 webxml and concrete portlet applications of concrete portlets based on the abstract ones The following portletxml example shows these two different parts

IBM PORTLET API PORTLETXML EXAMPLE

ltxml version=10 encoding=UTF-8gt

ltDOCTYPE portlet-app-def PUBLIC -IBMDTD Portlet Application 11EN

portlet_11dtdgt

ltportlet-app-defgt

ltportlet-app uid=commycobookmark1234 major-version=7 minor-version=24gt

ltportlet-app-namegtBookmark Application7ltportlet-app-namegt

ltportlet id=Portlet_1 href=WEB-INFwebxmlServlet_1gt

- 13 -

ltportlet-namegtBookmark Portlet7ltportlet-namegt

ltallowsgt

ltmaximizedgt

ltminimizedgt

ltallowsgt

ltsupportsgt

ltmarkup name=htmlgt

ltview output=fragmentgt

ltedit output=fragmentgt

ltmarkupgt

ltsupportsgt

ltportletgt

ltportlet-appgt

ltconcrete-portlet-app uid=commycobookmark12341gt

ltportlet-app-namegtConcreteSamplets_Bookmark7ltportlet-app-namegt

ltconcrete-portlet href=Portlet_1gt

ltportlet-namegtBookmark Portlet7ltportlet-namegt

ltdefault-localegtenltdefault-localegt

ltlanguage locale=engt

lttitlegtMy Bookmarks7lttitlegt

lttitle-shortgtBookmarks7lttitle-shortgt

ltdescriptiongtPortlet showing your personalized bookmarksltdescriptiongt

ltkeywordsgtbookmarksltkeywordsgt

ltlanguagegt

ltconfig-paramgt

ltparam-namegturl1ltparam-namegt

ltparam-valuegthttpwwwgooglecomltparam-valuegt

ltconfig-paramgt

ltconcrete-portletgt

- 14 -

ltconcrete-portlet-appgt

ltportlet-app-defgt

As portlets are servlets in the IBM Portlet API the portletxml has references for each portlet to the servlet in the webxml that represents the portlet The webxml for this example is

IBM PORTLET API WEBXML EXAMPLE

ltxml version=10 encoding=UTF-8gt

ltDOCTYPE web-app

PUBLIC -Sun Microsystems IncDTD Web Application 22EN

httpjavasuncomj2eedtdsweb-app_22dtdgt

ltweb-app id=WebApp_1gt

ltdisplay-namegtbookmark7ltdisplay-namegt

ltservlet id=Servlet_1gt

ltservlet-namegtBookmark7ltservlet-namegt

ltservlet-classgtcommycobookmarkBookmarkPortletltservlet-classgt

ltinit-paramgt

ltparam-namegtjspviewltparam-namegt

ltparam-valuegtbookmarkViewjspltparam-valuegt

ltinit-paramgt

ltinit-paramgt

ltparam-namegtjspeditltparam-namegt

ltparam-valuegtbookmarkEditjspltparam-valuegt

ltinit-paramgt

ltservletgt

ltservlet-mappinggt

ltservlet-namegtBookmark7ltservlet-namegt

lturl-patterngtBookmark7lturl-patterngt

ltservlet-mappinggt

ltweb-appgt

- 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 webxml and not in the portletxml In the JSR 168 the deployment descriptor is more like the webxml 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 portletxml example would look like when using the JSR 168 deployment descriptor format

JSR 168 PORTLETXML EXAMPLE

ltxml version=10 encoding=UTF-8gt

ltxml version=10encoding=UTF-8gt

ltportlet-app xmlns=httpjavasuncomxmlnsportletportlet-app_1_0xsd version=10

xmlnsxsi=httpwwww3org2001XMLSchema-instance

xsischemaLocation=httpjavasuncomxmlnsportlet-app_1_0xsd

httpjavasuncomxmlnsportletportlet-app_1_0xsdgt

ltportletgt

ltdescription xmllang=ENgtPortlet showing your personalized

bookmarksltdescriptiongt

ltportlet-namegtBookmark Portlet7ltportlet-namegt

ltdisplay-name xmllang=ENgtBookmark Portletltdisplay-namegt

ltportlet-classgtcommycobookmarkBookmarkPortletltportlet-classgt

ltinit-paramgt

ltnamegtjspviewltnamegt

ltvaluegtbookmarkViewjspltvaluegt

ltinit-paramgt

ltinit-paramgt

ltnamegtjspeditltnamegt

ltvaluegtbookmarkEditjspltvaluegt

ltinit-paramgt

ltsupportsgt

ltmime-typegttexthtmlltmime-typegt

ltportlet-modegtviewltportlet-modegt

- 16 -

ltportlet-modegteditltportlet-modegt

ltsupportsgt

ltsupported-localegtENltsupported-localegt

ltportlet-infogt

lttitlegtMy Bookmarks7lttitlegt

ltshort-titlegtBookmarks7ltshort-titlegt

ltkeywordsgtbookmarksltkeywordsgt

ltportlet-infogt

ltportlet-preferencesgt

ltpreferencegt

ltnamegturl1ltnamegt

ltvaluegthttpwwwgooglecomltvaluegt

ltpreferencegt

ltportlet-preferencesgt

ltportletgt

ltportlet-appgt

Here the initialization parameters are directly specified in the portletxml as portlets are independent components in the JSR 168 The following example represents the webxml for the JSR 168 bookmark portlet

JSR 168 WEBXML EXAMPLE

ltxml version=10 encoding=UTF-8gt

ltDOCTYPE web-app PUBLIC -Sun Microsystems IncDTD Web Application 23EN

httpjavasuncomdtdweb-app_2_3dtdgt

ltweb-appgt

ltdisplay-namegtBookmark Application7ltdisplay-namegt

ltweb-appgt

The only item that needs to be specified in the JSR 168 webxml 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 portletxml as portlet application name as there can be several concrete instances of the same abstract application

- 17 -

332 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 331) 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 331) 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

333 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

334 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 instanceentity 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 -

335 Portlet API does not extend servlet API

In the IBM Portlet API portlets extend servlets and all the major interfaces (Request Response Session hellip) 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

336 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

bull defineObjects tag ndash to define the basic portlet API objects RenderRequest RenderResponse and PortletConfig

bull actionURL tag ndash to create an action URL bull renderURL tag ndash to create a render URL bull namespace tag ndash 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 donrsquot need decoding

34 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 -

341 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 (eg 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

342 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

3421 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

3422 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 322) 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

3423 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

3424 Request Response properties

Properties can be used by the portalportlet container to send vendor specific information to the portlet andor the portlet can send vendor specific information to the portalportlet-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

343 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 (eg between portlets or between a portlet and a servlet)

344 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 23 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

345 J2EE role support

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

346 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 -

347 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 PortletRequestgetResponseContentTypes 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 (eg ldquotextrdquo or ldquordquo) 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

348 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 (eg an accounting servlet) in response to an action

349 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

3410 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 vendorrsquos 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)

3411 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 xmllang attribute like the

- 22 -

servlet 24 deployment descriptor Thus the same tag with descriptions in different languages can be used (eg 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

35 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)

351 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

bull ActionEventThe action event maps to the action phase call in the JSR 168

bull MessageEventMessage 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)

bull PortletApplicationSettingsAttributeEventPortletSettingsAttributeEventThese are events that get fired when attributes for the application or of the portlet settings change

bull WindowEventThe portlet will register for window events to get notified if the portlet window is changed via the window decorations

352 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 -

bull PortletPageListener The page listeners provides the portlet with events for the beginning of the page before any markup is written for this page (eg to write JavaScript at the beginning of the page) and the end of the page after all markup is written

bull 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 23 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

bull EventPhaseListener The event phase listener notifies the portlet of the beginning and end of the eventaction phase

353 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

354 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 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

Figure 4

- 24 -

Figure 4 Portlet menu example

355 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

356 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 -

36 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 indicates portlet in what mode to operate for a given request

View edit help + custom modes

view edit help + custom modes

full alignment

Window State the state of the window in which the portlet output will be displayed

minimized normal maximized solo +

custom window states

minimized normal maximized +

custom window states

full alignment (ldquosolordquo is missing in the JSR but can be implemented as a custom state)

URL encoding to allow re-writing URLs created by the portlet

defines how to create URLs to allow re-writing of the URLs either on consumer or producer side

encapsulates URL creation via a Java object

full alignment (the implementation of the Java object can implement the WSRP URL rewriting rules)

Namespace encoding to avoid that several portlets on a page conflicting with each other

defines namespace prefixes for consumer and producer side namespacing

provides a Java method to namespace a String

full alignment (the JSR namespace method can implement the WSRP namespace behavior)

User ndash portlet interaction operations

performBlockingInteraction blocking action processing

getMarkup render the markup

action blocking action processing

render render the makup

full alignment (action invocations carried through performBlockingInteraction render carried through getMarkup)

View state that allows the current portlet fragment to be correctly displayed in sub-sequent render calls

navigational state render parameter full alignment (WSRP navigational state maps to JSR render parameters)

Storing transient state across request

session state concept implemented via a sessionID

utilizes the Http web application session

full alignment (the WSRP sessionID can be used to reference the JSR session)

Storing persistent state to personalize the rendering of the portlet

allows to have properties of arbitrary types

provides String-based preferences

full alignment (JSR String preferences can be mapped to WSRP properties)

Information about the portal calling the portlet

RegistrationData provide information of the consumer to the producer

PortalContext provide a Java interface to access information about the portal calling the portlet

full alignment (all data represented through the PortalContext to the JSR portlet are available in the RegistrationData)

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

Aggregated HTML WML VoiceXML

over HTTPMark-Up Fragments

Transferred via WSRP

Portal

WSRP Service

WSRP Service

WSRP Service

WSRP Consumer WSRP Producer

Use of WSRP Services in Portals

Portal sharing Portlets as WSRP Services

ServerPortalPortals

Huge numberof users Publishing Portal

WSRPWrapperPortalsPortalsPortal

Portlet

Portlet

Portlet

WSRP Consumer WSRP Producer

ProxyPortlet

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

bull 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

bull 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

bull 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

bull 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 CCPP standard allowing a portlet to query the client capabilities and adopting its markup accordingly (eg screen size browser) This API is likely to be included in the next version of the portlet API Also J2EE 14 was finalized during this time period J2EE 14 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 14

bull caching The first version of the JSR 168 API is limited to expiration-based caching (see section 327) 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

bull 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

51 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

511 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

bull portlets are components Portlets are components that implement a specific function Different functions should be distributed to different portlets

bull 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

bull 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

512 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 HttpServletRequestgetSession() call in the JSPs called via the IBM Portlet API needs to be replaced when moving to JSR 168 portlets by the RenderRequestgetPortletSession() 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 HttpServletRequestgetSession() will get the HttpSession and therefore need to access the portlet session via the RenderRequest

513 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

514 Persistent data

Portlets can store customization and personalization data persistently Customization data are related to the portlet and are valid for all users (eg 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 (eg 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

515 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

516 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

52 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

521 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 351 353) 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

522 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

53 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 -

531 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

bull no support of the back button in the browser bull current state of the portlet is not bookmarkable bull 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 bull 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

54 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

541 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 -

542 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

543 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

544 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 wersquoll 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

Figure 7After clicking on the Edit mode button the portlet renders the Edit view shown in

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

Figure 8

After we press the ldquoAddrdquo 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

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

bull use JSPs for rendering the output bull customize the portlet output taking user specific data into account bull 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

61 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 comibmwpssampleswp5

import javaio

import javautil

import orgapachejetspeedportlet

import orgapachejetspeedportletevent

public class IbmBookmark extends PortletAdapter implements ActionListener

public void init(PortletConfig portletConfig) throws UnavailableException

superinit(portletConfig)

- 36 -

public void doView(PortletRequest request PortletResponse response)

throws PortletException IOException

String jspName = thisgetPortletConfig()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 = responsecreateReturnURI()

addURIaddAction(add)

requestsetAttribute(addURI addURItoString())

PortletURI cancelURI = responsecreateReturnURI()

requestsetAttribute(cancelURI cancelURItoString())

String jspName = thisgetPortletConfig()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 ldquocancelrdquo and ldquoaddrdquo URLs are created inside the portlet and attached to the request before including the Edit JSP Both URLs are from type ldquoReturnURIrdquo 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 = eventgetRequest()

String action = eventgetActionString()

PortletLog log = getPortletLog()

if ( action=null )

try

if (actionequals(removeURI))

String removeName = requestgetParameter(remove)

PortletData portData = requestgetData()

portDataremoveAttribute(removeName)

portDatastore()

if (actionequals(add))

PortletData portData = requestgetData()

String name = requestgetParameter(name)

String value = requestgetParameter(value)

portDatasetAttribute(name value)

portDatastore()

catch ( AccessDeniedException ade )

logerror(AccessDeniedException occured when adding or deleting a bookmark)

catch ( IOException ioe )

logerror(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 ldquoaddrdquo or ldquodeleterdquo 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 ldquoaddrdquo or ldquoremoveURIrdquo If the user has clicked on the ldquoremoverdquo button the corresponding link is removed from the portlet data whereas if ldquoaddrdquo was clicked the data entered by the user is added to the portlet data

62 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 comibmwpssamplesjsr

import javaio

import javaxportlet

public class Bookmark extends GenericPortlet

public void init(PortletConfig config) throws PortletException

superinit(config)

public void doView(RenderRequest request RenderResponse response)

throws PortletException IOException

responsesetContentType(texthtml)

String jspName = getPortletConfig()getInitParameter(jspView)

PortletRequestDispatcher rd = getPortletContext()getRequestDispatcher(jspName)

rdinclude(requestresponse)

- 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

responsesetContentType(texthtml)

PortletURL addUrl = responsecreateActionURL()

addUrlsetPortletMode(PortletModeVIEW)

addUrlsetParameter(addadd)

requestsetAttribute(addUrladdUrltoString())

PortletURL cancelUrl = responsecreateRenderURL()

cancelUrlsetPortletMode(PortletModeVIEW)

requestsetAttribute(cancelUrlcancelUrltoString())

String jspName = getPortletConfig()getInitParameter(jspEdit)

PortletRequestDispatcher rd = getPortletContext()getRequestDispatcher(jspName)

rdinclude(requestresponse)

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 ldquoaddrdquo button URL an action URL is created as we need to store the user input of the add form persistently For the ldquocancelrdquo 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 = requestgetParameter(remove)

if (removeName = null)

PortletPreferences prefs = requestgetPreferences()

prefsreset(removeName)

prefsstore()

String add = requestgetParameter(add)

if (add = null)

PortletPreferences prefs = requestgetPreferences()

String name = requestgetParameter(name)

String value = requestgetParameter(value)

prefssetValue(name value)

prefsstore()

catch ( IOException ioe )

getPortletContextlog(An IO error occured when trying to remove a bookmark)

catch ( PortletException pe )

getPortletContextlog(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

bull 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

bull 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

bull Persistent portlet data The JSR 168 persistent data PortletPreferences have an API similar to the JDK 14 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

bull 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

63 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

lt page contentType=texthtml import=javautil comibmwpssampleswp5

orgapachejetspeedportlet session=falsegt

lt taglib uri=WEB-INFtldportlettld prefix=portletAPI gt

- 42 -

ltportletAPIinitgt

ltp class=wpsPortletHeadgtltportletAPItext key=available_bookmarks

bundle=nlsTextgtAvailable BookmarksltportletAPItextgtltpgt

lt

PortletData prefs = portletRequestgetData()

Enumeration e = prefsgetAttributeNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltportletAPItext key=no_bookmarks bundle=nlsTextgtNo

bookmarksltportletAPItextgtltpgt

lt

else

gt

ltp class=wpsIndentMediumgt

lt

while (ehasMoreElements())

String name = (String)enextElement()

String value = (String)prefsgetAttribute(name)

gt

lta href=lt=valuegt target=_blankgtlt=namegtltagtltbr gt

lt

gt

ltpgt

The View JSP first call portletAPIinit 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

lt page contentType=texthtml import=javautil

comibmwpssampleswp5orgapachejetspeedportlet session=falsegt

lt taglib uri=WEB-INFtldportlettld prefix=portletAPI gt

ltjspuseBean id=addURI class=javalangString scope=request gt

ltjspuseBean id=cancelURI class=javalangString scope=request gt

ltportletAPIinitgt

lth4gtltportletAPItext key=available_bookmarks bundle=nlsTextgtAvailable

BookmarksltportletAPItextgtlth4gt

lttable class=wpsTablegt

lttr class=wpsTableRowgt

ltth class=portlet-table-headergtltportletAPItext key=name bundle=nlsTextgtltthgt

ltth class=portlet-table-headergtltportletAPItext key=url bundle=nlsTextgtltthgt

lttdgtlttdgt

lttrgt

lt

PortletData prefs = portletRequestgetData()

Enumeration e = prefsgetAttributeNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltportletAPItext key=no_bookmarks bundle=nlsTextgtNo

bookmarksltportletAPItextgtltpgt

lt

else

while (ehasMoreElements())

- 44 -

String name = (String)enextElement()

String value = (String)prefsgetAttribute(name)

gt

lttr class=wpsTableRowgt

lttdgt lt=namegt lttdgt

lttdgt lt=valuegt lttdgt

lttdgt lta href=ltportletAPIcreateURIgtltportletAPIURIAction

name=removeURIgtltportletAPIURIParameter name=remove

value=lt=namegtgtltportletAPIcreateURIgtgt

(ltportletAPItext key=delete bundle=nlsTextgt)ltagt

lttdgt

lttrgt

lt

gt

ltform action=lt=addURIgt method=POSTgt

lttr class=wpsTableRowgt

lttdgtltinput name=ltportletAPIencodeNamespace value=namegt type=text

class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=ltportletAPIencodeNamespace value=valuegt type=text

class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=ltportletAPIencodeNamespace value=addgt type=submit

value=ltportletAPItext key=add bundle=nlsTextgt class=portlet-form-buttongtlttdgt

lttrgt

ltformgt

lttablegt

- 45 -

ltform action=lt=cancelURIgt method=postgt

ltinput name=ltportletAPIencodeNamespace value=cancelgt type=submit

value=ltportletAPItext key=cancel bundle=nlsTextgt class=portlet-form-buttongt

ltformgt

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 ldquodeleterdquo button for which an URL with the action ldquoremoveURIrdquo 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 ldquocancelrdquo button from the request

64 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

lt page import=javaxportlet javautil session=falsegt

lt taglib uri=httpjavasuncomportlet prefix=portletAPI gt

lt taglib prefix=fmt uri=httpjavasuncomjstlfmt gt

ltportletAPIdefineObjects gt

ltfmtsetBundle basename=nlsTextgt

lt

ResourceBundle myText = ResourceBundlegetBundle(nlsText requestgetLocale())

gt

lth4gtltfmtmessage key=available_bookmarksgtlth4gt

lt

PortletPreferences prefs = renderRequestgetPreferences()

Enumeration e = prefsgetNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltfmtmessage key=no_bookmarksgtltpgt

- 46 -

lt

else

gt

ltpgt

lt

while (ehasMoreElements())

String name = (String)enextElement()

String value = prefsgetValue(namelt+myTextgetString(undefined)+gt)

gt

lta href=lt=valuegt target=_blankgtlt=namegtltagtltbr gt

lt

gt

ltpgt

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 fmtmessage 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

lt page import=javaxportlet javautil session=false gt

lt taglib uri=httpjavasuncomportlet prefix=portletAPI gt

lt taglib prefix=fmt uri=httpjavasuncomjstlfmt gt

ltjspuseBean id=addUrl scope=request class=javalangString gt

ltjspuseBean id=cancelUrl scope=request class=javalangString gt

- 47 -

ltportletAPIdefineObjectsgt

lt

ResourceBundle myText = ResourceBundlegetBundle(nlsText requestgetLocale())

gt

ltfmtsetBundle basename=nlsTextgt

lth4gtltfmtmessage key=available_bookmarksgtlth4gt

lttable class=wpsTablegt

lttr class=wpsTableRowgt

ltth class=wpsTableHeadgtltfmtmessage key=namegtltthgt

ltth class=wpsTableHeadgtltfmtmessage key=urlgtltthgt

lttdgtlttdgt

lttrgt

lt

PortletPreferences prefs = renderRequestgetPreferences()

Enumeration e = prefsgetNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltfmtmessage key=no_bookmarksgtltpgt

lt

else

while (ehasMoreElements())

String name = (String)enextElement()

String value = prefsgetValue(namelt+myTextgetString(undefined)+gt)

gt

lttr class=wpsTableRowgt

lttdgt lt=namegt lttdgt

lttdgt lt=valuegt lttdgt

- 48 -

lttdgt ltportletAPIactionURL var=removeUrlgt

ltportletAPIparam name=remove value=lt=namegtgt

ltportletAPIactionURLgt

lta href=lt=removeUrltoString()gtgt(ltfmtmessage key=deletegt)ltagt

lttdgt

lttrgt

lt

gt

ltform action=lt=addUrlgt method=POSTgt

lttr class=wpsTableRowgt

lttdgtltinput name=name type=text class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=value type=text class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=add type=submit value=ltfmtmessage key=addgt

class=portlet-form-buttongtlttdgt

lttrgt

ltformgt

lttablegt

ltform action=lt=cancelUrlgt method=postgt

ltinput name=cancel type=submit value=ltfmtmessage key=cancelgt class=portlet-

form-buttongt

ltformgt

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 14 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 -

- 51 -

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 (eg eventing) the IBM Portlet API still needs to be used Trademarks bull IBM and WebSphere are trademarks or registered trademarks of IBM Corporation in

the United States other countries or both bull 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 bull Other company product and service names may be trademarks or service marks of

others IBM copyright and trademark information httpwwwibmcomlegalcopytradephtml

  • Introduction
  • JSR 168 and the Java Community Process
  • Comparing concepts
    • Basic concepts
      • Portal
      • Portal page
      • Portlet
      • Portlet Container
        • Concepts that are the same
          • Portlet mode
          • Window state
          • Portlet life cycle and request processing
          • URL encoding
          • Include servletsJSPs
          • Portlet application packaging
          • Expiration-based caching
            • Concepts that differ
              • Portlet application entity
              • Portlet entity
              • Action and Render Request Response objects
              • Window concept
              • Portlet API does not extend servlet API
              • TAG libraries
                • Concepts new in the JSR 168
                  • Render parameter
                  • Extension mechanisms
                    • Custom window states
                    • Custom portlet modes
                    • Custom user info
                    • Request Response properties
                      • Web application session scope
                      • Reuse of the HttpSession listeners
                      • J2EE role support
                      • Resource bundles
                      • Multiple response content types
                      • Redirect in action
                      • Preference validator
                      • Portal context
                      • Localization support
                        • Concepts missing in the JSR 168
                          • Eventing
                          • Additional lifecycle events
                          • Property broker
                          • Portlet Menus
                          • Portlet Services
                          • Invalidation-based caching
                            • Alignment with WSRP
                              • Outlook for the next version of the JSR 168
                              • Guidelines for programming IBM Portlet API portlets
                                • Similar Functionality
                                  • Basic programming model
                                  • Portlet private session
                                  • User profile information
                                  • Persistent data
                                  • Portlet modes and window states
                                  • Expiration-based caching
                                    • Slightly different functionality
                                      • Sharing of data between portlets
                                      • Session listeners
                                        • New JSR 168 functionality
                                          • Navigational state (render parameters)
                                            • Pitfalls
                                              • Request response objects for action and render phase
                                              • Include search path
                                              • Form parameter encoding
                                              • Title setting
                                                  • Examples
                                                    • IBM Portlet API Portlet Code
                                                    • JSR 168 Portlet Code
                                                    • IBM Portlet API JSPs
                                                    • JSR 168 JSPs
                                                      • Summary
Page 4: Difference Bw Jsr168 and Ibm

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 Javatrade 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 IBMreg WebSpherereg Portal Version 50 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 Javatrade 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 httpjcporg 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 httpjcporgenjsrdetailid=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

31 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

311 Portal

A portal is a web based application that ndashcommonly ndash 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

PortalWeb

ApplicationHTTP

HTML

WML

Voi

ceXM

L

Portl

et In

voke

r API Portlet

(App)Po

rtlet

API

Portlet(App)

Portlet(App)

PortletServletContainer

Portl

et P

rovid

er S

PI

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

312 Portal page

Figure 2

Figure 2 Basic portal page components

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 (eg maximize or minimize the portlet) and buttons to change the mode of a portlet (eg show help or edit the predefined portlet settings)

ltTitlegt Edit

Portlet content

Portal page

Portletwindows

Window states Portlet modes

Markup Fragments

ltTitlegt Edit

ltTitlegt Edit

Portlet content

Portlet content

- 7 -

313 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 (eg 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 requestresponse 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 users interactions

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

314 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

32 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

321 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

bull Edit ndash to display one or more personalization views that let the user personalize portlet settings

bull Help ndash to display help views bull View ndash to display the portlet output bull Configure ndash 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

bull required to support (same semantic as above) o Edit o Help o View

bull optional custom modes o About ndash to display information on the portlets purpose origin version etc o Config ndash has the same semantic as the IBM Portlet API configure mode o Edit_defaults ndash to set the default values for the modifiable preferences that

are typically changed in the EDIT screen o Preview ndash to render output without the need of having back-end

connections or user specific data available o Print ndash to display a view that is suitable for printing

bull portal vendor specific modes that are available only in a portal of a specific vendor

322 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

bull Closed (deprecated) ndash to indicate that a window should be closed bull Detached (deprecated) ndash to indicate that a window should be detached bull Maximized ndash to indicate that a window has more real estate to render its output

then in normal window state

- 9 -

bull Minimized ndash to indicate that the portlet is minimized and cannot render any output

bull Moving (deprecated) ndash to indicate that the portlet window has been moved bull Normal ndash to indicate that the portlet is sharing its screen with other portlets on a

page bull Resizing (deprecated) ndash to indicate that the portlet has been resized bull Solo ndash to indicate that the portlet is the only portlet on the page

Whereas the JSR 168 has only the following mandatory window states

bull Maximized ndash same as in the IBM Portlet API bull Minimized ndash to indicate that the portlet should only render minimal or no output bull Normal ndash same as in the IBM Portlet API

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

323 Portlet life cycle and request processing

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

bull init ndash to initialize the portlet and put the portlet into service bull handle requests ndash process different kinds of action and render requests bull destroy ndash 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

324 URL encoding

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

bull 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

bull 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

325 Include servletsJSPs

In both APIrsquos 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()

contextinclude(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)

rdinclude(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 HttpServetRequestgetSession() 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

326 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 (webxml) and one to specify the portlet resources (portletxml) All web resources that are not portlets must be specified in the webxml deployment descriptor All portlets and portlet related settings must be specified in an additional file called portletxml

- 12 -

Different from JSR 168 in the IBM Portlet API all portlets must also be listed in the webxml as they are also servlets (see also 335 for examples of the deployment descitptors)

327 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

33 Concepts that differ

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

331 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 webxml and concrete portlet applications of concrete portlets based on the abstract ones The following portletxml example shows these two different parts

IBM PORTLET API PORTLETXML EXAMPLE

ltxml version=10 encoding=UTF-8gt

ltDOCTYPE portlet-app-def PUBLIC -IBMDTD Portlet Application 11EN

portlet_11dtdgt

ltportlet-app-defgt

ltportlet-app uid=commycobookmark1234 major-version=7 minor-version=24gt

ltportlet-app-namegtBookmark Application7ltportlet-app-namegt

ltportlet id=Portlet_1 href=WEB-INFwebxmlServlet_1gt

- 13 -

ltportlet-namegtBookmark Portlet7ltportlet-namegt

ltallowsgt

ltmaximizedgt

ltminimizedgt

ltallowsgt

ltsupportsgt

ltmarkup name=htmlgt

ltview output=fragmentgt

ltedit output=fragmentgt

ltmarkupgt

ltsupportsgt

ltportletgt

ltportlet-appgt

ltconcrete-portlet-app uid=commycobookmark12341gt

ltportlet-app-namegtConcreteSamplets_Bookmark7ltportlet-app-namegt

ltconcrete-portlet href=Portlet_1gt

ltportlet-namegtBookmark Portlet7ltportlet-namegt

ltdefault-localegtenltdefault-localegt

ltlanguage locale=engt

lttitlegtMy Bookmarks7lttitlegt

lttitle-shortgtBookmarks7lttitle-shortgt

ltdescriptiongtPortlet showing your personalized bookmarksltdescriptiongt

ltkeywordsgtbookmarksltkeywordsgt

ltlanguagegt

ltconfig-paramgt

ltparam-namegturl1ltparam-namegt

ltparam-valuegthttpwwwgooglecomltparam-valuegt

ltconfig-paramgt

ltconcrete-portletgt

- 14 -

ltconcrete-portlet-appgt

ltportlet-app-defgt

As portlets are servlets in the IBM Portlet API the portletxml has references for each portlet to the servlet in the webxml that represents the portlet The webxml for this example is

IBM PORTLET API WEBXML EXAMPLE

ltxml version=10 encoding=UTF-8gt

ltDOCTYPE web-app

PUBLIC -Sun Microsystems IncDTD Web Application 22EN

httpjavasuncomj2eedtdsweb-app_22dtdgt

ltweb-app id=WebApp_1gt

ltdisplay-namegtbookmark7ltdisplay-namegt

ltservlet id=Servlet_1gt

ltservlet-namegtBookmark7ltservlet-namegt

ltservlet-classgtcommycobookmarkBookmarkPortletltservlet-classgt

ltinit-paramgt

ltparam-namegtjspviewltparam-namegt

ltparam-valuegtbookmarkViewjspltparam-valuegt

ltinit-paramgt

ltinit-paramgt

ltparam-namegtjspeditltparam-namegt

ltparam-valuegtbookmarkEditjspltparam-valuegt

ltinit-paramgt

ltservletgt

ltservlet-mappinggt

ltservlet-namegtBookmark7ltservlet-namegt

lturl-patterngtBookmark7lturl-patterngt

ltservlet-mappinggt

ltweb-appgt

- 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 webxml and not in the portletxml In the JSR 168 the deployment descriptor is more like the webxml 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 portletxml example would look like when using the JSR 168 deployment descriptor format

JSR 168 PORTLETXML EXAMPLE

ltxml version=10 encoding=UTF-8gt

ltxml version=10encoding=UTF-8gt

ltportlet-app xmlns=httpjavasuncomxmlnsportletportlet-app_1_0xsd version=10

xmlnsxsi=httpwwww3org2001XMLSchema-instance

xsischemaLocation=httpjavasuncomxmlnsportlet-app_1_0xsd

httpjavasuncomxmlnsportletportlet-app_1_0xsdgt

ltportletgt

ltdescription xmllang=ENgtPortlet showing your personalized

bookmarksltdescriptiongt

ltportlet-namegtBookmark Portlet7ltportlet-namegt

ltdisplay-name xmllang=ENgtBookmark Portletltdisplay-namegt

ltportlet-classgtcommycobookmarkBookmarkPortletltportlet-classgt

ltinit-paramgt

ltnamegtjspviewltnamegt

ltvaluegtbookmarkViewjspltvaluegt

ltinit-paramgt

ltinit-paramgt

ltnamegtjspeditltnamegt

ltvaluegtbookmarkEditjspltvaluegt

ltinit-paramgt

ltsupportsgt

ltmime-typegttexthtmlltmime-typegt

ltportlet-modegtviewltportlet-modegt

- 16 -

ltportlet-modegteditltportlet-modegt

ltsupportsgt

ltsupported-localegtENltsupported-localegt

ltportlet-infogt

lttitlegtMy Bookmarks7lttitlegt

ltshort-titlegtBookmarks7ltshort-titlegt

ltkeywordsgtbookmarksltkeywordsgt

ltportlet-infogt

ltportlet-preferencesgt

ltpreferencegt

ltnamegturl1ltnamegt

ltvaluegthttpwwwgooglecomltvaluegt

ltpreferencegt

ltportlet-preferencesgt

ltportletgt

ltportlet-appgt

Here the initialization parameters are directly specified in the portletxml as portlets are independent components in the JSR 168 The following example represents the webxml for the JSR 168 bookmark portlet

JSR 168 WEBXML EXAMPLE

ltxml version=10 encoding=UTF-8gt

ltDOCTYPE web-app PUBLIC -Sun Microsystems IncDTD Web Application 23EN

httpjavasuncomdtdweb-app_2_3dtdgt

ltweb-appgt

ltdisplay-namegtBookmark Application7ltdisplay-namegt

ltweb-appgt

The only item that needs to be specified in the JSR 168 webxml 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 portletxml as portlet application name as there can be several concrete instances of the same abstract application

- 17 -

332 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 331) 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 331) 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

333 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

334 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 instanceentity 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 -

335 Portlet API does not extend servlet API

In the IBM Portlet API portlets extend servlets and all the major interfaces (Request Response Session hellip) 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

336 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

bull defineObjects tag ndash to define the basic portlet API objects RenderRequest RenderResponse and PortletConfig

bull actionURL tag ndash to create an action URL bull renderURL tag ndash to create a render URL bull namespace tag ndash 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 donrsquot need decoding

34 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 -

341 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 (eg 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

342 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

3421 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

3422 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 322) 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

3423 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

3424 Request Response properties

Properties can be used by the portalportlet container to send vendor specific information to the portlet andor the portlet can send vendor specific information to the portalportlet-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

343 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 (eg between portlets or between a portlet and a servlet)

344 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 23 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

345 J2EE role support

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

346 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 -

347 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 PortletRequestgetResponseContentTypes 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 (eg ldquotextrdquo or ldquordquo) 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

348 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 (eg an accounting servlet) in response to an action

349 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

3410 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 vendorrsquos 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)

3411 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 xmllang attribute like the

- 22 -

servlet 24 deployment descriptor Thus the same tag with descriptions in different languages can be used (eg 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

35 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)

351 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

bull ActionEventThe action event maps to the action phase call in the JSR 168

bull MessageEventMessage 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)

bull PortletApplicationSettingsAttributeEventPortletSettingsAttributeEventThese are events that get fired when attributes for the application or of the portlet settings change

bull WindowEventThe portlet will register for window events to get notified if the portlet window is changed via the window decorations

352 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 -

bull PortletPageListener The page listeners provides the portlet with events for the beginning of the page before any markup is written for this page (eg to write JavaScript at the beginning of the page) and the end of the page after all markup is written

bull 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 23 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

bull EventPhaseListener The event phase listener notifies the portlet of the beginning and end of the eventaction phase

353 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

354 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 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

Figure 4

- 24 -

Figure 4 Portlet menu example

355 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

356 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 -

36 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 indicates portlet in what mode to operate for a given request

View edit help + custom modes

view edit help + custom modes

full alignment

Window State the state of the window in which the portlet output will be displayed

minimized normal maximized solo +

custom window states

minimized normal maximized +

custom window states

full alignment (ldquosolordquo is missing in the JSR but can be implemented as a custom state)

URL encoding to allow re-writing URLs created by the portlet

defines how to create URLs to allow re-writing of the URLs either on consumer or producer side

encapsulates URL creation via a Java object

full alignment (the implementation of the Java object can implement the WSRP URL rewriting rules)

Namespace encoding to avoid that several portlets on a page conflicting with each other

defines namespace prefixes for consumer and producer side namespacing

provides a Java method to namespace a String

full alignment (the JSR namespace method can implement the WSRP namespace behavior)

User ndash portlet interaction operations

performBlockingInteraction blocking action processing

getMarkup render the markup

action blocking action processing

render render the makup

full alignment (action invocations carried through performBlockingInteraction render carried through getMarkup)

View state that allows the current portlet fragment to be correctly displayed in sub-sequent render calls

navigational state render parameter full alignment (WSRP navigational state maps to JSR render parameters)

Storing transient state across request

session state concept implemented via a sessionID

utilizes the Http web application session

full alignment (the WSRP sessionID can be used to reference the JSR session)

Storing persistent state to personalize the rendering of the portlet

allows to have properties of arbitrary types

provides String-based preferences

full alignment (JSR String preferences can be mapped to WSRP properties)

Information about the portal calling the portlet

RegistrationData provide information of the consumer to the producer

PortalContext provide a Java interface to access information about the portal calling the portlet

full alignment (all data represented through the PortalContext to the JSR portlet are available in the RegistrationData)

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

Aggregated HTML WML VoiceXML

over HTTPMark-Up Fragments

Transferred via WSRP

Portal

WSRP Service

WSRP Service

WSRP Service

WSRP Consumer WSRP Producer

Use of WSRP Services in Portals

Portal sharing Portlets as WSRP Services

ServerPortalPortals

Huge numberof users Publishing Portal

WSRPWrapperPortalsPortalsPortal

Portlet

Portlet

Portlet

WSRP Consumer WSRP Producer

ProxyPortlet

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

bull 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

bull 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

bull 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

bull 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 CCPP standard allowing a portlet to query the client capabilities and adopting its markup accordingly (eg screen size browser) This API is likely to be included in the next version of the portlet API Also J2EE 14 was finalized during this time period J2EE 14 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 14

bull caching The first version of the JSR 168 API is limited to expiration-based caching (see section 327) 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

bull 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

51 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

511 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

bull portlets are components Portlets are components that implement a specific function Different functions should be distributed to different portlets

bull 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

bull 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

512 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 HttpServletRequestgetSession() call in the JSPs called via the IBM Portlet API needs to be replaced when moving to JSR 168 portlets by the RenderRequestgetPortletSession() 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 HttpServletRequestgetSession() will get the HttpSession and therefore need to access the portlet session via the RenderRequest

513 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

514 Persistent data

Portlets can store customization and personalization data persistently Customization data are related to the portlet and are valid for all users (eg 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 (eg 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

515 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

516 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

52 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

521 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 351 353) 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

522 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

53 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 -

531 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

bull no support of the back button in the browser bull current state of the portlet is not bookmarkable bull 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 bull 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

54 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

541 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 -

542 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

543 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

544 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 wersquoll 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

Figure 7After clicking on the Edit mode button the portlet renders the Edit view shown in

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

Figure 8

After we press the ldquoAddrdquo 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

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

bull use JSPs for rendering the output bull customize the portlet output taking user specific data into account bull 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

61 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 comibmwpssampleswp5

import javaio

import javautil

import orgapachejetspeedportlet

import orgapachejetspeedportletevent

public class IbmBookmark extends PortletAdapter implements ActionListener

public void init(PortletConfig portletConfig) throws UnavailableException

superinit(portletConfig)

- 36 -

public void doView(PortletRequest request PortletResponse response)

throws PortletException IOException

String jspName = thisgetPortletConfig()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 = responsecreateReturnURI()

addURIaddAction(add)

requestsetAttribute(addURI addURItoString())

PortletURI cancelURI = responsecreateReturnURI()

requestsetAttribute(cancelURI cancelURItoString())

String jspName = thisgetPortletConfig()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 ldquocancelrdquo and ldquoaddrdquo URLs are created inside the portlet and attached to the request before including the Edit JSP Both URLs are from type ldquoReturnURIrdquo 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 = eventgetRequest()

String action = eventgetActionString()

PortletLog log = getPortletLog()

if ( action=null )

try

if (actionequals(removeURI))

String removeName = requestgetParameter(remove)

PortletData portData = requestgetData()

portDataremoveAttribute(removeName)

portDatastore()

if (actionequals(add))

PortletData portData = requestgetData()

String name = requestgetParameter(name)

String value = requestgetParameter(value)

portDatasetAttribute(name value)

portDatastore()

catch ( AccessDeniedException ade )

logerror(AccessDeniedException occured when adding or deleting a bookmark)

catch ( IOException ioe )

logerror(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 ldquoaddrdquo or ldquodeleterdquo 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 ldquoaddrdquo or ldquoremoveURIrdquo If the user has clicked on the ldquoremoverdquo button the corresponding link is removed from the portlet data whereas if ldquoaddrdquo was clicked the data entered by the user is added to the portlet data

62 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 comibmwpssamplesjsr

import javaio

import javaxportlet

public class Bookmark extends GenericPortlet

public void init(PortletConfig config) throws PortletException

superinit(config)

public void doView(RenderRequest request RenderResponse response)

throws PortletException IOException

responsesetContentType(texthtml)

String jspName = getPortletConfig()getInitParameter(jspView)

PortletRequestDispatcher rd = getPortletContext()getRequestDispatcher(jspName)

rdinclude(requestresponse)

- 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

responsesetContentType(texthtml)

PortletURL addUrl = responsecreateActionURL()

addUrlsetPortletMode(PortletModeVIEW)

addUrlsetParameter(addadd)

requestsetAttribute(addUrladdUrltoString())

PortletURL cancelUrl = responsecreateRenderURL()

cancelUrlsetPortletMode(PortletModeVIEW)

requestsetAttribute(cancelUrlcancelUrltoString())

String jspName = getPortletConfig()getInitParameter(jspEdit)

PortletRequestDispatcher rd = getPortletContext()getRequestDispatcher(jspName)

rdinclude(requestresponse)

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 ldquoaddrdquo button URL an action URL is created as we need to store the user input of the add form persistently For the ldquocancelrdquo 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 = requestgetParameter(remove)

if (removeName = null)

PortletPreferences prefs = requestgetPreferences()

prefsreset(removeName)

prefsstore()

String add = requestgetParameter(add)

if (add = null)

PortletPreferences prefs = requestgetPreferences()

String name = requestgetParameter(name)

String value = requestgetParameter(value)

prefssetValue(name value)

prefsstore()

catch ( IOException ioe )

getPortletContextlog(An IO error occured when trying to remove a bookmark)

catch ( PortletException pe )

getPortletContextlog(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

bull 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

bull 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

bull Persistent portlet data The JSR 168 persistent data PortletPreferences have an API similar to the JDK 14 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

bull 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

63 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

lt page contentType=texthtml import=javautil comibmwpssampleswp5

orgapachejetspeedportlet session=falsegt

lt taglib uri=WEB-INFtldportlettld prefix=portletAPI gt

- 42 -

ltportletAPIinitgt

ltp class=wpsPortletHeadgtltportletAPItext key=available_bookmarks

bundle=nlsTextgtAvailable BookmarksltportletAPItextgtltpgt

lt

PortletData prefs = portletRequestgetData()

Enumeration e = prefsgetAttributeNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltportletAPItext key=no_bookmarks bundle=nlsTextgtNo

bookmarksltportletAPItextgtltpgt

lt

else

gt

ltp class=wpsIndentMediumgt

lt

while (ehasMoreElements())

String name = (String)enextElement()

String value = (String)prefsgetAttribute(name)

gt

lta href=lt=valuegt target=_blankgtlt=namegtltagtltbr gt

lt

gt

ltpgt

The View JSP first call portletAPIinit 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

lt page contentType=texthtml import=javautil

comibmwpssampleswp5orgapachejetspeedportlet session=falsegt

lt taglib uri=WEB-INFtldportlettld prefix=portletAPI gt

ltjspuseBean id=addURI class=javalangString scope=request gt

ltjspuseBean id=cancelURI class=javalangString scope=request gt

ltportletAPIinitgt

lth4gtltportletAPItext key=available_bookmarks bundle=nlsTextgtAvailable

BookmarksltportletAPItextgtlth4gt

lttable class=wpsTablegt

lttr class=wpsTableRowgt

ltth class=portlet-table-headergtltportletAPItext key=name bundle=nlsTextgtltthgt

ltth class=portlet-table-headergtltportletAPItext key=url bundle=nlsTextgtltthgt

lttdgtlttdgt

lttrgt

lt

PortletData prefs = portletRequestgetData()

Enumeration e = prefsgetAttributeNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltportletAPItext key=no_bookmarks bundle=nlsTextgtNo

bookmarksltportletAPItextgtltpgt

lt

else

while (ehasMoreElements())

- 44 -

String name = (String)enextElement()

String value = (String)prefsgetAttribute(name)

gt

lttr class=wpsTableRowgt

lttdgt lt=namegt lttdgt

lttdgt lt=valuegt lttdgt

lttdgt lta href=ltportletAPIcreateURIgtltportletAPIURIAction

name=removeURIgtltportletAPIURIParameter name=remove

value=lt=namegtgtltportletAPIcreateURIgtgt

(ltportletAPItext key=delete bundle=nlsTextgt)ltagt

lttdgt

lttrgt

lt

gt

ltform action=lt=addURIgt method=POSTgt

lttr class=wpsTableRowgt

lttdgtltinput name=ltportletAPIencodeNamespace value=namegt type=text

class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=ltportletAPIencodeNamespace value=valuegt type=text

class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=ltportletAPIencodeNamespace value=addgt type=submit

value=ltportletAPItext key=add bundle=nlsTextgt class=portlet-form-buttongtlttdgt

lttrgt

ltformgt

lttablegt

- 45 -

ltform action=lt=cancelURIgt method=postgt

ltinput name=ltportletAPIencodeNamespace value=cancelgt type=submit

value=ltportletAPItext key=cancel bundle=nlsTextgt class=portlet-form-buttongt

ltformgt

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 ldquodeleterdquo button for which an URL with the action ldquoremoveURIrdquo 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 ldquocancelrdquo button from the request

64 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

lt page import=javaxportlet javautil session=falsegt

lt taglib uri=httpjavasuncomportlet prefix=portletAPI gt

lt taglib prefix=fmt uri=httpjavasuncomjstlfmt gt

ltportletAPIdefineObjects gt

ltfmtsetBundle basename=nlsTextgt

lt

ResourceBundle myText = ResourceBundlegetBundle(nlsText requestgetLocale())

gt

lth4gtltfmtmessage key=available_bookmarksgtlth4gt

lt

PortletPreferences prefs = renderRequestgetPreferences()

Enumeration e = prefsgetNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltfmtmessage key=no_bookmarksgtltpgt

- 46 -

lt

else

gt

ltpgt

lt

while (ehasMoreElements())

String name = (String)enextElement()

String value = prefsgetValue(namelt+myTextgetString(undefined)+gt)

gt

lta href=lt=valuegt target=_blankgtlt=namegtltagtltbr gt

lt

gt

ltpgt

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 fmtmessage 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

lt page import=javaxportlet javautil session=false gt

lt taglib uri=httpjavasuncomportlet prefix=portletAPI gt

lt taglib prefix=fmt uri=httpjavasuncomjstlfmt gt

ltjspuseBean id=addUrl scope=request class=javalangString gt

ltjspuseBean id=cancelUrl scope=request class=javalangString gt

- 47 -

ltportletAPIdefineObjectsgt

lt

ResourceBundle myText = ResourceBundlegetBundle(nlsText requestgetLocale())

gt

ltfmtsetBundle basename=nlsTextgt

lth4gtltfmtmessage key=available_bookmarksgtlth4gt

lttable class=wpsTablegt

lttr class=wpsTableRowgt

ltth class=wpsTableHeadgtltfmtmessage key=namegtltthgt

ltth class=wpsTableHeadgtltfmtmessage key=urlgtltthgt

lttdgtlttdgt

lttrgt

lt

PortletPreferences prefs = renderRequestgetPreferences()

Enumeration e = prefsgetNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltfmtmessage key=no_bookmarksgtltpgt

lt

else

while (ehasMoreElements())

String name = (String)enextElement()

String value = prefsgetValue(namelt+myTextgetString(undefined)+gt)

gt

lttr class=wpsTableRowgt

lttdgt lt=namegt lttdgt

lttdgt lt=valuegt lttdgt

- 48 -

lttdgt ltportletAPIactionURL var=removeUrlgt

ltportletAPIparam name=remove value=lt=namegtgt

ltportletAPIactionURLgt

lta href=lt=removeUrltoString()gtgt(ltfmtmessage key=deletegt)ltagt

lttdgt

lttrgt

lt

gt

ltform action=lt=addUrlgt method=POSTgt

lttr class=wpsTableRowgt

lttdgtltinput name=name type=text class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=value type=text class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=add type=submit value=ltfmtmessage key=addgt

class=portlet-form-buttongtlttdgt

lttrgt

ltformgt

lttablegt

ltform action=lt=cancelUrlgt method=postgt

ltinput name=cancel type=submit value=ltfmtmessage key=cancelgt class=portlet-

form-buttongt

ltformgt

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 14 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 -

- 51 -

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 (eg eventing) the IBM Portlet API still needs to be used Trademarks bull IBM and WebSphere are trademarks or registered trademarks of IBM Corporation in

the United States other countries or both bull 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 bull Other company product and service names may be trademarks or service marks of

others IBM copyright and trademark information httpwwwibmcomlegalcopytradephtml

  • Introduction
  • JSR 168 and the Java Community Process
  • Comparing concepts
    • Basic concepts
      • Portal
      • Portal page
      • Portlet
      • Portlet Container
        • Concepts that are the same
          • Portlet mode
          • Window state
          • Portlet life cycle and request processing
          • URL encoding
          • Include servletsJSPs
          • Portlet application packaging
          • Expiration-based caching
            • Concepts that differ
              • Portlet application entity
              • Portlet entity
              • Action and Render Request Response objects
              • Window concept
              • Portlet API does not extend servlet API
              • TAG libraries
                • Concepts new in the JSR 168
                  • Render parameter
                  • Extension mechanisms
                    • Custom window states
                    • Custom portlet modes
                    • Custom user info
                    • Request Response properties
                      • Web application session scope
                      • Reuse of the HttpSession listeners
                      • J2EE role support
                      • Resource bundles
                      • Multiple response content types
                      • Redirect in action
                      • Preference validator
                      • Portal context
                      • Localization support
                        • Concepts missing in the JSR 168
                          • Eventing
                          • Additional lifecycle events
                          • Property broker
                          • Portlet Menus
                          • Portlet Services
                          • Invalidation-based caching
                            • Alignment with WSRP
                              • Outlook for the next version of the JSR 168
                              • Guidelines for programming IBM Portlet API portlets
                                • Similar Functionality
                                  • Basic programming model
                                  • Portlet private session
                                  • User profile information
                                  • Persistent data
                                  • Portlet modes and window states
                                  • Expiration-based caching
                                    • Slightly different functionality
                                      • Sharing of data between portlets
                                      • Session listeners
                                        • New JSR 168 functionality
                                          • Navigational state (render parameters)
                                            • Pitfalls
                                              • Request response objects for action and render phase
                                              • Include search path
                                              • Form parameter encoding
                                              • Title setting
                                                  • Examples
                                                    • IBM Portlet API Portlet Code
                                                    • JSR 168 Portlet Code
                                                    • IBM Portlet API JSPs
                                                    • JSR 168 JSPs
                                                      • Summary
Page 5: Difference Bw Jsr168 and Ibm

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 Javatrade 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 httpjcporg 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 httpjcporgenjsrdetailid=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

31 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

311 Portal

A portal is a web based application that ndashcommonly ndash 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

PortalWeb

ApplicationHTTP

HTML

WML

Voi

ceXM

L

Portl

et In

voke

r API Portlet

(App)Po

rtlet

API

Portlet(App)

Portlet(App)

PortletServletContainer

Portl

et P

rovid

er S

PI

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

312 Portal page

Figure 2

Figure 2 Basic portal page components

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 (eg maximize or minimize the portlet) and buttons to change the mode of a portlet (eg show help or edit the predefined portlet settings)

ltTitlegt Edit

Portlet content

Portal page

Portletwindows

Window states Portlet modes

Markup Fragments

ltTitlegt Edit

ltTitlegt Edit

Portlet content

Portlet content

- 7 -

313 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 (eg 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 requestresponse 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 users interactions

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

314 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

32 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

321 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

bull Edit ndash to display one or more personalization views that let the user personalize portlet settings

bull Help ndash to display help views bull View ndash to display the portlet output bull Configure ndash 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

bull required to support (same semantic as above) o Edit o Help o View

bull optional custom modes o About ndash to display information on the portlets purpose origin version etc o Config ndash has the same semantic as the IBM Portlet API configure mode o Edit_defaults ndash to set the default values for the modifiable preferences that

are typically changed in the EDIT screen o Preview ndash to render output without the need of having back-end

connections or user specific data available o Print ndash to display a view that is suitable for printing

bull portal vendor specific modes that are available only in a portal of a specific vendor

322 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

bull Closed (deprecated) ndash to indicate that a window should be closed bull Detached (deprecated) ndash to indicate that a window should be detached bull Maximized ndash to indicate that a window has more real estate to render its output

then in normal window state

- 9 -

bull Minimized ndash to indicate that the portlet is minimized and cannot render any output

bull Moving (deprecated) ndash to indicate that the portlet window has been moved bull Normal ndash to indicate that the portlet is sharing its screen with other portlets on a

page bull Resizing (deprecated) ndash to indicate that the portlet has been resized bull Solo ndash to indicate that the portlet is the only portlet on the page

Whereas the JSR 168 has only the following mandatory window states

bull Maximized ndash same as in the IBM Portlet API bull Minimized ndash to indicate that the portlet should only render minimal or no output bull Normal ndash same as in the IBM Portlet API

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

323 Portlet life cycle and request processing

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

bull init ndash to initialize the portlet and put the portlet into service bull handle requests ndash process different kinds of action and render requests bull destroy ndash 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

324 URL encoding

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

bull 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

bull 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

325 Include servletsJSPs

In both APIrsquos 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()

contextinclude(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)

rdinclude(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 HttpServetRequestgetSession() 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

326 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 (webxml) and one to specify the portlet resources (portletxml) All web resources that are not portlets must be specified in the webxml deployment descriptor All portlets and portlet related settings must be specified in an additional file called portletxml

- 12 -

Different from JSR 168 in the IBM Portlet API all portlets must also be listed in the webxml as they are also servlets (see also 335 for examples of the deployment descitptors)

327 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

33 Concepts that differ

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

331 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 webxml and concrete portlet applications of concrete portlets based on the abstract ones The following portletxml example shows these two different parts

IBM PORTLET API PORTLETXML EXAMPLE

ltxml version=10 encoding=UTF-8gt

ltDOCTYPE portlet-app-def PUBLIC -IBMDTD Portlet Application 11EN

portlet_11dtdgt

ltportlet-app-defgt

ltportlet-app uid=commycobookmark1234 major-version=7 minor-version=24gt

ltportlet-app-namegtBookmark Application7ltportlet-app-namegt

ltportlet id=Portlet_1 href=WEB-INFwebxmlServlet_1gt

- 13 -

ltportlet-namegtBookmark Portlet7ltportlet-namegt

ltallowsgt

ltmaximizedgt

ltminimizedgt

ltallowsgt

ltsupportsgt

ltmarkup name=htmlgt

ltview output=fragmentgt

ltedit output=fragmentgt

ltmarkupgt

ltsupportsgt

ltportletgt

ltportlet-appgt

ltconcrete-portlet-app uid=commycobookmark12341gt

ltportlet-app-namegtConcreteSamplets_Bookmark7ltportlet-app-namegt

ltconcrete-portlet href=Portlet_1gt

ltportlet-namegtBookmark Portlet7ltportlet-namegt

ltdefault-localegtenltdefault-localegt

ltlanguage locale=engt

lttitlegtMy Bookmarks7lttitlegt

lttitle-shortgtBookmarks7lttitle-shortgt

ltdescriptiongtPortlet showing your personalized bookmarksltdescriptiongt

ltkeywordsgtbookmarksltkeywordsgt

ltlanguagegt

ltconfig-paramgt

ltparam-namegturl1ltparam-namegt

ltparam-valuegthttpwwwgooglecomltparam-valuegt

ltconfig-paramgt

ltconcrete-portletgt

- 14 -

ltconcrete-portlet-appgt

ltportlet-app-defgt

As portlets are servlets in the IBM Portlet API the portletxml has references for each portlet to the servlet in the webxml that represents the portlet The webxml for this example is

IBM PORTLET API WEBXML EXAMPLE

ltxml version=10 encoding=UTF-8gt

ltDOCTYPE web-app

PUBLIC -Sun Microsystems IncDTD Web Application 22EN

httpjavasuncomj2eedtdsweb-app_22dtdgt

ltweb-app id=WebApp_1gt

ltdisplay-namegtbookmark7ltdisplay-namegt

ltservlet id=Servlet_1gt

ltservlet-namegtBookmark7ltservlet-namegt

ltservlet-classgtcommycobookmarkBookmarkPortletltservlet-classgt

ltinit-paramgt

ltparam-namegtjspviewltparam-namegt

ltparam-valuegtbookmarkViewjspltparam-valuegt

ltinit-paramgt

ltinit-paramgt

ltparam-namegtjspeditltparam-namegt

ltparam-valuegtbookmarkEditjspltparam-valuegt

ltinit-paramgt

ltservletgt

ltservlet-mappinggt

ltservlet-namegtBookmark7ltservlet-namegt

lturl-patterngtBookmark7lturl-patterngt

ltservlet-mappinggt

ltweb-appgt

- 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 webxml and not in the portletxml In the JSR 168 the deployment descriptor is more like the webxml 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 portletxml example would look like when using the JSR 168 deployment descriptor format

JSR 168 PORTLETXML EXAMPLE

ltxml version=10 encoding=UTF-8gt

ltxml version=10encoding=UTF-8gt

ltportlet-app xmlns=httpjavasuncomxmlnsportletportlet-app_1_0xsd version=10

xmlnsxsi=httpwwww3org2001XMLSchema-instance

xsischemaLocation=httpjavasuncomxmlnsportlet-app_1_0xsd

httpjavasuncomxmlnsportletportlet-app_1_0xsdgt

ltportletgt

ltdescription xmllang=ENgtPortlet showing your personalized

bookmarksltdescriptiongt

ltportlet-namegtBookmark Portlet7ltportlet-namegt

ltdisplay-name xmllang=ENgtBookmark Portletltdisplay-namegt

ltportlet-classgtcommycobookmarkBookmarkPortletltportlet-classgt

ltinit-paramgt

ltnamegtjspviewltnamegt

ltvaluegtbookmarkViewjspltvaluegt

ltinit-paramgt

ltinit-paramgt

ltnamegtjspeditltnamegt

ltvaluegtbookmarkEditjspltvaluegt

ltinit-paramgt

ltsupportsgt

ltmime-typegttexthtmlltmime-typegt

ltportlet-modegtviewltportlet-modegt

- 16 -

ltportlet-modegteditltportlet-modegt

ltsupportsgt

ltsupported-localegtENltsupported-localegt

ltportlet-infogt

lttitlegtMy Bookmarks7lttitlegt

ltshort-titlegtBookmarks7ltshort-titlegt

ltkeywordsgtbookmarksltkeywordsgt

ltportlet-infogt

ltportlet-preferencesgt

ltpreferencegt

ltnamegturl1ltnamegt

ltvaluegthttpwwwgooglecomltvaluegt

ltpreferencegt

ltportlet-preferencesgt

ltportletgt

ltportlet-appgt

Here the initialization parameters are directly specified in the portletxml as portlets are independent components in the JSR 168 The following example represents the webxml for the JSR 168 bookmark portlet

JSR 168 WEBXML EXAMPLE

ltxml version=10 encoding=UTF-8gt

ltDOCTYPE web-app PUBLIC -Sun Microsystems IncDTD Web Application 23EN

httpjavasuncomdtdweb-app_2_3dtdgt

ltweb-appgt

ltdisplay-namegtBookmark Application7ltdisplay-namegt

ltweb-appgt

The only item that needs to be specified in the JSR 168 webxml 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 portletxml as portlet application name as there can be several concrete instances of the same abstract application

- 17 -

332 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 331) 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 331) 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

333 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

334 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 instanceentity 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 -

335 Portlet API does not extend servlet API

In the IBM Portlet API portlets extend servlets and all the major interfaces (Request Response Session hellip) 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

336 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

bull defineObjects tag ndash to define the basic portlet API objects RenderRequest RenderResponse and PortletConfig

bull actionURL tag ndash to create an action URL bull renderURL tag ndash to create a render URL bull namespace tag ndash 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 donrsquot need decoding

34 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 -

341 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 (eg 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

342 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

3421 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

3422 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 322) 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

3423 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

3424 Request Response properties

Properties can be used by the portalportlet container to send vendor specific information to the portlet andor the portlet can send vendor specific information to the portalportlet-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

343 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 (eg between portlets or between a portlet and a servlet)

344 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 23 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

345 J2EE role support

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

346 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 -

347 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 PortletRequestgetResponseContentTypes 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 (eg ldquotextrdquo or ldquordquo) 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

348 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 (eg an accounting servlet) in response to an action

349 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

3410 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 vendorrsquos 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)

3411 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 xmllang attribute like the

- 22 -

servlet 24 deployment descriptor Thus the same tag with descriptions in different languages can be used (eg 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

35 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)

351 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

bull ActionEventThe action event maps to the action phase call in the JSR 168

bull MessageEventMessage 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)

bull PortletApplicationSettingsAttributeEventPortletSettingsAttributeEventThese are events that get fired when attributes for the application or of the portlet settings change

bull WindowEventThe portlet will register for window events to get notified if the portlet window is changed via the window decorations

352 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 -

bull PortletPageListener The page listeners provides the portlet with events for the beginning of the page before any markup is written for this page (eg to write JavaScript at the beginning of the page) and the end of the page after all markup is written

bull 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 23 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

bull EventPhaseListener The event phase listener notifies the portlet of the beginning and end of the eventaction phase

353 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

354 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 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

Figure 4

- 24 -

Figure 4 Portlet menu example

355 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

356 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 -

36 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 indicates portlet in what mode to operate for a given request

View edit help + custom modes

view edit help + custom modes

full alignment

Window State the state of the window in which the portlet output will be displayed

minimized normal maximized solo +

custom window states

minimized normal maximized +

custom window states

full alignment (ldquosolordquo is missing in the JSR but can be implemented as a custom state)

URL encoding to allow re-writing URLs created by the portlet

defines how to create URLs to allow re-writing of the URLs either on consumer or producer side

encapsulates URL creation via a Java object

full alignment (the implementation of the Java object can implement the WSRP URL rewriting rules)

Namespace encoding to avoid that several portlets on a page conflicting with each other

defines namespace prefixes for consumer and producer side namespacing

provides a Java method to namespace a String

full alignment (the JSR namespace method can implement the WSRP namespace behavior)

User ndash portlet interaction operations

performBlockingInteraction blocking action processing

getMarkup render the markup

action blocking action processing

render render the makup

full alignment (action invocations carried through performBlockingInteraction render carried through getMarkup)

View state that allows the current portlet fragment to be correctly displayed in sub-sequent render calls

navigational state render parameter full alignment (WSRP navigational state maps to JSR render parameters)

Storing transient state across request

session state concept implemented via a sessionID

utilizes the Http web application session

full alignment (the WSRP sessionID can be used to reference the JSR session)

Storing persistent state to personalize the rendering of the portlet

allows to have properties of arbitrary types

provides String-based preferences

full alignment (JSR String preferences can be mapped to WSRP properties)

Information about the portal calling the portlet

RegistrationData provide information of the consumer to the producer

PortalContext provide a Java interface to access information about the portal calling the portlet

full alignment (all data represented through the PortalContext to the JSR portlet are available in the RegistrationData)

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

Aggregated HTML WML VoiceXML

over HTTPMark-Up Fragments

Transferred via WSRP

Portal

WSRP Service

WSRP Service

WSRP Service

WSRP Consumer WSRP Producer

Use of WSRP Services in Portals

Portal sharing Portlets as WSRP Services

ServerPortalPortals

Huge numberof users Publishing Portal

WSRPWrapperPortalsPortalsPortal

Portlet

Portlet

Portlet

WSRP Consumer WSRP Producer

ProxyPortlet

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

bull 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

bull 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

bull 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

bull 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 CCPP standard allowing a portlet to query the client capabilities and adopting its markup accordingly (eg screen size browser) This API is likely to be included in the next version of the portlet API Also J2EE 14 was finalized during this time period J2EE 14 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 14

bull caching The first version of the JSR 168 API is limited to expiration-based caching (see section 327) 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

bull 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

51 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

511 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

bull portlets are components Portlets are components that implement a specific function Different functions should be distributed to different portlets

bull 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

bull 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

512 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 HttpServletRequestgetSession() call in the JSPs called via the IBM Portlet API needs to be replaced when moving to JSR 168 portlets by the RenderRequestgetPortletSession() 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 HttpServletRequestgetSession() will get the HttpSession and therefore need to access the portlet session via the RenderRequest

513 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

514 Persistent data

Portlets can store customization and personalization data persistently Customization data are related to the portlet and are valid for all users (eg 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 (eg 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

515 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

516 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

52 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

521 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 351 353) 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

522 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

53 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 -

531 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

bull no support of the back button in the browser bull current state of the portlet is not bookmarkable bull 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 bull 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

54 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

541 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 -

542 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

543 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

544 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 wersquoll 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

Figure 7After clicking on the Edit mode button the portlet renders the Edit view shown in

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

Figure 8

After we press the ldquoAddrdquo 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

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

bull use JSPs for rendering the output bull customize the portlet output taking user specific data into account bull 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

61 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 comibmwpssampleswp5

import javaio

import javautil

import orgapachejetspeedportlet

import orgapachejetspeedportletevent

public class IbmBookmark extends PortletAdapter implements ActionListener

public void init(PortletConfig portletConfig) throws UnavailableException

superinit(portletConfig)

- 36 -

public void doView(PortletRequest request PortletResponse response)

throws PortletException IOException

String jspName = thisgetPortletConfig()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 = responsecreateReturnURI()

addURIaddAction(add)

requestsetAttribute(addURI addURItoString())

PortletURI cancelURI = responsecreateReturnURI()

requestsetAttribute(cancelURI cancelURItoString())

String jspName = thisgetPortletConfig()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 ldquocancelrdquo and ldquoaddrdquo URLs are created inside the portlet and attached to the request before including the Edit JSP Both URLs are from type ldquoReturnURIrdquo 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 = eventgetRequest()

String action = eventgetActionString()

PortletLog log = getPortletLog()

if ( action=null )

try

if (actionequals(removeURI))

String removeName = requestgetParameter(remove)

PortletData portData = requestgetData()

portDataremoveAttribute(removeName)

portDatastore()

if (actionequals(add))

PortletData portData = requestgetData()

String name = requestgetParameter(name)

String value = requestgetParameter(value)

portDatasetAttribute(name value)

portDatastore()

catch ( AccessDeniedException ade )

logerror(AccessDeniedException occured when adding or deleting a bookmark)

catch ( IOException ioe )

logerror(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 ldquoaddrdquo or ldquodeleterdquo 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 ldquoaddrdquo or ldquoremoveURIrdquo If the user has clicked on the ldquoremoverdquo button the corresponding link is removed from the portlet data whereas if ldquoaddrdquo was clicked the data entered by the user is added to the portlet data

62 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 comibmwpssamplesjsr

import javaio

import javaxportlet

public class Bookmark extends GenericPortlet

public void init(PortletConfig config) throws PortletException

superinit(config)

public void doView(RenderRequest request RenderResponse response)

throws PortletException IOException

responsesetContentType(texthtml)

String jspName = getPortletConfig()getInitParameter(jspView)

PortletRequestDispatcher rd = getPortletContext()getRequestDispatcher(jspName)

rdinclude(requestresponse)

- 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

responsesetContentType(texthtml)

PortletURL addUrl = responsecreateActionURL()

addUrlsetPortletMode(PortletModeVIEW)

addUrlsetParameter(addadd)

requestsetAttribute(addUrladdUrltoString())

PortletURL cancelUrl = responsecreateRenderURL()

cancelUrlsetPortletMode(PortletModeVIEW)

requestsetAttribute(cancelUrlcancelUrltoString())

String jspName = getPortletConfig()getInitParameter(jspEdit)

PortletRequestDispatcher rd = getPortletContext()getRequestDispatcher(jspName)

rdinclude(requestresponse)

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 ldquoaddrdquo button URL an action URL is created as we need to store the user input of the add form persistently For the ldquocancelrdquo 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 = requestgetParameter(remove)

if (removeName = null)

PortletPreferences prefs = requestgetPreferences()

prefsreset(removeName)

prefsstore()

String add = requestgetParameter(add)

if (add = null)

PortletPreferences prefs = requestgetPreferences()

String name = requestgetParameter(name)

String value = requestgetParameter(value)

prefssetValue(name value)

prefsstore()

catch ( IOException ioe )

getPortletContextlog(An IO error occured when trying to remove a bookmark)

catch ( PortletException pe )

getPortletContextlog(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

bull 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

bull 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

bull Persistent portlet data The JSR 168 persistent data PortletPreferences have an API similar to the JDK 14 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

bull 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

63 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

lt page contentType=texthtml import=javautil comibmwpssampleswp5

orgapachejetspeedportlet session=falsegt

lt taglib uri=WEB-INFtldportlettld prefix=portletAPI gt

- 42 -

ltportletAPIinitgt

ltp class=wpsPortletHeadgtltportletAPItext key=available_bookmarks

bundle=nlsTextgtAvailable BookmarksltportletAPItextgtltpgt

lt

PortletData prefs = portletRequestgetData()

Enumeration e = prefsgetAttributeNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltportletAPItext key=no_bookmarks bundle=nlsTextgtNo

bookmarksltportletAPItextgtltpgt

lt

else

gt

ltp class=wpsIndentMediumgt

lt

while (ehasMoreElements())

String name = (String)enextElement()

String value = (String)prefsgetAttribute(name)

gt

lta href=lt=valuegt target=_blankgtlt=namegtltagtltbr gt

lt

gt

ltpgt

The View JSP first call portletAPIinit 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

lt page contentType=texthtml import=javautil

comibmwpssampleswp5orgapachejetspeedportlet session=falsegt

lt taglib uri=WEB-INFtldportlettld prefix=portletAPI gt

ltjspuseBean id=addURI class=javalangString scope=request gt

ltjspuseBean id=cancelURI class=javalangString scope=request gt

ltportletAPIinitgt

lth4gtltportletAPItext key=available_bookmarks bundle=nlsTextgtAvailable

BookmarksltportletAPItextgtlth4gt

lttable class=wpsTablegt

lttr class=wpsTableRowgt

ltth class=portlet-table-headergtltportletAPItext key=name bundle=nlsTextgtltthgt

ltth class=portlet-table-headergtltportletAPItext key=url bundle=nlsTextgtltthgt

lttdgtlttdgt

lttrgt

lt

PortletData prefs = portletRequestgetData()

Enumeration e = prefsgetAttributeNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltportletAPItext key=no_bookmarks bundle=nlsTextgtNo

bookmarksltportletAPItextgtltpgt

lt

else

while (ehasMoreElements())

- 44 -

String name = (String)enextElement()

String value = (String)prefsgetAttribute(name)

gt

lttr class=wpsTableRowgt

lttdgt lt=namegt lttdgt

lttdgt lt=valuegt lttdgt

lttdgt lta href=ltportletAPIcreateURIgtltportletAPIURIAction

name=removeURIgtltportletAPIURIParameter name=remove

value=lt=namegtgtltportletAPIcreateURIgtgt

(ltportletAPItext key=delete bundle=nlsTextgt)ltagt

lttdgt

lttrgt

lt

gt

ltform action=lt=addURIgt method=POSTgt

lttr class=wpsTableRowgt

lttdgtltinput name=ltportletAPIencodeNamespace value=namegt type=text

class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=ltportletAPIencodeNamespace value=valuegt type=text

class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=ltportletAPIencodeNamespace value=addgt type=submit

value=ltportletAPItext key=add bundle=nlsTextgt class=portlet-form-buttongtlttdgt

lttrgt

ltformgt

lttablegt

- 45 -

ltform action=lt=cancelURIgt method=postgt

ltinput name=ltportletAPIencodeNamespace value=cancelgt type=submit

value=ltportletAPItext key=cancel bundle=nlsTextgt class=portlet-form-buttongt

ltformgt

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 ldquodeleterdquo button for which an URL with the action ldquoremoveURIrdquo 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 ldquocancelrdquo button from the request

64 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

lt page import=javaxportlet javautil session=falsegt

lt taglib uri=httpjavasuncomportlet prefix=portletAPI gt

lt taglib prefix=fmt uri=httpjavasuncomjstlfmt gt

ltportletAPIdefineObjects gt

ltfmtsetBundle basename=nlsTextgt

lt

ResourceBundle myText = ResourceBundlegetBundle(nlsText requestgetLocale())

gt

lth4gtltfmtmessage key=available_bookmarksgtlth4gt

lt

PortletPreferences prefs = renderRequestgetPreferences()

Enumeration e = prefsgetNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltfmtmessage key=no_bookmarksgtltpgt

- 46 -

lt

else

gt

ltpgt

lt

while (ehasMoreElements())

String name = (String)enextElement()

String value = prefsgetValue(namelt+myTextgetString(undefined)+gt)

gt

lta href=lt=valuegt target=_blankgtlt=namegtltagtltbr gt

lt

gt

ltpgt

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 fmtmessage 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

lt page import=javaxportlet javautil session=false gt

lt taglib uri=httpjavasuncomportlet prefix=portletAPI gt

lt taglib prefix=fmt uri=httpjavasuncomjstlfmt gt

ltjspuseBean id=addUrl scope=request class=javalangString gt

ltjspuseBean id=cancelUrl scope=request class=javalangString gt

- 47 -

ltportletAPIdefineObjectsgt

lt

ResourceBundle myText = ResourceBundlegetBundle(nlsText requestgetLocale())

gt

ltfmtsetBundle basename=nlsTextgt

lth4gtltfmtmessage key=available_bookmarksgtlth4gt

lttable class=wpsTablegt

lttr class=wpsTableRowgt

ltth class=wpsTableHeadgtltfmtmessage key=namegtltthgt

ltth class=wpsTableHeadgtltfmtmessage key=urlgtltthgt

lttdgtlttdgt

lttrgt

lt

PortletPreferences prefs = renderRequestgetPreferences()

Enumeration e = prefsgetNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltfmtmessage key=no_bookmarksgtltpgt

lt

else

while (ehasMoreElements())

String name = (String)enextElement()

String value = prefsgetValue(namelt+myTextgetString(undefined)+gt)

gt

lttr class=wpsTableRowgt

lttdgt lt=namegt lttdgt

lttdgt lt=valuegt lttdgt

- 48 -

lttdgt ltportletAPIactionURL var=removeUrlgt

ltportletAPIparam name=remove value=lt=namegtgt

ltportletAPIactionURLgt

lta href=lt=removeUrltoString()gtgt(ltfmtmessage key=deletegt)ltagt

lttdgt

lttrgt

lt

gt

ltform action=lt=addUrlgt method=POSTgt

lttr class=wpsTableRowgt

lttdgtltinput name=name type=text class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=value type=text class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=add type=submit value=ltfmtmessage key=addgt

class=portlet-form-buttongtlttdgt

lttrgt

ltformgt

lttablegt

ltform action=lt=cancelUrlgt method=postgt

ltinput name=cancel type=submit value=ltfmtmessage key=cancelgt class=portlet-

form-buttongt

ltformgt

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 14 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 -

- 51 -

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 (eg eventing) the IBM Portlet API still needs to be used Trademarks bull IBM and WebSphere are trademarks or registered trademarks of IBM Corporation in

the United States other countries or both bull 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 bull Other company product and service names may be trademarks or service marks of

others IBM copyright and trademark information httpwwwibmcomlegalcopytradephtml

  • Introduction
  • JSR 168 and the Java Community Process
  • Comparing concepts
    • Basic concepts
      • Portal
      • Portal page
      • Portlet
      • Portlet Container
        • Concepts that are the same
          • Portlet mode
          • Window state
          • Portlet life cycle and request processing
          • URL encoding
          • Include servletsJSPs
          • Portlet application packaging
          • Expiration-based caching
            • Concepts that differ
              • Portlet application entity
              • Portlet entity
              • Action and Render Request Response objects
              • Window concept
              • Portlet API does not extend servlet API
              • TAG libraries
                • Concepts new in the JSR 168
                  • Render parameter
                  • Extension mechanisms
                    • Custom window states
                    • Custom portlet modes
                    • Custom user info
                    • Request Response properties
                      • Web application session scope
                      • Reuse of the HttpSession listeners
                      • J2EE role support
                      • Resource bundles
                      • Multiple response content types
                      • Redirect in action
                      • Preference validator
                      • Portal context
                      • Localization support
                        • Concepts missing in the JSR 168
                          • Eventing
                          • Additional lifecycle events
                          • Property broker
                          • Portlet Menus
                          • Portlet Services
                          • Invalidation-based caching
                            • Alignment with WSRP
                              • Outlook for the next version of the JSR 168
                              • Guidelines for programming IBM Portlet API portlets
                                • Similar Functionality
                                  • Basic programming model
                                  • Portlet private session
                                  • User profile information
                                  • Persistent data
                                  • Portlet modes and window states
                                  • Expiration-based caching
                                    • Slightly different functionality
                                      • Sharing of data between portlets
                                      • Session listeners
                                        • New JSR 168 functionality
                                          • Navigational state (render parameters)
                                            • Pitfalls
                                              • Request response objects for action and render phase
                                              • Include search path
                                              • Form parameter encoding
                                              • Title setting
                                                  • Examples
                                                    • IBM Portlet API Portlet Code
                                                    • JSR 168 Portlet Code
                                                    • IBM Portlet API JSPs
                                                    • JSR 168 JSPs
                                                      • Summary
Page 6: Difference Bw Jsr168 and Ibm

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

31 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

311 Portal

A portal is a web based application that ndashcommonly ndash 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

PortalWeb

ApplicationHTTP

HTML

WML

Voi

ceXM

L

Portl

et In

voke

r API Portlet

(App)Po

rtlet

API

Portlet(App)

Portlet(App)

PortletServletContainer

Portl

et P

rovid

er S

PI

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

312 Portal page

Figure 2

Figure 2 Basic portal page components

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 (eg maximize or minimize the portlet) and buttons to change the mode of a portlet (eg show help or edit the predefined portlet settings)

ltTitlegt Edit

Portlet content

Portal page

Portletwindows

Window states Portlet modes

Markup Fragments

ltTitlegt Edit

ltTitlegt Edit

Portlet content

Portlet content

- 7 -

313 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 (eg 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 requestresponse 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 users interactions

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

314 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

32 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

321 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

bull Edit ndash to display one or more personalization views that let the user personalize portlet settings

bull Help ndash to display help views bull View ndash to display the portlet output bull Configure ndash 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

bull required to support (same semantic as above) o Edit o Help o View

bull optional custom modes o About ndash to display information on the portlets purpose origin version etc o Config ndash has the same semantic as the IBM Portlet API configure mode o Edit_defaults ndash to set the default values for the modifiable preferences that

are typically changed in the EDIT screen o Preview ndash to render output without the need of having back-end

connections or user specific data available o Print ndash to display a view that is suitable for printing

bull portal vendor specific modes that are available only in a portal of a specific vendor

322 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

bull Closed (deprecated) ndash to indicate that a window should be closed bull Detached (deprecated) ndash to indicate that a window should be detached bull Maximized ndash to indicate that a window has more real estate to render its output

then in normal window state

- 9 -

bull Minimized ndash to indicate that the portlet is minimized and cannot render any output

bull Moving (deprecated) ndash to indicate that the portlet window has been moved bull Normal ndash to indicate that the portlet is sharing its screen with other portlets on a

page bull Resizing (deprecated) ndash to indicate that the portlet has been resized bull Solo ndash to indicate that the portlet is the only portlet on the page

Whereas the JSR 168 has only the following mandatory window states

bull Maximized ndash same as in the IBM Portlet API bull Minimized ndash to indicate that the portlet should only render minimal or no output bull Normal ndash same as in the IBM Portlet API

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

323 Portlet life cycle and request processing

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

bull init ndash to initialize the portlet and put the portlet into service bull handle requests ndash process different kinds of action and render requests bull destroy ndash 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

324 URL encoding

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

bull 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

bull 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

325 Include servletsJSPs

In both APIrsquos 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()

contextinclude(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)

rdinclude(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 HttpServetRequestgetSession() 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

326 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 (webxml) and one to specify the portlet resources (portletxml) All web resources that are not portlets must be specified in the webxml deployment descriptor All portlets and portlet related settings must be specified in an additional file called portletxml

- 12 -

Different from JSR 168 in the IBM Portlet API all portlets must also be listed in the webxml as they are also servlets (see also 335 for examples of the deployment descitptors)

327 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

33 Concepts that differ

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

331 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 webxml and concrete portlet applications of concrete portlets based on the abstract ones The following portletxml example shows these two different parts

IBM PORTLET API PORTLETXML EXAMPLE

ltxml version=10 encoding=UTF-8gt

ltDOCTYPE portlet-app-def PUBLIC -IBMDTD Portlet Application 11EN

portlet_11dtdgt

ltportlet-app-defgt

ltportlet-app uid=commycobookmark1234 major-version=7 minor-version=24gt

ltportlet-app-namegtBookmark Application7ltportlet-app-namegt

ltportlet id=Portlet_1 href=WEB-INFwebxmlServlet_1gt

- 13 -

ltportlet-namegtBookmark Portlet7ltportlet-namegt

ltallowsgt

ltmaximizedgt

ltminimizedgt

ltallowsgt

ltsupportsgt

ltmarkup name=htmlgt

ltview output=fragmentgt

ltedit output=fragmentgt

ltmarkupgt

ltsupportsgt

ltportletgt

ltportlet-appgt

ltconcrete-portlet-app uid=commycobookmark12341gt

ltportlet-app-namegtConcreteSamplets_Bookmark7ltportlet-app-namegt

ltconcrete-portlet href=Portlet_1gt

ltportlet-namegtBookmark Portlet7ltportlet-namegt

ltdefault-localegtenltdefault-localegt

ltlanguage locale=engt

lttitlegtMy Bookmarks7lttitlegt

lttitle-shortgtBookmarks7lttitle-shortgt

ltdescriptiongtPortlet showing your personalized bookmarksltdescriptiongt

ltkeywordsgtbookmarksltkeywordsgt

ltlanguagegt

ltconfig-paramgt

ltparam-namegturl1ltparam-namegt

ltparam-valuegthttpwwwgooglecomltparam-valuegt

ltconfig-paramgt

ltconcrete-portletgt

- 14 -

ltconcrete-portlet-appgt

ltportlet-app-defgt

As portlets are servlets in the IBM Portlet API the portletxml has references for each portlet to the servlet in the webxml that represents the portlet The webxml for this example is

IBM PORTLET API WEBXML EXAMPLE

ltxml version=10 encoding=UTF-8gt

ltDOCTYPE web-app

PUBLIC -Sun Microsystems IncDTD Web Application 22EN

httpjavasuncomj2eedtdsweb-app_22dtdgt

ltweb-app id=WebApp_1gt

ltdisplay-namegtbookmark7ltdisplay-namegt

ltservlet id=Servlet_1gt

ltservlet-namegtBookmark7ltservlet-namegt

ltservlet-classgtcommycobookmarkBookmarkPortletltservlet-classgt

ltinit-paramgt

ltparam-namegtjspviewltparam-namegt

ltparam-valuegtbookmarkViewjspltparam-valuegt

ltinit-paramgt

ltinit-paramgt

ltparam-namegtjspeditltparam-namegt

ltparam-valuegtbookmarkEditjspltparam-valuegt

ltinit-paramgt

ltservletgt

ltservlet-mappinggt

ltservlet-namegtBookmark7ltservlet-namegt

lturl-patterngtBookmark7lturl-patterngt

ltservlet-mappinggt

ltweb-appgt

- 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 webxml and not in the portletxml In the JSR 168 the deployment descriptor is more like the webxml 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 portletxml example would look like when using the JSR 168 deployment descriptor format

JSR 168 PORTLETXML EXAMPLE

ltxml version=10 encoding=UTF-8gt

ltxml version=10encoding=UTF-8gt

ltportlet-app xmlns=httpjavasuncomxmlnsportletportlet-app_1_0xsd version=10

xmlnsxsi=httpwwww3org2001XMLSchema-instance

xsischemaLocation=httpjavasuncomxmlnsportlet-app_1_0xsd

httpjavasuncomxmlnsportletportlet-app_1_0xsdgt

ltportletgt

ltdescription xmllang=ENgtPortlet showing your personalized

bookmarksltdescriptiongt

ltportlet-namegtBookmark Portlet7ltportlet-namegt

ltdisplay-name xmllang=ENgtBookmark Portletltdisplay-namegt

ltportlet-classgtcommycobookmarkBookmarkPortletltportlet-classgt

ltinit-paramgt

ltnamegtjspviewltnamegt

ltvaluegtbookmarkViewjspltvaluegt

ltinit-paramgt

ltinit-paramgt

ltnamegtjspeditltnamegt

ltvaluegtbookmarkEditjspltvaluegt

ltinit-paramgt

ltsupportsgt

ltmime-typegttexthtmlltmime-typegt

ltportlet-modegtviewltportlet-modegt

- 16 -

ltportlet-modegteditltportlet-modegt

ltsupportsgt

ltsupported-localegtENltsupported-localegt

ltportlet-infogt

lttitlegtMy Bookmarks7lttitlegt

ltshort-titlegtBookmarks7ltshort-titlegt

ltkeywordsgtbookmarksltkeywordsgt

ltportlet-infogt

ltportlet-preferencesgt

ltpreferencegt

ltnamegturl1ltnamegt

ltvaluegthttpwwwgooglecomltvaluegt

ltpreferencegt

ltportlet-preferencesgt

ltportletgt

ltportlet-appgt

Here the initialization parameters are directly specified in the portletxml as portlets are independent components in the JSR 168 The following example represents the webxml for the JSR 168 bookmark portlet

JSR 168 WEBXML EXAMPLE

ltxml version=10 encoding=UTF-8gt

ltDOCTYPE web-app PUBLIC -Sun Microsystems IncDTD Web Application 23EN

httpjavasuncomdtdweb-app_2_3dtdgt

ltweb-appgt

ltdisplay-namegtBookmark Application7ltdisplay-namegt

ltweb-appgt

The only item that needs to be specified in the JSR 168 webxml 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 portletxml as portlet application name as there can be several concrete instances of the same abstract application

- 17 -

332 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 331) 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 331) 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

333 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

334 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 instanceentity 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 -

335 Portlet API does not extend servlet API

In the IBM Portlet API portlets extend servlets and all the major interfaces (Request Response Session hellip) 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

336 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

bull defineObjects tag ndash to define the basic portlet API objects RenderRequest RenderResponse and PortletConfig

bull actionURL tag ndash to create an action URL bull renderURL tag ndash to create a render URL bull namespace tag ndash 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 donrsquot need decoding

34 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 -

341 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 (eg 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

342 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

3421 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

3422 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 322) 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

3423 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

3424 Request Response properties

Properties can be used by the portalportlet container to send vendor specific information to the portlet andor the portlet can send vendor specific information to the portalportlet-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

343 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 (eg between portlets or between a portlet and a servlet)

344 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 23 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

345 J2EE role support

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

346 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 -

347 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 PortletRequestgetResponseContentTypes 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 (eg ldquotextrdquo or ldquordquo) 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

348 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 (eg an accounting servlet) in response to an action

349 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

3410 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 vendorrsquos 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)

3411 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 xmllang attribute like the

- 22 -

servlet 24 deployment descriptor Thus the same tag with descriptions in different languages can be used (eg 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

35 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)

351 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

bull ActionEventThe action event maps to the action phase call in the JSR 168

bull MessageEventMessage 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)

bull PortletApplicationSettingsAttributeEventPortletSettingsAttributeEventThese are events that get fired when attributes for the application or of the portlet settings change

bull WindowEventThe portlet will register for window events to get notified if the portlet window is changed via the window decorations

352 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 -

bull PortletPageListener The page listeners provides the portlet with events for the beginning of the page before any markup is written for this page (eg to write JavaScript at the beginning of the page) and the end of the page after all markup is written

bull 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 23 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

bull EventPhaseListener The event phase listener notifies the portlet of the beginning and end of the eventaction phase

353 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

354 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 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

Figure 4

- 24 -

Figure 4 Portlet menu example

355 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

356 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 -

36 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 indicates portlet in what mode to operate for a given request

View edit help + custom modes

view edit help + custom modes

full alignment

Window State the state of the window in which the portlet output will be displayed

minimized normal maximized solo +

custom window states

minimized normal maximized +

custom window states

full alignment (ldquosolordquo is missing in the JSR but can be implemented as a custom state)

URL encoding to allow re-writing URLs created by the portlet

defines how to create URLs to allow re-writing of the URLs either on consumer or producer side

encapsulates URL creation via a Java object

full alignment (the implementation of the Java object can implement the WSRP URL rewriting rules)

Namespace encoding to avoid that several portlets on a page conflicting with each other

defines namespace prefixes for consumer and producer side namespacing

provides a Java method to namespace a String

full alignment (the JSR namespace method can implement the WSRP namespace behavior)

User ndash portlet interaction operations

performBlockingInteraction blocking action processing

getMarkup render the markup

action blocking action processing

render render the makup

full alignment (action invocations carried through performBlockingInteraction render carried through getMarkup)

View state that allows the current portlet fragment to be correctly displayed in sub-sequent render calls

navigational state render parameter full alignment (WSRP navigational state maps to JSR render parameters)

Storing transient state across request

session state concept implemented via a sessionID

utilizes the Http web application session

full alignment (the WSRP sessionID can be used to reference the JSR session)

Storing persistent state to personalize the rendering of the portlet

allows to have properties of arbitrary types

provides String-based preferences

full alignment (JSR String preferences can be mapped to WSRP properties)

Information about the portal calling the portlet

RegistrationData provide information of the consumer to the producer

PortalContext provide a Java interface to access information about the portal calling the portlet

full alignment (all data represented through the PortalContext to the JSR portlet are available in the RegistrationData)

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

Aggregated HTML WML VoiceXML

over HTTPMark-Up Fragments

Transferred via WSRP

Portal

WSRP Service

WSRP Service

WSRP Service

WSRP Consumer WSRP Producer

Use of WSRP Services in Portals

Portal sharing Portlets as WSRP Services

ServerPortalPortals

Huge numberof users Publishing Portal

WSRPWrapperPortalsPortalsPortal

Portlet

Portlet

Portlet

WSRP Consumer WSRP Producer

ProxyPortlet

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

bull 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

bull 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

bull 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

bull 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 CCPP standard allowing a portlet to query the client capabilities and adopting its markup accordingly (eg screen size browser) This API is likely to be included in the next version of the portlet API Also J2EE 14 was finalized during this time period J2EE 14 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 14

bull caching The first version of the JSR 168 API is limited to expiration-based caching (see section 327) 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

bull 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

51 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

511 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

bull portlets are components Portlets are components that implement a specific function Different functions should be distributed to different portlets

bull 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

bull 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

512 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 HttpServletRequestgetSession() call in the JSPs called via the IBM Portlet API needs to be replaced when moving to JSR 168 portlets by the RenderRequestgetPortletSession() 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 HttpServletRequestgetSession() will get the HttpSession and therefore need to access the portlet session via the RenderRequest

513 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

514 Persistent data

Portlets can store customization and personalization data persistently Customization data are related to the portlet and are valid for all users (eg 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 (eg 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

515 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

516 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

52 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

521 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 351 353) 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

522 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

53 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 -

531 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

bull no support of the back button in the browser bull current state of the portlet is not bookmarkable bull 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 bull 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

54 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

541 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 -

542 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

543 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

544 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 wersquoll 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

Figure 7After clicking on the Edit mode button the portlet renders the Edit view shown in

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

Figure 8

After we press the ldquoAddrdquo 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

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

bull use JSPs for rendering the output bull customize the portlet output taking user specific data into account bull 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

61 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 comibmwpssampleswp5

import javaio

import javautil

import orgapachejetspeedportlet

import orgapachejetspeedportletevent

public class IbmBookmark extends PortletAdapter implements ActionListener

public void init(PortletConfig portletConfig) throws UnavailableException

superinit(portletConfig)

- 36 -

public void doView(PortletRequest request PortletResponse response)

throws PortletException IOException

String jspName = thisgetPortletConfig()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 = responsecreateReturnURI()

addURIaddAction(add)

requestsetAttribute(addURI addURItoString())

PortletURI cancelURI = responsecreateReturnURI()

requestsetAttribute(cancelURI cancelURItoString())

String jspName = thisgetPortletConfig()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 ldquocancelrdquo and ldquoaddrdquo URLs are created inside the portlet and attached to the request before including the Edit JSP Both URLs are from type ldquoReturnURIrdquo 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 = eventgetRequest()

String action = eventgetActionString()

PortletLog log = getPortletLog()

if ( action=null )

try

if (actionequals(removeURI))

String removeName = requestgetParameter(remove)

PortletData portData = requestgetData()

portDataremoveAttribute(removeName)

portDatastore()

if (actionequals(add))

PortletData portData = requestgetData()

String name = requestgetParameter(name)

String value = requestgetParameter(value)

portDatasetAttribute(name value)

portDatastore()

catch ( AccessDeniedException ade )

logerror(AccessDeniedException occured when adding or deleting a bookmark)

catch ( IOException ioe )

logerror(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 ldquoaddrdquo or ldquodeleterdquo 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 ldquoaddrdquo or ldquoremoveURIrdquo If the user has clicked on the ldquoremoverdquo button the corresponding link is removed from the portlet data whereas if ldquoaddrdquo was clicked the data entered by the user is added to the portlet data

62 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 comibmwpssamplesjsr

import javaio

import javaxportlet

public class Bookmark extends GenericPortlet

public void init(PortletConfig config) throws PortletException

superinit(config)

public void doView(RenderRequest request RenderResponse response)

throws PortletException IOException

responsesetContentType(texthtml)

String jspName = getPortletConfig()getInitParameter(jspView)

PortletRequestDispatcher rd = getPortletContext()getRequestDispatcher(jspName)

rdinclude(requestresponse)

- 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

responsesetContentType(texthtml)

PortletURL addUrl = responsecreateActionURL()

addUrlsetPortletMode(PortletModeVIEW)

addUrlsetParameter(addadd)

requestsetAttribute(addUrladdUrltoString())

PortletURL cancelUrl = responsecreateRenderURL()

cancelUrlsetPortletMode(PortletModeVIEW)

requestsetAttribute(cancelUrlcancelUrltoString())

String jspName = getPortletConfig()getInitParameter(jspEdit)

PortletRequestDispatcher rd = getPortletContext()getRequestDispatcher(jspName)

rdinclude(requestresponse)

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 ldquoaddrdquo button URL an action URL is created as we need to store the user input of the add form persistently For the ldquocancelrdquo 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 = requestgetParameter(remove)

if (removeName = null)

PortletPreferences prefs = requestgetPreferences()

prefsreset(removeName)

prefsstore()

String add = requestgetParameter(add)

if (add = null)

PortletPreferences prefs = requestgetPreferences()

String name = requestgetParameter(name)

String value = requestgetParameter(value)

prefssetValue(name value)

prefsstore()

catch ( IOException ioe )

getPortletContextlog(An IO error occured when trying to remove a bookmark)

catch ( PortletException pe )

getPortletContextlog(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

bull 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

bull 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

bull Persistent portlet data The JSR 168 persistent data PortletPreferences have an API similar to the JDK 14 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

bull 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

63 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

lt page contentType=texthtml import=javautil comibmwpssampleswp5

orgapachejetspeedportlet session=falsegt

lt taglib uri=WEB-INFtldportlettld prefix=portletAPI gt

- 42 -

ltportletAPIinitgt

ltp class=wpsPortletHeadgtltportletAPItext key=available_bookmarks

bundle=nlsTextgtAvailable BookmarksltportletAPItextgtltpgt

lt

PortletData prefs = portletRequestgetData()

Enumeration e = prefsgetAttributeNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltportletAPItext key=no_bookmarks bundle=nlsTextgtNo

bookmarksltportletAPItextgtltpgt

lt

else

gt

ltp class=wpsIndentMediumgt

lt

while (ehasMoreElements())

String name = (String)enextElement()

String value = (String)prefsgetAttribute(name)

gt

lta href=lt=valuegt target=_blankgtlt=namegtltagtltbr gt

lt

gt

ltpgt

The View JSP first call portletAPIinit 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

lt page contentType=texthtml import=javautil

comibmwpssampleswp5orgapachejetspeedportlet session=falsegt

lt taglib uri=WEB-INFtldportlettld prefix=portletAPI gt

ltjspuseBean id=addURI class=javalangString scope=request gt

ltjspuseBean id=cancelURI class=javalangString scope=request gt

ltportletAPIinitgt

lth4gtltportletAPItext key=available_bookmarks bundle=nlsTextgtAvailable

BookmarksltportletAPItextgtlth4gt

lttable class=wpsTablegt

lttr class=wpsTableRowgt

ltth class=portlet-table-headergtltportletAPItext key=name bundle=nlsTextgtltthgt

ltth class=portlet-table-headergtltportletAPItext key=url bundle=nlsTextgtltthgt

lttdgtlttdgt

lttrgt

lt

PortletData prefs = portletRequestgetData()

Enumeration e = prefsgetAttributeNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltportletAPItext key=no_bookmarks bundle=nlsTextgtNo

bookmarksltportletAPItextgtltpgt

lt

else

while (ehasMoreElements())

- 44 -

String name = (String)enextElement()

String value = (String)prefsgetAttribute(name)

gt

lttr class=wpsTableRowgt

lttdgt lt=namegt lttdgt

lttdgt lt=valuegt lttdgt

lttdgt lta href=ltportletAPIcreateURIgtltportletAPIURIAction

name=removeURIgtltportletAPIURIParameter name=remove

value=lt=namegtgtltportletAPIcreateURIgtgt

(ltportletAPItext key=delete bundle=nlsTextgt)ltagt

lttdgt

lttrgt

lt

gt

ltform action=lt=addURIgt method=POSTgt

lttr class=wpsTableRowgt

lttdgtltinput name=ltportletAPIencodeNamespace value=namegt type=text

class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=ltportletAPIencodeNamespace value=valuegt type=text

class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=ltportletAPIencodeNamespace value=addgt type=submit

value=ltportletAPItext key=add bundle=nlsTextgt class=portlet-form-buttongtlttdgt

lttrgt

ltformgt

lttablegt

- 45 -

ltform action=lt=cancelURIgt method=postgt

ltinput name=ltportletAPIencodeNamespace value=cancelgt type=submit

value=ltportletAPItext key=cancel bundle=nlsTextgt class=portlet-form-buttongt

ltformgt

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 ldquodeleterdquo button for which an URL with the action ldquoremoveURIrdquo 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 ldquocancelrdquo button from the request

64 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

lt page import=javaxportlet javautil session=falsegt

lt taglib uri=httpjavasuncomportlet prefix=portletAPI gt

lt taglib prefix=fmt uri=httpjavasuncomjstlfmt gt

ltportletAPIdefineObjects gt

ltfmtsetBundle basename=nlsTextgt

lt

ResourceBundle myText = ResourceBundlegetBundle(nlsText requestgetLocale())

gt

lth4gtltfmtmessage key=available_bookmarksgtlth4gt

lt

PortletPreferences prefs = renderRequestgetPreferences()

Enumeration e = prefsgetNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltfmtmessage key=no_bookmarksgtltpgt

- 46 -

lt

else

gt

ltpgt

lt

while (ehasMoreElements())

String name = (String)enextElement()

String value = prefsgetValue(namelt+myTextgetString(undefined)+gt)

gt

lta href=lt=valuegt target=_blankgtlt=namegtltagtltbr gt

lt

gt

ltpgt

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 fmtmessage 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

lt page import=javaxportlet javautil session=false gt

lt taglib uri=httpjavasuncomportlet prefix=portletAPI gt

lt taglib prefix=fmt uri=httpjavasuncomjstlfmt gt

ltjspuseBean id=addUrl scope=request class=javalangString gt

ltjspuseBean id=cancelUrl scope=request class=javalangString gt

- 47 -

ltportletAPIdefineObjectsgt

lt

ResourceBundle myText = ResourceBundlegetBundle(nlsText requestgetLocale())

gt

ltfmtsetBundle basename=nlsTextgt

lth4gtltfmtmessage key=available_bookmarksgtlth4gt

lttable class=wpsTablegt

lttr class=wpsTableRowgt

ltth class=wpsTableHeadgtltfmtmessage key=namegtltthgt

ltth class=wpsTableHeadgtltfmtmessage key=urlgtltthgt

lttdgtlttdgt

lttrgt

lt

PortletPreferences prefs = renderRequestgetPreferences()

Enumeration e = prefsgetNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltfmtmessage key=no_bookmarksgtltpgt

lt

else

while (ehasMoreElements())

String name = (String)enextElement()

String value = prefsgetValue(namelt+myTextgetString(undefined)+gt)

gt

lttr class=wpsTableRowgt

lttdgt lt=namegt lttdgt

lttdgt lt=valuegt lttdgt

- 48 -

lttdgt ltportletAPIactionURL var=removeUrlgt

ltportletAPIparam name=remove value=lt=namegtgt

ltportletAPIactionURLgt

lta href=lt=removeUrltoString()gtgt(ltfmtmessage key=deletegt)ltagt

lttdgt

lttrgt

lt

gt

ltform action=lt=addUrlgt method=POSTgt

lttr class=wpsTableRowgt

lttdgtltinput name=name type=text class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=value type=text class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=add type=submit value=ltfmtmessage key=addgt

class=portlet-form-buttongtlttdgt

lttrgt

ltformgt

lttablegt

ltform action=lt=cancelUrlgt method=postgt

ltinput name=cancel type=submit value=ltfmtmessage key=cancelgt class=portlet-

form-buttongt

ltformgt

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 14 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 -

- 51 -

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 (eg eventing) the IBM Portlet API still needs to be used Trademarks bull IBM and WebSphere are trademarks or registered trademarks of IBM Corporation in

the United States other countries or both bull 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 bull Other company product and service names may be trademarks or service marks of

others IBM copyright and trademark information httpwwwibmcomlegalcopytradephtml

  • Introduction
  • JSR 168 and the Java Community Process
  • Comparing concepts
    • Basic concepts
      • Portal
      • Portal page
      • Portlet
      • Portlet Container
        • Concepts that are the same
          • Portlet mode
          • Window state
          • Portlet life cycle and request processing
          • URL encoding
          • Include servletsJSPs
          • Portlet application packaging
          • Expiration-based caching
            • Concepts that differ
              • Portlet application entity
              • Portlet entity
              • Action and Render Request Response objects
              • Window concept
              • Portlet API does not extend servlet API
              • TAG libraries
                • Concepts new in the JSR 168
                  • Render parameter
                  • Extension mechanisms
                    • Custom window states
                    • Custom portlet modes
                    • Custom user info
                    • Request Response properties
                      • Web application session scope
                      • Reuse of the HttpSession listeners
                      • J2EE role support
                      • Resource bundles
                      • Multiple response content types
                      • Redirect in action
                      • Preference validator
                      • Portal context
                      • Localization support
                        • Concepts missing in the JSR 168
                          • Eventing
                          • Additional lifecycle events
                          • Property broker
                          • Portlet Menus
                          • Portlet Services
                          • Invalidation-based caching
                            • Alignment with WSRP
                              • Outlook for the next version of the JSR 168
                              • Guidelines for programming IBM Portlet API portlets
                                • Similar Functionality
                                  • Basic programming model
                                  • Portlet private session
                                  • User profile information
                                  • Persistent data
                                  • Portlet modes and window states
                                  • Expiration-based caching
                                    • Slightly different functionality
                                      • Sharing of data between portlets
                                      • Session listeners
                                        • New JSR 168 functionality
                                          • Navigational state (render parameters)
                                            • Pitfalls
                                              • Request response objects for action and render phase
                                              • Include search path
                                              • Form parameter encoding
                                              • Title setting
                                                  • Examples
                                                    • IBM Portlet API Portlet Code
                                                    • JSR 168 Portlet Code
                                                    • IBM Portlet API JSPs
                                                    • JSR 168 JSPs
                                                      • Summary
Page 7: Difference Bw Jsr168 and Ibm

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

312 Portal page

Figure 2

Figure 2 Basic portal page components

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 (eg maximize or minimize the portlet) and buttons to change the mode of a portlet (eg show help or edit the predefined portlet settings)

ltTitlegt Edit

Portlet content

Portal page

Portletwindows

Window states Portlet modes

Markup Fragments

ltTitlegt Edit

ltTitlegt Edit

Portlet content

Portlet content

- 7 -

313 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 (eg 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 requestresponse 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 users interactions

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

314 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

32 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

321 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

bull Edit ndash to display one or more personalization views that let the user personalize portlet settings

bull Help ndash to display help views bull View ndash to display the portlet output bull Configure ndash 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

bull required to support (same semantic as above) o Edit o Help o View

bull optional custom modes o About ndash to display information on the portlets purpose origin version etc o Config ndash has the same semantic as the IBM Portlet API configure mode o Edit_defaults ndash to set the default values for the modifiable preferences that

are typically changed in the EDIT screen o Preview ndash to render output without the need of having back-end

connections or user specific data available o Print ndash to display a view that is suitable for printing

bull portal vendor specific modes that are available only in a portal of a specific vendor

322 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

bull Closed (deprecated) ndash to indicate that a window should be closed bull Detached (deprecated) ndash to indicate that a window should be detached bull Maximized ndash to indicate that a window has more real estate to render its output

then in normal window state

- 9 -

bull Minimized ndash to indicate that the portlet is minimized and cannot render any output

bull Moving (deprecated) ndash to indicate that the portlet window has been moved bull Normal ndash to indicate that the portlet is sharing its screen with other portlets on a

page bull Resizing (deprecated) ndash to indicate that the portlet has been resized bull Solo ndash to indicate that the portlet is the only portlet on the page

Whereas the JSR 168 has only the following mandatory window states

bull Maximized ndash same as in the IBM Portlet API bull Minimized ndash to indicate that the portlet should only render minimal or no output bull Normal ndash same as in the IBM Portlet API

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

323 Portlet life cycle and request processing

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

bull init ndash to initialize the portlet and put the portlet into service bull handle requests ndash process different kinds of action and render requests bull destroy ndash 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

324 URL encoding

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

bull 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

bull 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

325 Include servletsJSPs

In both APIrsquos 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()

contextinclude(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)

rdinclude(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 HttpServetRequestgetSession() 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

326 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 (webxml) and one to specify the portlet resources (portletxml) All web resources that are not portlets must be specified in the webxml deployment descriptor All portlets and portlet related settings must be specified in an additional file called portletxml

- 12 -

Different from JSR 168 in the IBM Portlet API all portlets must also be listed in the webxml as they are also servlets (see also 335 for examples of the deployment descitptors)

327 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

33 Concepts that differ

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

331 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 webxml and concrete portlet applications of concrete portlets based on the abstract ones The following portletxml example shows these two different parts

IBM PORTLET API PORTLETXML EXAMPLE

ltxml version=10 encoding=UTF-8gt

ltDOCTYPE portlet-app-def PUBLIC -IBMDTD Portlet Application 11EN

portlet_11dtdgt

ltportlet-app-defgt

ltportlet-app uid=commycobookmark1234 major-version=7 minor-version=24gt

ltportlet-app-namegtBookmark Application7ltportlet-app-namegt

ltportlet id=Portlet_1 href=WEB-INFwebxmlServlet_1gt

- 13 -

ltportlet-namegtBookmark Portlet7ltportlet-namegt

ltallowsgt

ltmaximizedgt

ltminimizedgt

ltallowsgt

ltsupportsgt

ltmarkup name=htmlgt

ltview output=fragmentgt

ltedit output=fragmentgt

ltmarkupgt

ltsupportsgt

ltportletgt

ltportlet-appgt

ltconcrete-portlet-app uid=commycobookmark12341gt

ltportlet-app-namegtConcreteSamplets_Bookmark7ltportlet-app-namegt

ltconcrete-portlet href=Portlet_1gt

ltportlet-namegtBookmark Portlet7ltportlet-namegt

ltdefault-localegtenltdefault-localegt

ltlanguage locale=engt

lttitlegtMy Bookmarks7lttitlegt

lttitle-shortgtBookmarks7lttitle-shortgt

ltdescriptiongtPortlet showing your personalized bookmarksltdescriptiongt

ltkeywordsgtbookmarksltkeywordsgt

ltlanguagegt

ltconfig-paramgt

ltparam-namegturl1ltparam-namegt

ltparam-valuegthttpwwwgooglecomltparam-valuegt

ltconfig-paramgt

ltconcrete-portletgt

- 14 -

ltconcrete-portlet-appgt

ltportlet-app-defgt

As portlets are servlets in the IBM Portlet API the portletxml has references for each portlet to the servlet in the webxml that represents the portlet The webxml for this example is

IBM PORTLET API WEBXML EXAMPLE

ltxml version=10 encoding=UTF-8gt

ltDOCTYPE web-app

PUBLIC -Sun Microsystems IncDTD Web Application 22EN

httpjavasuncomj2eedtdsweb-app_22dtdgt

ltweb-app id=WebApp_1gt

ltdisplay-namegtbookmark7ltdisplay-namegt

ltservlet id=Servlet_1gt

ltservlet-namegtBookmark7ltservlet-namegt

ltservlet-classgtcommycobookmarkBookmarkPortletltservlet-classgt

ltinit-paramgt

ltparam-namegtjspviewltparam-namegt

ltparam-valuegtbookmarkViewjspltparam-valuegt

ltinit-paramgt

ltinit-paramgt

ltparam-namegtjspeditltparam-namegt

ltparam-valuegtbookmarkEditjspltparam-valuegt

ltinit-paramgt

ltservletgt

ltservlet-mappinggt

ltservlet-namegtBookmark7ltservlet-namegt

lturl-patterngtBookmark7lturl-patterngt

ltservlet-mappinggt

ltweb-appgt

- 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 webxml and not in the portletxml In the JSR 168 the deployment descriptor is more like the webxml 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 portletxml example would look like when using the JSR 168 deployment descriptor format

JSR 168 PORTLETXML EXAMPLE

ltxml version=10 encoding=UTF-8gt

ltxml version=10encoding=UTF-8gt

ltportlet-app xmlns=httpjavasuncomxmlnsportletportlet-app_1_0xsd version=10

xmlnsxsi=httpwwww3org2001XMLSchema-instance

xsischemaLocation=httpjavasuncomxmlnsportlet-app_1_0xsd

httpjavasuncomxmlnsportletportlet-app_1_0xsdgt

ltportletgt

ltdescription xmllang=ENgtPortlet showing your personalized

bookmarksltdescriptiongt

ltportlet-namegtBookmark Portlet7ltportlet-namegt

ltdisplay-name xmllang=ENgtBookmark Portletltdisplay-namegt

ltportlet-classgtcommycobookmarkBookmarkPortletltportlet-classgt

ltinit-paramgt

ltnamegtjspviewltnamegt

ltvaluegtbookmarkViewjspltvaluegt

ltinit-paramgt

ltinit-paramgt

ltnamegtjspeditltnamegt

ltvaluegtbookmarkEditjspltvaluegt

ltinit-paramgt

ltsupportsgt

ltmime-typegttexthtmlltmime-typegt

ltportlet-modegtviewltportlet-modegt

- 16 -

ltportlet-modegteditltportlet-modegt

ltsupportsgt

ltsupported-localegtENltsupported-localegt

ltportlet-infogt

lttitlegtMy Bookmarks7lttitlegt

ltshort-titlegtBookmarks7ltshort-titlegt

ltkeywordsgtbookmarksltkeywordsgt

ltportlet-infogt

ltportlet-preferencesgt

ltpreferencegt

ltnamegturl1ltnamegt

ltvaluegthttpwwwgooglecomltvaluegt

ltpreferencegt

ltportlet-preferencesgt

ltportletgt

ltportlet-appgt

Here the initialization parameters are directly specified in the portletxml as portlets are independent components in the JSR 168 The following example represents the webxml for the JSR 168 bookmark portlet

JSR 168 WEBXML EXAMPLE

ltxml version=10 encoding=UTF-8gt

ltDOCTYPE web-app PUBLIC -Sun Microsystems IncDTD Web Application 23EN

httpjavasuncomdtdweb-app_2_3dtdgt

ltweb-appgt

ltdisplay-namegtBookmark Application7ltdisplay-namegt

ltweb-appgt

The only item that needs to be specified in the JSR 168 webxml 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 portletxml as portlet application name as there can be several concrete instances of the same abstract application

- 17 -

332 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 331) 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 331) 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

333 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

334 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 instanceentity 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 -

335 Portlet API does not extend servlet API

In the IBM Portlet API portlets extend servlets and all the major interfaces (Request Response Session hellip) 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

336 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

bull defineObjects tag ndash to define the basic portlet API objects RenderRequest RenderResponse and PortletConfig

bull actionURL tag ndash to create an action URL bull renderURL tag ndash to create a render URL bull namespace tag ndash 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 donrsquot need decoding

34 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 -

341 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 (eg 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

342 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

3421 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

3422 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 322) 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

3423 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

3424 Request Response properties

Properties can be used by the portalportlet container to send vendor specific information to the portlet andor the portlet can send vendor specific information to the portalportlet-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

343 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 (eg between portlets or between a portlet and a servlet)

344 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 23 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

345 J2EE role support

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

346 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 -

347 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 PortletRequestgetResponseContentTypes 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 (eg ldquotextrdquo or ldquordquo) 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

348 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 (eg an accounting servlet) in response to an action

349 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

3410 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 vendorrsquos 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)

3411 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 xmllang attribute like the

- 22 -

servlet 24 deployment descriptor Thus the same tag with descriptions in different languages can be used (eg 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

35 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)

351 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

bull ActionEventThe action event maps to the action phase call in the JSR 168

bull MessageEventMessage 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)

bull PortletApplicationSettingsAttributeEventPortletSettingsAttributeEventThese are events that get fired when attributes for the application or of the portlet settings change

bull WindowEventThe portlet will register for window events to get notified if the portlet window is changed via the window decorations

352 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 -

bull PortletPageListener The page listeners provides the portlet with events for the beginning of the page before any markup is written for this page (eg to write JavaScript at the beginning of the page) and the end of the page after all markup is written

bull 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 23 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

bull EventPhaseListener The event phase listener notifies the portlet of the beginning and end of the eventaction phase

353 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

354 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 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

Figure 4

- 24 -

Figure 4 Portlet menu example

355 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

356 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 -

36 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 indicates portlet in what mode to operate for a given request

View edit help + custom modes

view edit help + custom modes

full alignment

Window State the state of the window in which the portlet output will be displayed

minimized normal maximized solo +

custom window states

minimized normal maximized +

custom window states

full alignment (ldquosolordquo is missing in the JSR but can be implemented as a custom state)

URL encoding to allow re-writing URLs created by the portlet

defines how to create URLs to allow re-writing of the URLs either on consumer or producer side

encapsulates URL creation via a Java object

full alignment (the implementation of the Java object can implement the WSRP URL rewriting rules)

Namespace encoding to avoid that several portlets on a page conflicting with each other

defines namespace prefixes for consumer and producer side namespacing

provides a Java method to namespace a String

full alignment (the JSR namespace method can implement the WSRP namespace behavior)

User ndash portlet interaction operations

performBlockingInteraction blocking action processing

getMarkup render the markup

action blocking action processing

render render the makup

full alignment (action invocations carried through performBlockingInteraction render carried through getMarkup)

View state that allows the current portlet fragment to be correctly displayed in sub-sequent render calls

navigational state render parameter full alignment (WSRP navigational state maps to JSR render parameters)

Storing transient state across request

session state concept implemented via a sessionID

utilizes the Http web application session

full alignment (the WSRP sessionID can be used to reference the JSR session)

Storing persistent state to personalize the rendering of the portlet

allows to have properties of arbitrary types

provides String-based preferences

full alignment (JSR String preferences can be mapped to WSRP properties)

Information about the portal calling the portlet

RegistrationData provide information of the consumer to the producer

PortalContext provide a Java interface to access information about the portal calling the portlet

full alignment (all data represented through the PortalContext to the JSR portlet are available in the RegistrationData)

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

Aggregated HTML WML VoiceXML

over HTTPMark-Up Fragments

Transferred via WSRP

Portal

WSRP Service

WSRP Service

WSRP Service

WSRP Consumer WSRP Producer

Use of WSRP Services in Portals

Portal sharing Portlets as WSRP Services

ServerPortalPortals

Huge numberof users Publishing Portal

WSRPWrapperPortalsPortalsPortal

Portlet

Portlet

Portlet

WSRP Consumer WSRP Producer

ProxyPortlet

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

bull 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

bull 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

bull 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

bull 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 CCPP standard allowing a portlet to query the client capabilities and adopting its markup accordingly (eg screen size browser) This API is likely to be included in the next version of the portlet API Also J2EE 14 was finalized during this time period J2EE 14 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 14

bull caching The first version of the JSR 168 API is limited to expiration-based caching (see section 327) 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

bull 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

51 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

511 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

bull portlets are components Portlets are components that implement a specific function Different functions should be distributed to different portlets

bull 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

bull 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

512 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 HttpServletRequestgetSession() call in the JSPs called via the IBM Portlet API needs to be replaced when moving to JSR 168 portlets by the RenderRequestgetPortletSession() 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 HttpServletRequestgetSession() will get the HttpSession and therefore need to access the portlet session via the RenderRequest

513 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

514 Persistent data

Portlets can store customization and personalization data persistently Customization data are related to the portlet and are valid for all users (eg 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 (eg 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

515 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

516 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

52 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

521 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 351 353) 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

522 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

53 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 -

531 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

bull no support of the back button in the browser bull current state of the portlet is not bookmarkable bull 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 bull 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

54 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

541 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 -

542 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

543 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

544 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 wersquoll 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

Figure 7After clicking on the Edit mode button the portlet renders the Edit view shown in

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

Figure 8

After we press the ldquoAddrdquo 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

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

bull use JSPs for rendering the output bull customize the portlet output taking user specific data into account bull 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

61 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 comibmwpssampleswp5

import javaio

import javautil

import orgapachejetspeedportlet

import orgapachejetspeedportletevent

public class IbmBookmark extends PortletAdapter implements ActionListener

public void init(PortletConfig portletConfig) throws UnavailableException

superinit(portletConfig)

- 36 -

public void doView(PortletRequest request PortletResponse response)

throws PortletException IOException

String jspName = thisgetPortletConfig()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 = responsecreateReturnURI()

addURIaddAction(add)

requestsetAttribute(addURI addURItoString())

PortletURI cancelURI = responsecreateReturnURI()

requestsetAttribute(cancelURI cancelURItoString())

String jspName = thisgetPortletConfig()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 ldquocancelrdquo and ldquoaddrdquo URLs are created inside the portlet and attached to the request before including the Edit JSP Both URLs are from type ldquoReturnURIrdquo 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 = eventgetRequest()

String action = eventgetActionString()

PortletLog log = getPortletLog()

if ( action=null )

try

if (actionequals(removeURI))

String removeName = requestgetParameter(remove)

PortletData portData = requestgetData()

portDataremoveAttribute(removeName)

portDatastore()

if (actionequals(add))

PortletData portData = requestgetData()

String name = requestgetParameter(name)

String value = requestgetParameter(value)

portDatasetAttribute(name value)

portDatastore()

catch ( AccessDeniedException ade )

logerror(AccessDeniedException occured when adding or deleting a bookmark)

catch ( IOException ioe )

logerror(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 ldquoaddrdquo or ldquodeleterdquo 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 ldquoaddrdquo or ldquoremoveURIrdquo If the user has clicked on the ldquoremoverdquo button the corresponding link is removed from the portlet data whereas if ldquoaddrdquo was clicked the data entered by the user is added to the portlet data

62 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 comibmwpssamplesjsr

import javaio

import javaxportlet

public class Bookmark extends GenericPortlet

public void init(PortletConfig config) throws PortletException

superinit(config)

public void doView(RenderRequest request RenderResponse response)

throws PortletException IOException

responsesetContentType(texthtml)

String jspName = getPortletConfig()getInitParameter(jspView)

PortletRequestDispatcher rd = getPortletContext()getRequestDispatcher(jspName)

rdinclude(requestresponse)

- 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

responsesetContentType(texthtml)

PortletURL addUrl = responsecreateActionURL()

addUrlsetPortletMode(PortletModeVIEW)

addUrlsetParameter(addadd)

requestsetAttribute(addUrladdUrltoString())

PortletURL cancelUrl = responsecreateRenderURL()

cancelUrlsetPortletMode(PortletModeVIEW)

requestsetAttribute(cancelUrlcancelUrltoString())

String jspName = getPortletConfig()getInitParameter(jspEdit)

PortletRequestDispatcher rd = getPortletContext()getRequestDispatcher(jspName)

rdinclude(requestresponse)

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 ldquoaddrdquo button URL an action URL is created as we need to store the user input of the add form persistently For the ldquocancelrdquo 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 = requestgetParameter(remove)

if (removeName = null)

PortletPreferences prefs = requestgetPreferences()

prefsreset(removeName)

prefsstore()

String add = requestgetParameter(add)

if (add = null)

PortletPreferences prefs = requestgetPreferences()

String name = requestgetParameter(name)

String value = requestgetParameter(value)

prefssetValue(name value)

prefsstore()

catch ( IOException ioe )

getPortletContextlog(An IO error occured when trying to remove a bookmark)

catch ( PortletException pe )

getPortletContextlog(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

bull 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

bull 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

bull Persistent portlet data The JSR 168 persistent data PortletPreferences have an API similar to the JDK 14 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

bull 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

63 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

lt page contentType=texthtml import=javautil comibmwpssampleswp5

orgapachejetspeedportlet session=falsegt

lt taglib uri=WEB-INFtldportlettld prefix=portletAPI gt

- 42 -

ltportletAPIinitgt

ltp class=wpsPortletHeadgtltportletAPItext key=available_bookmarks

bundle=nlsTextgtAvailable BookmarksltportletAPItextgtltpgt

lt

PortletData prefs = portletRequestgetData()

Enumeration e = prefsgetAttributeNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltportletAPItext key=no_bookmarks bundle=nlsTextgtNo

bookmarksltportletAPItextgtltpgt

lt

else

gt

ltp class=wpsIndentMediumgt

lt

while (ehasMoreElements())

String name = (String)enextElement()

String value = (String)prefsgetAttribute(name)

gt

lta href=lt=valuegt target=_blankgtlt=namegtltagtltbr gt

lt

gt

ltpgt

The View JSP first call portletAPIinit 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

lt page contentType=texthtml import=javautil

comibmwpssampleswp5orgapachejetspeedportlet session=falsegt

lt taglib uri=WEB-INFtldportlettld prefix=portletAPI gt

ltjspuseBean id=addURI class=javalangString scope=request gt

ltjspuseBean id=cancelURI class=javalangString scope=request gt

ltportletAPIinitgt

lth4gtltportletAPItext key=available_bookmarks bundle=nlsTextgtAvailable

BookmarksltportletAPItextgtlth4gt

lttable class=wpsTablegt

lttr class=wpsTableRowgt

ltth class=portlet-table-headergtltportletAPItext key=name bundle=nlsTextgtltthgt

ltth class=portlet-table-headergtltportletAPItext key=url bundle=nlsTextgtltthgt

lttdgtlttdgt

lttrgt

lt

PortletData prefs = portletRequestgetData()

Enumeration e = prefsgetAttributeNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltportletAPItext key=no_bookmarks bundle=nlsTextgtNo

bookmarksltportletAPItextgtltpgt

lt

else

while (ehasMoreElements())

- 44 -

String name = (String)enextElement()

String value = (String)prefsgetAttribute(name)

gt

lttr class=wpsTableRowgt

lttdgt lt=namegt lttdgt

lttdgt lt=valuegt lttdgt

lttdgt lta href=ltportletAPIcreateURIgtltportletAPIURIAction

name=removeURIgtltportletAPIURIParameter name=remove

value=lt=namegtgtltportletAPIcreateURIgtgt

(ltportletAPItext key=delete bundle=nlsTextgt)ltagt

lttdgt

lttrgt

lt

gt

ltform action=lt=addURIgt method=POSTgt

lttr class=wpsTableRowgt

lttdgtltinput name=ltportletAPIencodeNamespace value=namegt type=text

class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=ltportletAPIencodeNamespace value=valuegt type=text

class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=ltportletAPIencodeNamespace value=addgt type=submit

value=ltportletAPItext key=add bundle=nlsTextgt class=portlet-form-buttongtlttdgt

lttrgt

ltformgt

lttablegt

- 45 -

ltform action=lt=cancelURIgt method=postgt

ltinput name=ltportletAPIencodeNamespace value=cancelgt type=submit

value=ltportletAPItext key=cancel bundle=nlsTextgt class=portlet-form-buttongt

ltformgt

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 ldquodeleterdquo button for which an URL with the action ldquoremoveURIrdquo 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 ldquocancelrdquo button from the request

64 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

lt page import=javaxportlet javautil session=falsegt

lt taglib uri=httpjavasuncomportlet prefix=portletAPI gt

lt taglib prefix=fmt uri=httpjavasuncomjstlfmt gt

ltportletAPIdefineObjects gt

ltfmtsetBundle basename=nlsTextgt

lt

ResourceBundle myText = ResourceBundlegetBundle(nlsText requestgetLocale())

gt

lth4gtltfmtmessage key=available_bookmarksgtlth4gt

lt

PortletPreferences prefs = renderRequestgetPreferences()

Enumeration e = prefsgetNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltfmtmessage key=no_bookmarksgtltpgt

- 46 -

lt

else

gt

ltpgt

lt

while (ehasMoreElements())

String name = (String)enextElement()

String value = prefsgetValue(namelt+myTextgetString(undefined)+gt)

gt

lta href=lt=valuegt target=_blankgtlt=namegtltagtltbr gt

lt

gt

ltpgt

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 fmtmessage 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

lt page import=javaxportlet javautil session=false gt

lt taglib uri=httpjavasuncomportlet prefix=portletAPI gt

lt taglib prefix=fmt uri=httpjavasuncomjstlfmt gt

ltjspuseBean id=addUrl scope=request class=javalangString gt

ltjspuseBean id=cancelUrl scope=request class=javalangString gt

- 47 -

ltportletAPIdefineObjectsgt

lt

ResourceBundle myText = ResourceBundlegetBundle(nlsText requestgetLocale())

gt

ltfmtsetBundle basename=nlsTextgt

lth4gtltfmtmessage key=available_bookmarksgtlth4gt

lttable class=wpsTablegt

lttr class=wpsTableRowgt

ltth class=wpsTableHeadgtltfmtmessage key=namegtltthgt

ltth class=wpsTableHeadgtltfmtmessage key=urlgtltthgt

lttdgtlttdgt

lttrgt

lt

PortletPreferences prefs = renderRequestgetPreferences()

Enumeration e = prefsgetNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltfmtmessage key=no_bookmarksgtltpgt

lt

else

while (ehasMoreElements())

String name = (String)enextElement()

String value = prefsgetValue(namelt+myTextgetString(undefined)+gt)

gt

lttr class=wpsTableRowgt

lttdgt lt=namegt lttdgt

lttdgt lt=valuegt lttdgt

- 48 -

lttdgt ltportletAPIactionURL var=removeUrlgt

ltportletAPIparam name=remove value=lt=namegtgt

ltportletAPIactionURLgt

lta href=lt=removeUrltoString()gtgt(ltfmtmessage key=deletegt)ltagt

lttdgt

lttrgt

lt

gt

ltform action=lt=addUrlgt method=POSTgt

lttr class=wpsTableRowgt

lttdgtltinput name=name type=text class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=value type=text class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=add type=submit value=ltfmtmessage key=addgt

class=portlet-form-buttongtlttdgt

lttrgt

ltformgt

lttablegt

ltform action=lt=cancelUrlgt method=postgt

ltinput name=cancel type=submit value=ltfmtmessage key=cancelgt class=portlet-

form-buttongt

ltformgt

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 14 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 -

- 51 -

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 (eg eventing) the IBM Portlet API still needs to be used Trademarks bull IBM and WebSphere are trademarks or registered trademarks of IBM Corporation in

the United States other countries or both bull 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 bull Other company product and service names may be trademarks or service marks of

others IBM copyright and trademark information httpwwwibmcomlegalcopytradephtml

  • Introduction
  • JSR 168 and the Java Community Process
  • Comparing concepts
    • Basic concepts
      • Portal
      • Portal page
      • Portlet
      • Portlet Container
        • Concepts that are the same
          • Portlet mode
          • Window state
          • Portlet life cycle and request processing
          • URL encoding
          • Include servletsJSPs
          • Portlet application packaging
          • Expiration-based caching
            • Concepts that differ
              • Portlet application entity
              • Portlet entity
              • Action and Render Request Response objects
              • Window concept
              • Portlet API does not extend servlet API
              • TAG libraries
                • Concepts new in the JSR 168
                  • Render parameter
                  • Extension mechanisms
                    • Custom window states
                    • Custom portlet modes
                    • Custom user info
                    • Request Response properties
                      • Web application session scope
                      • Reuse of the HttpSession listeners
                      • J2EE role support
                      • Resource bundles
                      • Multiple response content types
                      • Redirect in action
                      • Preference validator
                      • Portal context
                      • Localization support
                        • Concepts missing in the JSR 168
                          • Eventing
                          • Additional lifecycle events
                          • Property broker
                          • Portlet Menus
                          • Portlet Services
                          • Invalidation-based caching
                            • Alignment with WSRP
                              • Outlook for the next version of the JSR 168
                              • Guidelines for programming IBM Portlet API portlets
                                • Similar Functionality
                                  • Basic programming model
                                  • Portlet private session
                                  • User profile information
                                  • Persistent data
                                  • Portlet modes and window states
                                  • Expiration-based caching
                                    • Slightly different functionality
                                      • Sharing of data between portlets
                                      • Session listeners
                                        • New JSR 168 functionality
                                          • Navigational state (render parameters)
                                            • Pitfalls
                                              • Request response objects for action and render phase
                                              • Include search path
                                              • Form parameter encoding
                                              • Title setting
                                                  • Examples
                                                    • IBM Portlet API Portlet Code
                                                    • JSR 168 Portlet Code
                                                    • IBM Portlet API JSPs
                                                    • JSR 168 JSPs
                                                      • Summary
Page 8: Difference Bw Jsr168 and Ibm

313 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 (eg 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 requestresponse 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 users interactions

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

314 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

32 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

321 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

bull Edit ndash to display one or more personalization views that let the user personalize portlet settings

bull Help ndash to display help views bull View ndash to display the portlet output bull Configure ndash 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

bull required to support (same semantic as above) o Edit o Help o View

bull optional custom modes o About ndash to display information on the portlets purpose origin version etc o Config ndash has the same semantic as the IBM Portlet API configure mode o Edit_defaults ndash to set the default values for the modifiable preferences that

are typically changed in the EDIT screen o Preview ndash to render output without the need of having back-end

connections or user specific data available o Print ndash to display a view that is suitable for printing

bull portal vendor specific modes that are available only in a portal of a specific vendor

322 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

bull Closed (deprecated) ndash to indicate that a window should be closed bull Detached (deprecated) ndash to indicate that a window should be detached bull Maximized ndash to indicate that a window has more real estate to render its output

then in normal window state

- 9 -

bull Minimized ndash to indicate that the portlet is minimized and cannot render any output

bull Moving (deprecated) ndash to indicate that the portlet window has been moved bull Normal ndash to indicate that the portlet is sharing its screen with other portlets on a

page bull Resizing (deprecated) ndash to indicate that the portlet has been resized bull Solo ndash to indicate that the portlet is the only portlet on the page

Whereas the JSR 168 has only the following mandatory window states

bull Maximized ndash same as in the IBM Portlet API bull Minimized ndash to indicate that the portlet should only render minimal or no output bull Normal ndash same as in the IBM Portlet API

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

323 Portlet life cycle and request processing

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

bull init ndash to initialize the portlet and put the portlet into service bull handle requests ndash process different kinds of action and render requests bull destroy ndash 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

324 URL encoding

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

bull 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

bull 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

325 Include servletsJSPs

In both APIrsquos 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()

contextinclude(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)

rdinclude(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 HttpServetRequestgetSession() 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

326 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 (webxml) and one to specify the portlet resources (portletxml) All web resources that are not portlets must be specified in the webxml deployment descriptor All portlets and portlet related settings must be specified in an additional file called portletxml

- 12 -

Different from JSR 168 in the IBM Portlet API all portlets must also be listed in the webxml as they are also servlets (see also 335 for examples of the deployment descitptors)

327 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

33 Concepts that differ

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

331 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 webxml and concrete portlet applications of concrete portlets based on the abstract ones The following portletxml example shows these two different parts

IBM PORTLET API PORTLETXML EXAMPLE

ltxml version=10 encoding=UTF-8gt

ltDOCTYPE portlet-app-def PUBLIC -IBMDTD Portlet Application 11EN

portlet_11dtdgt

ltportlet-app-defgt

ltportlet-app uid=commycobookmark1234 major-version=7 minor-version=24gt

ltportlet-app-namegtBookmark Application7ltportlet-app-namegt

ltportlet id=Portlet_1 href=WEB-INFwebxmlServlet_1gt

- 13 -

ltportlet-namegtBookmark Portlet7ltportlet-namegt

ltallowsgt

ltmaximizedgt

ltminimizedgt

ltallowsgt

ltsupportsgt

ltmarkup name=htmlgt

ltview output=fragmentgt

ltedit output=fragmentgt

ltmarkupgt

ltsupportsgt

ltportletgt

ltportlet-appgt

ltconcrete-portlet-app uid=commycobookmark12341gt

ltportlet-app-namegtConcreteSamplets_Bookmark7ltportlet-app-namegt

ltconcrete-portlet href=Portlet_1gt

ltportlet-namegtBookmark Portlet7ltportlet-namegt

ltdefault-localegtenltdefault-localegt

ltlanguage locale=engt

lttitlegtMy Bookmarks7lttitlegt

lttitle-shortgtBookmarks7lttitle-shortgt

ltdescriptiongtPortlet showing your personalized bookmarksltdescriptiongt

ltkeywordsgtbookmarksltkeywordsgt

ltlanguagegt

ltconfig-paramgt

ltparam-namegturl1ltparam-namegt

ltparam-valuegthttpwwwgooglecomltparam-valuegt

ltconfig-paramgt

ltconcrete-portletgt

- 14 -

ltconcrete-portlet-appgt

ltportlet-app-defgt

As portlets are servlets in the IBM Portlet API the portletxml has references for each portlet to the servlet in the webxml that represents the portlet The webxml for this example is

IBM PORTLET API WEBXML EXAMPLE

ltxml version=10 encoding=UTF-8gt

ltDOCTYPE web-app

PUBLIC -Sun Microsystems IncDTD Web Application 22EN

httpjavasuncomj2eedtdsweb-app_22dtdgt

ltweb-app id=WebApp_1gt

ltdisplay-namegtbookmark7ltdisplay-namegt

ltservlet id=Servlet_1gt

ltservlet-namegtBookmark7ltservlet-namegt

ltservlet-classgtcommycobookmarkBookmarkPortletltservlet-classgt

ltinit-paramgt

ltparam-namegtjspviewltparam-namegt

ltparam-valuegtbookmarkViewjspltparam-valuegt

ltinit-paramgt

ltinit-paramgt

ltparam-namegtjspeditltparam-namegt

ltparam-valuegtbookmarkEditjspltparam-valuegt

ltinit-paramgt

ltservletgt

ltservlet-mappinggt

ltservlet-namegtBookmark7ltservlet-namegt

lturl-patterngtBookmark7lturl-patterngt

ltservlet-mappinggt

ltweb-appgt

- 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 webxml and not in the portletxml In the JSR 168 the deployment descriptor is more like the webxml 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 portletxml example would look like when using the JSR 168 deployment descriptor format

JSR 168 PORTLETXML EXAMPLE

ltxml version=10 encoding=UTF-8gt

ltxml version=10encoding=UTF-8gt

ltportlet-app xmlns=httpjavasuncomxmlnsportletportlet-app_1_0xsd version=10

xmlnsxsi=httpwwww3org2001XMLSchema-instance

xsischemaLocation=httpjavasuncomxmlnsportlet-app_1_0xsd

httpjavasuncomxmlnsportletportlet-app_1_0xsdgt

ltportletgt

ltdescription xmllang=ENgtPortlet showing your personalized

bookmarksltdescriptiongt

ltportlet-namegtBookmark Portlet7ltportlet-namegt

ltdisplay-name xmllang=ENgtBookmark Portletltdisplay-namegt

ltportlet-classgtcommycobookmarkBookmarkPortletltportlet-classgt

ltinit-paramgt

ltnamegtjspviewltnamegt

ltvaluegtbookmarkViewjspltvaluegt

ltinit-paramgt

ltinit-paramgt

ltnamegtjspeditltnamegt

ltvaluegtbookmarkEditjspltvaluegt

ltinit-paramgt

ltsupportsgt

ltmime-typegttexthtmlltmime-typegt

ltportlet-modegtviewltportlet-modegt

- 16 -

ltportlet-modegteditltportlet-modegt

ltsupportsgt

ltsupported-localegtENltsupported-localegt

ltportlet-infogt

lttitlegtMy Bookmarks7lttitlegt

ltshort-titlegtBookmarks7ltshort-titlegt

ltkeywordsgtbookmarksltkeywordsgt

ltportlet-infogt

ltportlet-preferencesgt

ltpreferencegt

ltnamegturl1ltnamegt

ltvaluegthttpwwwgooglecomltvaluegt

ltpreferencegt

ltportlet-preferencesgt

ltportletgt

ltportlet-appgt

Here the initialization parameters are directly specified in the portletxml as portlets are independent components in the JSR 168 The following example represents the webxml for the JSR 168 bookmark portlet

JSR 168 WEBXML EXAMPLE

ltxml version=10 encoding=UTF-8gt

ltDOCTYPE web-app PUBLIC -Sun Microsystems IncDTD Web Application 23EN

httpjavasuncomdtdweb-app_2_3dtdgt

ltweb-appgt

ltdisplay-namegtBookmark Application7ltdisplay-namegt

ltweb-appgt

The only item that needs to be specified in the JSR 168 webxml 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 portletxml as portlet application name as there can be several concrete instances of the same abstract application

- 17 -

332 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 331) 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 331) 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

333 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

334 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 instanceentity 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 -

335 Portlet API does not extend servlet API

In the IBM Portlet API portlets extend servlets and all the major interfaces (Request Response Session hellip) 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

336 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

bull defineObjects tag ndash to define the basic portlet API objects RenderRequest RenderResponse and PortletConfig

bull actionURL tag ndash to create an action URL bull renderURL tag ndash to create a render URL bull namespace tag ndash 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 donrsquot need decoding

34 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 -

341 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 (eg 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

342 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

3421 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

3422 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 322) 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

3423 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

3424 Request Response properties

Properties can be used by the portalportlet container to send vendor specific information to the portlet andor the portlet can send vendor specific information to the portalportlet-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

343 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 (eg between portlets or between a portlet and a servlet)

344 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 23 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

345 J2EE role support

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

346 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 -

347 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 PortletRequestgetResponseContentTypes 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 (eg ldquotextrdquo or ldquordquo) 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

348 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 (eg an accounting servlet) in response to an action

349 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

3410 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 vendorrsquos 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)

3411 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 xmllang attribute like the

- 22 -

servlet 24 deployment descriptor Thus the same tag with descriptions in different languages can be used (eg 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

35 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)

351 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

bull ActionEventThe action event maps to the action phase call in the JSR 168

bull MessageEventMessage 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)

bull PortletApplicationSettingsAttributeEventPortletSettingsAttributeEventThese are events that get fired when attributes for the application or of the portlet settings change

bull WindowEventThe portlet will register for window events to get notified if the portlet window is changed via the window decorations

352 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 -

bull PortletPageListener The page listeners provides the portlet with events for the beginning of the page before any markup is written for this page (eg to write JavaScript at the beginning of the page) and the end of the page after all markup is written

bull 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 23 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

bull EventPhaseListener The event phase listener notifies the portlet of the beginning and end of the eventaction phase

353 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

354 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 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

Figure 4

- 24 -

Figure 4 Portlet menu example

355 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

356 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 -

36 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 indicates portlet in what mode to operate for a given request

View edit help + custom modes

view edit help + custom modes

full alignment

Window State the state of the window in which the portlet output will be displayed

minimized normal maximized solo +

custom window states

minimized normal maximized +

custom window states

full alignment (ldquosolordquo is missing in the JSR but can be implemented as a custom state)

URL encoding to allow re-writing URLs created by the portlet

defines how to create URLs to allow re-writing of the URLs either on consumer or producer side

encapsulates URL creation via a Java object

full alignment (the implementation of the Java object can implement the WSRP URL rewriting rules)

Namespace encoding to avoid that several portlets on a page conflicting with each other

defines namespace prefixes for consumer and producer side namespacing

provides a Java method to namespace a String

full alignment (the JSR namespace method can implement the WSRP namespace behavior)

User ndash portlet interaction operations

performBlockingInteraction blocking action processing

getMarkup render the markup

action blocking action processing

render render the makup

full alignment (action invocations carried through performBlockingInteraction render carried through getMarkup)

View state that allows the current portlet fragment to be correctly displayed in sub-sequent render calls

navigational state render parameter full alignment (WSRP navigational state maps to JSR render parameters)

Storing transient state across request

session state concept implemented via a sessionID

utilizes the Http web application session

full alignment (the WSRP sessionID can be used to reference the JSR session)

Storing persistent state to personalize the rendering of the portlet

allows to have properties of arbitrary types

provides String-based preferences

full alignment (JSR String preferences can be mapped to WSRP properties)

Information about the portal calling the portlet

RegistrationData provide information of the consumer to the producer

PortalContext provide a Java interface to access information about the portal calling the portlet

full alignment (all data represented through the PortalContext to the JSR portlet are available in the RegistrationData)

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

Aggregated HTML WML VoiceXML

over HTTPMark-Up Fragments

Transferred via WSRP

Portal

WSRP Service

WSRP Service

WSRP Service

WSRP Consumer WSRP Producer

Use of WSRP Services in Portals

Portal sharing Portlets as WSRP Services

ServerPortalPortals

Huge numberof users Publishing Portal

WSRPWrapperPortalsPortalsPortal

Portlet

Portlet

Portlet

WSRP Consumer WSRP Producer

ProxyPortlet

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

bull 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

bull 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

bull 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

bull 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 CCPP standard allowing a portlet to query the client capabilities and adopting its markup accordingly (eg screen size browser) This API is likely to be included in the next version of the portlet API Also J2EE 14 was finalized during this time period J2EE 14 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 14

bull caching The first version of the JSR 168 API is limited to expiration-based caching (see section 327) 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

bull 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

51 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

511 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

bull portlets are components Portlets are components that implement a specific function Different functions should be distributed to different portlets

bull 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

bull 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

512 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 HttpServletRequestgetSession() call in the JSPs called via the IBM Portlet API needs to be replaced when moving to JSR 168 portlets by the RenderRequestgetPortletSession() 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 HttpServletRequestgetSession() will get the HttpSession and therefore need to access the portlet session via the RenderRequest

513 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

514 Persistent data

Portlets can store customization and personalization data persistently Customization data are related to the portlet and are valid for all users (eg 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 (eg 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

515 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

516 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

52 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

521 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 351 353) 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

522 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

53 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 -

531 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

bull no support of the back button in the browser bull current state of the portlet is not bookmarkable bull 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 bull 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

54 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

541 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 -

542 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

543 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

544 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 wersquoll 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

Figure 7After clicking on the Edit mode button the portlet renders the Edit view shown in

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

Figure 8

After we press the ldquoAddrdquo 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

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

bull use JSPs for rendering the output bull customize the portlet output taking user specific data into account bull 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

61 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 comibmwpssampleswp5

import javaio

import javautil

import orgapachejetspeedportlet

import orgapachejetspeedportletevent

public class IbmBookmark extends PortletAdapter implements ActionListener

public void init(PortletConfig portletConfig) throws UnavailableException

superinit(portletConfig)

- 36 -

public void doView(PortletRequest request PortletResponse response)

throws PortletException IOException

String jspName = thisgetPortletConfig()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 = responsecreateReturnURI()

addURIaddAction(add)

requestsetAttribute(addURI addURItoString())

PortletURI cancelURI = responsecreateReturnURI()

requestsetAttribute(cancelURI cancelURItoString())

String jspName = thisgetPortletConfig()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 ldquocancelrdquo and ldquoaddrdquo URLs are created inside the portlet and attached to the request before including the Edit JSP Both URLs are from type ldquoReturnURIrdquo 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 = eventgetRequest()

String action = eventgetActionString()

PortletLog log = getPortletLog()

if ( action=null )

try

if (actionequals(removeURI))

String removeName = requestgetParameter(remove)

PortletData portData = requestgetData()

portDataremoveAttribute(removeName)

portDatastore()

if (actionequals(add))

PortletData portData = requestgetData()

String name = requestgetParameter(name)

String value = requestgetParameter(value)

portDatasetAttribute(name value)

portDatastore()

catch ( AccessDeniedException ade )

logerror(AccessDeniedException occured when adding or deleting a bookmark)

catch ( IOException ioe )

logerror(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 ldquoaddrdquo or ldquodeleterdquo 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 ldquoaddrdquo or ldquoremoveURIrdquo If the user has clicked on the ldquoremoverdquo button the corresponding link is removed from the portlet data whereas if ldquoaddrdquo was clicked the data entered by the user is added to the portlet data

62 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 comibmwpssamplesjsr

import javaio

import javaxportlet

public class Bookmark extends GenericPortlet

public void init(PortletConfig config) throws PortletException

superinit(config)

public void doView(RenderRequest request RenderResponse response)

throws PortletException IOException

responsesetContentType(texthtml)

String jspName = getPortletConfig()getInitParameter(jspView)

PortletRequestDispatcher rd = getPortletContext()getRequestDispatcher(jspName)

rdinclude(requestresponse)

- 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

responsesetContentType(texthtml)

PortletURL addUrl = responsecreateActionURL()

addUrlsetPortletMode(PortletModeVIEW)

addUrlsetParameter(addadd)

requestsetAttribute(addUrladdUrltoString())

PortletURL cancelUrl = responsecreateRenderURL()

cancelUrlsetPortletMode(PortletModeVIEW)

requestsetAttribute(cancelUrlcancelUrltoString())

String jspName = getPortletConfig()getInitParameter(jspEdit)

PortletRequestDispatcher rd = getPortletContext()getRequestDispatcher(jspName)

rdinclude(requestresponse)

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 ldquoaddrdquo button URL an action URL is created as we need to store the user input of the add form persistently For the ldquocancelrdquo 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 = requestgetParameter(remove)

if (removeName = null)

PortletPreferences prefs = requestgetPreferences()

prefsreset(removeName)

prefsstore()

String add = requestgetParameter(add)

if (add = null)

PortletPreferences prefs = requestgetPreferences()

String name = requestgetParameter(name)

String value = requestgetParameter(value)

prefssetValue(name value)

prefsstore()

catch ( IOException ioe )

getPortletContextlog(An IO error occured when trying to remove a bookmark)

catch ( PortletException pe )

getPortletContextlog(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

bull 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

bull 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

bull Persistent portlet data The JSR 168 persistent data PortletPreferences have an API similar to the JDK 14 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

bull 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

63 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

lt page contentType=texthtml import=javautil comibmwpssampleswp5

orgapachejetspeedportlet session=falsegt

lt taglib uri=WEB-INFtldportlettld prefix=portletAPI gt

- 42 -

ltportletAPIinitgt

ltp class=wpsPortletHeadgtltportletAPItext key=available_bookmarks

bundle=nlsTextgtAvailable BookmarksltportletAPItextgtltpgt

lt

PortletData prefs = portletRequestgetData()

Enumeration e = prefsgetAttributeNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltportletAPItext key=no_bookmarks bundle=nlsTextgtNo

bookmarksltportletAPItextgtltpgt

lt

else

gt

ltp class=wpsIndentMediumgt

lt

while (ehasMoreElements())

String name = (String)enextElement()

String value = (String)prefsgetAttribute(name)

gt

lta href=lt=valuegt target=_blankgtlt=namegtltagtltbr gt

lt

gt

ltpgt

The View JSP first call portletAPIinit 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

lt page contentType=texthtml import=javautil

comibmwpssampleswp5orgapachejetspeedportlet session=falsegt

lt taglib uri=WEB-INFtldportlettld prefix=portletAPI gt

ltjspuseBean id=addURI class=javalangString scope=request gt

ltjspuseBean id=cancelURI class=javalangString scope=request gt

ltportletAPIinitgt

lth4gtltportletAPItext key=available_bookmarks bundle=nlsTextgtAvailable

BookmarksltportletAPItextgtlth4gt

lttable class=wpsTablegt

lttr class=wpsTableRowgt

ltth class=portlet-table-headergtltportletAPItext key=name bundle=nlsTextgtltthgt

ltth class=portlet-table-headergtltportletAPItext key=url bundle=nlsTextgtltthgt

lttdgtlttdgt

lttrgt

lt

PortletData prefs = portletRequestgetData()

Enumeration e = prefsgetAttributeNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltportletAPItext key=no_bookmarks bundle=nlsTextgtNo

bookmarksltportletAPItextgtltpgt

lt

else

while (ehasMoreElements())

- 44 -

String name = (String)enextElement()

String value = (String)prefsgetAttribute(name)

gt

lttr class=wpsTableRowgt

lttdgt lt=namegt lttdgt

lttdgt lt=valuegt lttdgt

lttdgt lta href=ltportletAPIcreateURIgtltportletAPIURIAction

name=removeURIgtltportletAPIURIParameter name=remove

value=lt=namegtgtltportletAPIcreateURIgtgt

(ltportletAPItext key=delete bundle=nlsTextgt)ltagt

lttdgt

lttrgt

lt

gt

ltform action=lt=addURIgt method=POSTgt

lttr class=wpsTableRowgt

lttdgtltinput name=ltportletAPIencodeNamespace value=namegt type=text

class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=ltportletAPIencodeNamespace value=valuegt type=text

class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=ltportletAPIencodeNamespace value=addgt type=submit

value=ltportletAPItext key=add bundle=nlsTextgt class=portlet-form-buttongtlttdgt

lttrgt

ltformgt

lttablegt

- 45 -

ltform action=lt=cancelURIgt method=postgt

ltinput name=ltportletAPIencodeNamespace value=cancelgt type=submit

value=ltportletAPItext key=cancel bundle=nlsTextgt class=portlet-form-buttongt

ltformgt

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 ldquodeleterdquo button for which an URL with the action ldquoremoveURIrdquo 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 ldquocancelrdquo button from the request

64 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

lt page import=javaxportlet javautil session=falsegt

lt taglib uri=httpjavasuncomportlet prefix=portletAPI gt

lt taglib prefix=fmt uri=httpjavasuncomjstlfmt gt

ltportletAPIdefineObjects gt

ltfmtsetBundle basename=nlsTextgt

lt

ResourceBundle myText = ResourceBundlegetBundle(nlsText requestgetLocale())

gt

lth4gtltfmtmessage key=available_bookmarksgtlth4gt

lt

PortletPreferences prefs = renderRequestgetPreferences()

Enumeration e = prefsgetNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltfmtmessage key=no_bookmarksgtltpgt

- 46 -

lt

else

gt

ltpgt

lt

while (ehasMoreElements())

String name = (String)enextElement()

String value = prefsgetValue(namelt+myTextgetString(undefined)+gt)

gt

lta href=lt=valuegt target=_blankgtlt=namegtltagtltbr gt

lt

gt

ltpgt

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 fmtmessage 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

lt page import=javaxportlet javautil session=false gt

lt taglib uri=httpjavasuncomportlet prefix=portletAPI gt

lt taglib prefix=fmt uri=httpjavasuncomjstlfmt gt

ltjspuseBean id=addUrl scope=request class=javalangString gt

ltjspuseBean id=cancelUrl scope=request class=javalangString gt

- 47 -

ltportletAPIdefineObjectsgt

lt

ResourceBundle myText = ResourceBundlegetBundle(nlsText requestgetLocale())

gt

ltfmtsetBundle basename=nlsTextgt

lth4gtltfmtmessage key=available_bookmarksgtlth4gt

lttable class=wpsTablegt

lttr class=wpsTableRowgt

ltth class=wpsTableHeadgtltfmtmessage key=namegtltthgt

ltth class=wpsTableHeadgtltfmtmessage key=urlgtltthgt

lttdgtlttdgt

lttrgt

lt

PortletPreferences prefs = renderRequestgetPreferences()

Enumeration e = prefsgetNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltfmtmessage key=no_bookmarksgtltpgt

lt

else

while (ehasMoreElements())

String name = (String)enextElement()

String value = prefsgetValue(namelt+myTextgetString(undefined)+gt)

gt

lttr class=wpsTableRowgt

lttdgt lt=namegt lttdgt

lttdgt lt=valuegt lttdgt

- 48 -

lttdgt ltportletAPIactionURL var=removeUrlgt

ltportletAPIparam name=remove value=lt=namegtgt

ltportletAPIactionURLgt

lta href=lt=removeUrltoString()gtgt(ltfmtmessage key=deletegt)ltagt

lttdgt

lttrgt

lt

gt

ltform action=lt=addUrlgt method=POSTgt

lttr class=wpsTableRowgt

lttdgtltinput name=name type=text class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=value type=text class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=add type=submit value=ltfmtmessage key=addgt

class=portlet-form-buttongtlttdgt

lttrgt

ltformgt

lttablegt

ltform action=lt=cancelUrlgt method=postgt

ltinput name=cancel type=submit value=ltfmtmessage key=cancelgt class=portlet-

form-buttongt

ltformgt

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 14 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 -

- 51 -

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 (eg eventing) the IBM Portlet API still needs to be used Trademarks bull IBM and WebSphere are trademarks or registered trademarks of IBM Corporation in

the United States other countries or both bull 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 bull Other company product and service names may be trademarks or service marks of

others IBM copyright and trademark information httpwwwibmcomlegalcopytradephtml

  • Introduction
  • JSR 168 and the Java Community Process
  • Comparing concepts
    • Basic concepts
      • Portal
      • Portal page
      • Portlet
      • Portlet Container
        • Concepts that are the same
          • Portlet mode
          • Window state
          • Portlet life cycle and request processing
          • URL encoding
          • Include servletsJSPs
          • Portlet application packaging
          • Expiration-based caching
            • Concepts that differ
              • Portlet application entity
              • Portlet entity
              • Action and Render Request Response objects
              • Window concept
              • Portlet API does not extend servlet API
              • TAG libraries
                • Concepts new in the JSR 168
                  • Render parameter
                  • Extension mechanisms
                    • Custom window states
                    • Custom portlet modes
                    • Custom user info
                    • Request Response properties
                      • Web application session scope
                      • Reuse of the HttpSession listeners
                      • J2EE role support
                      • Resource bundles
                      • Multiple response content types
                      • Redirect in action
                      • Preference validator
                      • Portal context
                      • Localization support
                        • Concepts missing in the JSR 168
                          • Eventing
                          • Additional lifecycle events
                          • Property broker
                          • Portlet Menus
                          • Portlet Services
                          • Invalidation-based caching
                            • Alignment with WSRP
                              • Outlook for the next version of the JSR 168
                              • Guidelines for programming IBM Portlet API portlets
                                • Similar Functionality
                                  • Basic programming model
                                  • Portlet private session
                                  • User profile information
                                  • Persistent data
                                  • Portlet modes and window states
                                  • Expiration-based caching
                                    • Slightly different functionality
                                      • Sharing of data between portlets
                                      • Session listeners
                                        • New JSR 168 functionality
                                          • Navigational state (render parameters)
                                            • Pitfalls
                                              • Request response objects for action and render phase
                                              • Include search path
                                              • Form parameter encoding
                                              • Title setting
                                                  • Examples
                                                    • IBM Portlet API Portlet Code
                                                    • JSR 168 Portlet Code
                                                    • IBM Portlet API JSPs
                                                    • JSR 168 JSPs
                                                      • Summary
Page 9: Difference Bw Jsr168 and Ibm

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

bull Edit ndash to display one or more personalization views that let the user personalize portlet settings

bull Help ndash to display help views bull View ndash to display the portlet output bull Configure ndash 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

bull required to support (same semantic as above) o Edit o Help o View

bull optional custom modes o About ndash to display information on the portlets purpose origin version etc o Config ndash has the same semantic as the IBM Portlet API configure mode o Edit_defaults ndash to set the default values for the modifiable preferences that

are typically changed in the EDIT screen o Preview ndash to render output without the need of having back-end

connections or user specific data available o Print ndash to display a view that is suitable for printing

bull portal vendor specific modes that are available only in a portal of a specific vendor

322 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

bull Closed (deprecated) ndash to indicate that a window should be closed bull Detached (deprecated) ndash to indicate that a window should be detached bull Maximized ndash to indicate that a window has more real estate to render its output

then in normal window state

- 9 -

bull Minimized ndash to indicate that the portlet is minimized and cannot render any output

bull Moving (deprecated) ndash to indicate that the portlet window has been moved bull Normal ndash to indicate that the portlet is sharing its screen with other portlets on a

page bull Resizing (deprecated) ndash to indicate that the portlet has been resized bull Solo ndash to indicate that the portlet is the only portlet on the page

Whereas the JSR 168 has only the following mandatory window states

bull Maximized ndash same as in the IBM Portlet API bull Minimized ndash to indicate that the portlet should only render minimal or no output bull Normal ndash same as in the IBM Portlet API

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

323 Portlet life cycle and request processing

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

bull init ndash to initialize the portlet and put the portlet into service bull handle requests ndash process different kinds of action and render requests bull destroy ndash 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

324 URL encoding

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

bull 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

bull 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

325 Include servletsJSPs

In both APIrsquos 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()

contextinclude(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)

rdinclude(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 HttpServetRequestgetSession() 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

326 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 (webxml) and one to specify the portlet resources (portletxml) All web resources that are not portlets must be specified in the webxml deployment descriptor All portlets and portlet related settings must be specified in an additional file called portletxml

- 12 -

Different from JSR 168 in the IBM Portlet API all portlets must also be listed in the webxml as they are also servlets (see also 335 for examples of the deployment descitptors)

327 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

33 Concepts that differ

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

331 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 webxml and concrete portlet applications of concrete portlets based on the abstract ones The following portletxml example shows these two different parts

IBM PORTLET API PORTLETXML EXAMPLE

ltxml version=10 encoding=UTF-8gt

ltDOCTYPE portlet-app-def PUBLIC -IBMDTD Portlet Application 11EN

portlet_11dtdgt

ltportlet-app-defgt

ltportlet-app uid=commycobookmark1234 major-version=7 minor-version=24gt

ltportlet-app-namegtBookmark Application7ltportlet-app-namegt

ltportlet id=Portlet_1 href=WEB-INFwebxmlServlet_1gt

- 13 -

ltportlet-namegtBookmark Portlet7ltportlet-namegt

ltallowsgt

ltmaximizedgt

ltminimizedgt

ltallowsgt

ltsupportsgt

ltmarkup name=htmlgt

ltview output=fragmentgt

ltedit output=fragmentgt

ltmarkupgt

ltsupportsgt

ltportletgt

ltportlet-appgt

ltconcrete-portlet-app uid=commycobookmark12341gt

ltportlet-app-namegtConcreteSamplets_Bookmark7ltportlet-app-namegt

ltconcrete-portlet href=Portlet_1gt

ltportlet-namegtBookmark Portlet7ltportlet-namegt

ltdefault-localegtenltdefault-localegt

ltlanguage locale=engt

lttitlegtMy Bookmarks7lttitlegt

lttitle-shortgtBookmarks7lttitle-shortgt

ltdescriptiongtPortlet showing your personalized bookmarksltdescriptiongt

ltkeywordsgtbookmarksltkeywordsgt

ltlanguagegt

ltconfig-paramgt

ltparam-namegturl1ltparam-namegt

ltparam-valuegthttpwwwgooglecomltparam-valuegt

ltconfig-paramgt

ltconcrete-portletgt

- 14 -

ltconcrete-portlet-appgt

ltportlet-app-defgt

As portlets are servlets in the IBM Portlet API the portletxml has references for each portlet to the servlet in the webxml that represents the portlet The webxml for this example is

IBM PORTLET API WEBXML EXAMPLE

ltxml version=10 encoding=UTF-8gt

ltDOCTYPE web-app

PUBLIC -Sun Microsystems IncDTD Web Application 22EN

httpjavasuncomj2eedtdsweb-app_22dtdgt

ltweb-app id=WebApp_1gt

ltdisplay-namegtbookmark7ltdisplay-namegt

ltservlet id=Servlet_1gt

ltservlet-namegtBookmark7ltservlet-namegt

ltservlet-classgtcommycobookmarkBookmarkPortletltservlet-classgt

ltinit-paramgt

ltparam-namegtjspviewltparam-namegt

ltparam-valuegtbookmarkViewjspltparam-valuegt

ltinit-paramgt

ltinit-paramgt

ltparam-namegtjspeditltparam-namegt

ltparam-valuegtbookmarkEditjspltparam-valuegt

ltinit-paramgt

ltservletgt

ltservlet-mappinggt

ltservlet-namegtBookmark7ltservlet-namegt

lturl-patterngtBookmark7lturl-patterngt

ltservlet-mappinggt

ltweb-appgt

- 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 webxml and not in the portletxml In the JSR 168 the deployment descriptor is more like the webxml 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 portletxml example would look like when using the JSR 168 deployment descriptor format

JSR 168 PORTLETXML EXAMPLE

ltxml version=10 encoding=UTF-8gt

ltxml version=10encoding=UTF-8gt

ltportlet-app xmlns=httpjavasuncomxmlnsportletportlet-app_1_0xsd version=10

xmlnsxsi=httpwwww3org2001XMLSchema-instance

xsischemaLocation=httpjavasuncomxmlnsportlet-app_1_0xsd

httpjavasuncomxmlnsportletportlet-app_1_0xsdgt

ltportletgt

ltdescription xmllang=ENgtPortlet showing your personalized

bookmarksltdescriptiongt

ltportlet-namegtBookmark Portlet7ltportlet-namegt

ltdisplay-name xmllang=ENgtBookmark Portletltdisplay-namegt

ltportlet-classgtcommycobookmarkBookmarkPortletltportlet-classgt

ltinit-paramgt

ltnamegtjspviewltnamegt

ltvaluegtbookmarkViewjspltvaluegt

ltinit-paramgt

ltinit-paramgt

ltnamegtjspeditltnamegt

ltvaluegtbookmarkEditjspltvaluegt

ltinit-paramgt

ltsupportsgt

ltmime-typegttexthtmlltmime-typegt

ltportlet-modegtviewltportlet-modegt

- 16 -

ltportlet-modegteditltportlet-modegt

ltsupportsgt

ltsupported-localegtENltsupported-localegt

ltportlet-infogt

lttitlegtMy Bookmarks7lttitlegt

ltshort-titlegtBookmarks7ltshort-titlegt

ltkeywordsgtbookmarksltkeywordsgt

ltportlet-infogt

ltportlet-preferencesgt

ltpreferencegt

ltnamegturl1ltnamegt

ltvaluegthttpwwwgooglecomltvaluegt

ltpreferencegt

ltportlet-preferencesgt

ltportletgt

ltportlet-appgt

Here the initialization parameters are directly specified in the portletxml as portlets are independent components in the JSR 168 The following example represents the webxml for the JSR 168 bookmark portlet

JSR 168 WEBXML EXAMPLE

ltxml version=10 encoding=UTF-8gt

ltDOCTYPE web-app PUBLIC -Sun Microsystems IncDTD Web Application 23EN

httpjavasuncomdtdweb-app_2_3dtdgt

ltweb-appgt

ltdisplay-namegtBookmark Application7ltdisplay-namegt

ltweb-appgt

The only item that needs to be specified in the JSR 168 webxml 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 portletxml as portlet application name as there can be several concrete instances of the same abstract application

- 17 -

332 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 331) 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 331) 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

333 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

334 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 instanceentity 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 -

335 Portlet API does not extend servlet API

In the IBM Portlet API portlets extend servlets and all the major interfaces (Request Response Session hellip) 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

336 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

bull defineObjects tag ndash to define the basic portlet API objects RenderRequest RenderResponse and PortletConfig

bull actionURL tag ndash to create an action URL bull renderURL tag ndash to create a render URL bull namespace tag ndash 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 donrsquot need decoding

34 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 -

341 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 (eg 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

342 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

3421 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

3422 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 322) 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

3423 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

3424 Request Response properties

Properties can be used by the portalportlet container to send vendor specific information to the portlet andor the portlet can send vendor specific information to the portalportlet-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

343 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 (eg between portlets or between a portlet and a servlet)

344 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 23 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

345 J2EE role support

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

346 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 -

347 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 PortletRequestgetResponseContentTypes 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 (eg ldquotextrdquo or ldquordquo) 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

348 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 (eg an accounting servlet) in response to an action

349 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

3410 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 vendorrsquos 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)

3411 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 xmllang attribute like the

- 22 -

servlet 24 deployment descriptor Thus the same tag with descriptions in different languages can be used (eg 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

35 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)

351 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

bull ActionEventThe action event maps to the action phase call in the JSR 168

bull MessageEventMessage 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)

bull PortletApplicationSettingsAttributeEventPortletSettingsAttributeEventThese are events that get fired when attributes for the application or of the portlet settings change

bull WindowEventThe portlet will register for window events to get notified if the portlet window is changed via the window decorations

352 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 -

bull PortletPageListener The page listeners provides the portlet with events for the beginning of the page before any markup is written for this page (eg to write JavaScript at the beginning of the page) and the end of the page after all markup is written

bull 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 23 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

bull EventPhaseListener The event phase listener notifies the portlet of the beginning and end of the eventaction phase

353 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

354 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 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

Figure 4

- 24 -

Figure 4 Portlet menu example

355 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

356 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 -

36 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 indicates portlet in what mode to operate for a given request

View edit help + custom modes

view edit help + custom modes

full alignment

Window State the state of the window in which the portlet output will be displayed

minimized normal maximized solo +

custom window states

minimized normal maximized +

custom window states

full alignment (ldquosolordquo is missing in the JSR but can be implemented as a custom state)

URL encoding to allow re-writing URLs created by the portlet

defines how to create URLs to allow re-writing of the URLs either on consumer or producer side

encapsulates URL creation via a Java object

full alignment (the implementation of the Java object can implement the WSRP URL rewriting rules)

Namespace encoding to avoid that several portlets on a page conflicting with each other

defines namespace prefixes for consumer and producer side namespacing

provides a Java method to namespace a String

full alignment (the JSR namespace method can implement the WSRP namespace behavior)

User ndash portlet interaction operations

performBlockingInteraction blocking action processing

getMarkup render the markup

action blocking action processing

render render the makup

full alignment (action invocations carried through performBlockingInteraction render carried through getMarkup)

View state that allows the current portlet fragment to be correctly displayed in sub-sequent render calls

navigational state render parameter full alignment (WSRP navigational state maps to JSR render parameters)

Storing transient state across request

session state concept implemented via a sessionID

utilizes the Http web application session

full alignment (the WSRP sessionID can be used to reference the JSR session)

Storing persistent state to personalize the rendering of the portlet

allows to have properties of arbitrary types

provides String-based preferences

full alignment (JSR String preferences can be mapped to WSRP properties)

Information about the portal calling the portlet

RegistrationData provide information of the consumer to the producer

PortalContext provide a Java interface to access information about the portal calling the portlet

full alignment (all data represented through the PortalContext to the JSR portlet are available in the RegistrationData)

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

Aggregated HTML WML VoiceXML

over HTTPMark-Up Fragments

Transferred via WSRP

Portal

WSRP Service

WSRP Service

WSRP Service

WSRP Consumer WSRP Producer

Use of WSRP Services in Portals

Portal sharing Portlets as WSRP Services

ServerPortalPortals

Huge numberof users Publishing Portal

WSRPWrapperPortalsPortalsPortal

Portlet

Portlet

Portlet

WSRP Consumer WSRP Producer

ProxyPortlet

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

bull 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

bull 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

bull 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

bull 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 CCPP standard allowing a portlet to query the client capabilities and adopting its markup accordingly (eg screen size browser) This API is likely to be included in the next version of the portlet API Also J2EE 14 was finalized during this time period J2EE 14 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 14

bull caching The first version of the JSR 168 API is limited to expiration-based caching (see section 327) 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

bull 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

51 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

511 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

bull portlets are components Portlets are components that implement a specific function Different functions should be distributed to different portlets

bull 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

bull 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

512 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 HttpServletRequestgetSession() call in the JSPs called via the IBM Portlet API needs to be replaced when moving to JSR 168 portlets by the RenderRequestgetPortletSession() 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 HttpServletRequestgetSession() will get the HttpSession and therefore need to access the portlet session via the RenderRequest

513 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

514 Persistent data

Portlets can store customization and personalization data persistently Customization data are related to the portlet and are valid for all users (eg 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 (eg 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

515 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

516 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

52 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

521 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 351 353) 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

522 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

53 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 -

531 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

bull no support of the back button in the browser bull current state of the portlet is not bookmarkable bull 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 bull 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

54 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

541 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 -

542 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

543 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

544 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 wersquoll 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

Figure 7After clicking on the Edit mode button the portlet renders the Edit view shown in

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

Figure 8

After we press the ldquoAddrdquo 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

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

bull use JSPs for rendering the output bull customize the portlet output taking user specific data into account bull 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

61 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 comibmwpssampleswp5

import javaio

import javautil

import orgapachejetspeedportlet

import orgapachejetspeedportletevent

public class IbmBookmark extends PortletAdapter implements ActionListener

public void init(PortletConfig portletConfig) throws UnavailableException

superinit(portletConfig)

- 36 -

public void doView(PortletRequest request PortletResponse response)

throws PortletException IOException

String jspName = thisgetPortletConfig()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 = responsecreateReturnURI()

addURIaddAction(add)

requestsetAttribute(addURI addURItoString())

PortletURI cancelURI = responsecreateReturnURI()

requestsetAttribute(cancelURI cancelURItoString())

String jspName = thisgetPortletConfig()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 ldquocancelrdquo and ldquoaddrdquo URLs are created inside the portlet and attached to the request before including the Edit JSP Both URLs are from type ldquoReturnURIrdquo 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 = eventgetRequest()

String action = eventgetActionString()

PortletLog log = getPortletLog()

if ( action=null )

try

if (actionequals(removeURI))

String removeName = requestgetParameter(remove)

PortletData portData = requestgetData()

portDataremoveAttribute(removeName)

portDatastore()

if (actionequals(add))

PortletData portData = requestgetData()

String name = requestgetParameter(name)

String value = requestgetParameter(value)

portDatasetAttribute(name value)

portDatastore()

catch ( AccessDeniedException ade )

logerror(AccessDeniedException occured when adding or deleting a bookmark)

catch ( IOException ioe )

logerror(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 ldquoaddrdquo or ldquodeleterdquo 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 ldquoaddrdquo or ldquoremoveURIrdquo If the user has clicked on the ldquoremoverdquo button the corresponding link is removed from the portlet data whereas if ldquoaddrdquo was clicked the data entered by the user is added to the portlet data

62 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 comibmwpssamplesjsr

import javaio

import javaxportlet

public class Bookmark extends GenericPortlet

public void init(PortletConfig config) throws PortletException

superinit(config)

public void doView(RenderRequest request RenderResponse response)

throws PortletException IOException

responsesetContentType(texthtml)

String jspName = getPortletConfig()getInitParameter(jspView)

PortletRequestDispatcher rd = getPortletContext()getRequestDispatcher(jspName)

rdinclude(requestresponse)

- 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

responsesetContentType(texthtml)

PortletURL addUrl = responsecreateActionURL()

addUrlsetPortletMode(PortletModeVIEW)

addUrlsetParameter(addadd)

requestsetAttribute(addUrladdUrltoString())

PortletURL cancelUrl = responsecreateRenderURL()

cancelUrlsetPortletMode(PortletModeVIEW)

requestsetAttribute(cancelUrlcancelUrltoString())

String jspName = getPortletConfig()getInitParameter(jspEdit)

PortletRequestDispatcher rd = getPortletContext()getRequestDispatcher(jspName)

rdinclude(requestresponse)

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 ldquoaddrdquo button URL an action URL is created as we need to store the user input of the add form persistently For the ldquocancelrdquo 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 = requestgetParameter(remove)

if (removeName = null)

PortletPreferences prefs = requestgetPreferences()

prefsreset(removeName)

prefsstore()

String add = requestgetParameter(add)

if (add = null)

PortletPreferences prefs = requestgetPreferences()

String name = requestgetParameter(name)

String value = requestgetParameter(value)

prefssetValue(name value)

prefsstore()

catch ( IOException ioe )

getPortletContextlog(An IO error occured when trying to remove a bookmark)

catch ( PortletException pe )

getPortletContextlog(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

bull 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

bull 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

bull Persistent portlet data The JSR 168 persistent data PortletPreferences have an API similar to the JDK 14 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

bull 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

63 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

lt page contentType=texthtml import=javautil comibmwpssampleswp5

orgapachejetspeedportlet session=falsegt

lt taglib uri=WEB-INFtldportlettld prefix=portletAPI gt

- 42 -

ltportletAPIinitgt

ltp class=wpsPortletHeadgtltportletAPItext key=available_bookmarks

bundle=nlsTextgtAvailable BookmarksltportletAPItextgtltpgt

lt

PortletData prefs = portletRequestgetData()

Enumeration e = prefsgetAttributeNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltportletAPItext key=no_bookmarks bundle=nlsTextgtNo

bookmarksltportletAPItextgtltpgt

lt

else

gt

ltp class=wpsIndentMediumgt

lt

while (ehasMoreElements())

String name = (String)enextElement()

String value = (String)prefsgetAttribute(name)

gt

lta href=lt=valuegt target=_blankgtlt=namegtltagtltbr gt

lt

gt

ltpgt

The View JSP first call portletAPIinit 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

lt page contentType=texthtml import=javautil

comibmwpssampleswp5orgapachejetspeedportlet session=falsegt

lt taglib uri=WEB-INFtldportlettld prefix=portletAPI gt

ltjspuseBean id=addURI class=javalangString scope=request gt

ltjspuseBean id=cancelURI class=javalangString scope=request gt

ltportletAPIinitgt

lth4gtltportletAPItext key=available_bookmarks bundle=nlsTextgtAvailable

BookmarksltportletAPItextgtlth4gt

lttable class=wpsTablegt

lttr class=wpsTableRowgt

ltth class=portlet-table-headergtltportletAPItext key=name bundle=nlsTextgtltthgt

ltth class=portlet-table-headergtltportletAPItext key=url bundle=nlsTextgtltthgt

lttdgtlttdgt

lttrgt

lt

PortletData prefs = portletRequestgetData()

Enumeration e = prefsgetAttributeNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltportletAPItext key=no_bookmarks bundle=nlsTextgtNo

bookmarksltportletAPItextgtltpgt

lt

else

while (ehasMoreElements())

- 44 -

String name = (String)enextElement()

String value = (String)prefsgetAttribute(name)

gt

lttr class=wpsTableRowgt

lttdgt lt=namegt lttdgt

lttdgt lt=valuegt lttdgt

lttdgt lta href=ltportletAPIcreateURIgtltportletAPIURIAction

name=removeURIgtltportletAPIURIParameter name=remove

value=lt=namegtgtltportletAPIcreateURIgtgt

(ltportletAPItext key=delete bundle=nlsTextgt)ltagt

lttdgt

lttrgt

lt

gt

ltform action=lt=addURIgt method=POSTgt

lttr class=wpsTableRowgt

lttdgtltinput name=ltportletAPIencodeNamespace value=namegt type=text

class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=ltportletAPIencodeNamespace value=valuegt type=text

class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=ltportletAPIencodeNamespace value=addgt type=submit

value=ltportletAPItext key=add bundle=nlsTextgt class=portlet-form-buttongtlttdgt

lttrgt

ltformgt

lttablegt

- 45 -

ltform action=lt=cancelURIgt method=postgt

ltinput name=ltportletAPIencodeNamespace value=cancelgt type=submit

value=ltportletAPItext key=cancel bundle=nlsTextgt class=portlet-form-buttongt

ltformgt

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 ldquodeleterdquo button for which an URL with the action ldquoremoveURIrdquo 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 ldquocancelrdquo button from the request

64 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

lt page import=javaxportlet javautil session=falsegt

lt taglib uri=httpjavasuncomportlet prefix=portletAPI gt

lt taglib prefix=fmt uri=httpjavasuncomjstlfmt gt

ltportletAPIdefineObjects gt

ltfmtsetBundle basename=nlsTextgt

lt

ResourceBundle myText = ResourceBundlegetBundle(nlsText requestgetLocale())

gt

lth4gtltfmtmessage key=available_bookmarksgtlth4gt

lt

PortletPreferences prefs = renderRequestgetPreferences()

Enumeration e = prefsgetNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltfmtmessage key=no_bookmarksgtltpgt

- 46 -

lt

else

gt

ltpgt

lt

while (ehasMoreElements())

String name = (String)enextElement()

String value = prefsgetValue(namelt+myTextgetString(undefined)+gt)

gt

lta href=lt=valuegt target=_blankgtlt=namegtltagtltbr gt

lt

gt

ltpgt

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 fmtmessage 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

lt page import=javaxportlet javautil session=false gt

lt taglib uri=httpjavasuncomportlet prefix=portletAPI gt

lt taglib prefix=fmt uri=httpjavasuncomjstlfmt gt

ltjspuseBean id=addUrl scope=request class=javalangString gt

ltjspuseBean id=cancelUrl scope=request class=javalangString gt

- 47 -

ltportletAPIdefineObjectsgt

lt

ResourceBundle myText = ResourceBundlegetBundle(nlsText requestgetLocale())

gt

ltfmtsetBundle basename=nlsTextgt

lth4gtltfmtmessage key=available_bookmarksgtlth4gt

lttable class=wpsTablegt

lttr class=wpsTableRowgt

ltth class=wpsTableHeadgtltfmtmessage key=namegtltthgt

ltth class=wpsTableHeadgtltfmtmessage key=urlgtltthgt

lttdgtlttdgt

lttrgt

lt

PortletPreferences prefs = renderRequestgetPreferences()

Enumeration e = prefsgetNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltfmtmessage key=no_bookmarksgtltpgt

lt

else

while (ehasMoreElements())

String name = (String)enextElement()

String value = prefsgetValue(namelt+myTextgetString(undefined)+gt)

gt

lttr class=wpsTableRowgt

lttdgt lt=namegt lttdgt

lttdgt lt=valuegt lttdgt

- 48 -

lttdgt ltportletAPIactionURL var=removeUrlgt

ltportletAPIparam name=remove value=lt=namegtgt

ltportletAPIactionURLgt

lta href=lt=removeUrltoString()gtgt(ltfmtmessage key=deletegt)ltagt

lttdgt

lttrgt

lt

gt

ltform action=lt=addUrlgt method=POSTgt

lttr class=wpsTableRowgt

lttdgtltinput name=name type=text class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=value type=text class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=add type=submit value=ltfmtmessage key=addgt

class=portlet-form-buttongtlttdgt

lttrgt

ltformgt

lttablegt

ltform action=lt=cancelUrlgt method=postgt

ltinput name=cancel type=submit value=ltfmtmessage key=cancelgt class=portlet-

form-buttongt

ltformgt

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 14 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 -

- 51 -

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 (eg eventing) the IBM Portlet API still needs to be used Trademarks bull IBM and WebSphere are trademarks or registered trademarks of IBM Corporation in

the United States other countries or both bull 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 bull Other company product and service names may be trademarks or service marks of

others IBM copyright and trademark information httpwwwibmcomlegalcopytradephtml

  • Introduction
  • JSR 168 and the Java Community Process
  • Comparing concepts
    • Basic concepts
      • Portal
      • Portal page
      • Portlet
      • Portlet Container
        • Concepts that are the same
          • Portlet mode
          • Window state
          • Portlet life cycle and request processing
          • URL encoding
          • Include servletsJSPs
          • Portlet application packaging
          • Expiration-based caching
            • Concepts that differ
              • Portlet application entity
              • Portlet entity
              • Action and Render Request Response objects
              • Window concept
              • Portlet API does not extend servlet API
              • TAG libraries
                • Concepts new in the JSR 168
                  • Render parameter
                  • Extension mechanisms
                    • Custom window states
                    • Custom portlet modes
                    • Custom user info
                    • Request Response properties
                      • Web application session scope
                      • Reuse of the HttpSession listeners
                      • J2EE role support
                      • Resource bundles
                      • Multiple response content types
                      • Redirect in action
                      • Preference validator
                      • Portal context
                      • Localization support
                        • Concepts missing in the JSR 168
                          • Eventing
                          • Additional lifecycle events
                          • Property broker
                          • Portlet Menus
                          • Portlet Services
                          • Invalidation-based caching
                            • Alignment with WSRP
                              • Outlook for the next version of the JSR 168
                              • Guidelines for programming IBM Portlet API portlets
                                • Similar Functionality
                                  • Basic programming model
                                  • Portlet private session
                                  • User profile information
                                  • Persistent data
                                  • Portlet modes and window states
                                  • Expiration-based caching
                                    • Slightly different functionality
                                      • Sharing of data between portlets
                                      • Session listeners
                                        • New JSR 168 functionality
                                          • Navigational state (render parameters)
                                            • Pitfalls
                                              • Request response objects for action and render phase
                                              • Include search path
                                              • Form parameter encoding
                                              • Title setting
                                                  • Examples
                                                    • IBM Portlet API Portlet Code
                                                    • JSR 168 Portlet Code
                                                    • IBM Portlet API JSPs
                                                    • JSR 168 JSPs
                                                      • Summary
Page 10: Difference Bw Jsr168 and Ibm

bull Minimized ndash to indicate that the portlet is minimized and cannot render any output

bull Moving (deprecated) ndash to indicate that the portlet window has been moved bull Normal ndash to indicate that the portlet is sharing its screen with other portlets on a

page bull Resizing (deprecated) ndash to indicate that the portlet has been resized bull Solo ndash to indicate that the portlet is the only portlet on the page

Whereas the JSR 168 has only the following mandatory window states

bull Maximized ndash same as in the IBM Portlet API bull Minimized ndash to indicate that the portlet should only render minimal or no output bull Normal ndash same as in the IBM Portlet API

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

323 Portlet life cycle and request processing

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

bull init ndash to initialize the portlet and put the portlet into service bull handle requests ndash process different kinds of action and render requests bull destroy ndash 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

324 URL encoding

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

bull 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

bull 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

325 Include servletsJSPs

In both APIrsquos 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()

contextinclude(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)

rdinclude(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 HttpServetRequestgetSession() 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

326 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 (webxml) and one to specify the portlet resources (portletxml) All web resources that are not portlets must be specified in the webxml deployment descriptor All portlets and portlet related settings must be specified in an additional file called portletxml

- 12 -

Different from JSR 168 in the IBM Portlet API all portlets must also be listed in the webxml as they are also servlets (see also 335 for examples of the deployment descitptors)

327 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

33 Concepts that differ

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

331 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 webxml and concrete portlet applications of concrete portlets based on the abstract ones The following portletxml example shows these two different parts

IBM PORTLET API PORTLETXML EXAMPLE

ltxml version=10 encoding=UTF-8gt

ltDOCTYPE portlet-app-def PUBLIC -IBMDTD Portlet Application 11EN

portlet_11dtdgt

ltportlet-app-defgt

ltportlet-app uid=commycobookmark1234 major-version=7 minor-version=24gt

ltportlet-app-namegtBookmark Application7ltportlet-app-namegt

ltportlet id=Portlet_1 href=WEB-INFwebxmlServlet_1gt

- 13 -

ltportlet-namegtBookmark Portlet7ltportlet-namegt

ltallowsgt

ltmaximizedgt

ltminimizedgt

ltallowsgt

ltsupportsgt

ltmarkup name=htmlgt

ltview output=fragmentgt

ltedit output=fragmentgt

ltmarkupgt

ltsupportsgt

ltportletgt

ltportlet-appgt

ltconcrete-portlet-app uid=commycobookmark12341gt

ltportlet-app-namegtConcreteSamplets_Bookmark7ltportlet-app-namegt

ltconcrete-portlet href=Portlet_1gt

ltportlet-namegtBookmark Portlet7ltportlet-namegt

ltdefault-localegtenltdefault-localegt

ltlanguage locale=engt

lttitlegtMy Bookmarks7lttitlegt

lttitle-shortgtBookmarks7lttitle-shortgt

ltdescriptiongtPortlet showing your personalized bookmarksltdescriptiongt

ltkeywordsgtbookmarksltkeywordsgt

ltlanguagegt

ltconfig-paramgt

ltparam-namegturl1ltparam-namegt

ltparam-valuegthttpwwwgooglecomltparam-valuegt

ltconfig-paramgt

ltconcrete-portletgt

- 14 -

ltconcrete-portlet-appgt

ltportlet-app-defgt

As portlets are servlets in the IBM Portlet API the portletxml has references for each portlet to the servlet in the webxml that represents the portlet The webxml for this example is

IBM PORTLET API WEBXML EXAMPLE

ltxml version=10 encoding=UTF-8gt

ltDOCTYPE web-app

PUBLIC -Sun Microsystems IncDTD Web Application 22EN

httpjavasuncomj2eedtdsweb-app_22dtdgt

ltweb-app id=WebApp_1gt

ltdisplay-namegtbookmark7ltdisplay-namegt

ltservlet id=Servlet_1gt

ltservlet-namegtBookmark7ltservlet-namegt

ltservlet-classgtcommycobookmarkBookmarkPortletltservlet-classgt

ltinit-paramgt

ltparam-namegtjspviewltparam-namegt

ltparam-valuegtbookmarkViewjspltparam-valuegt

ltinit-paramgt

ltinit-paramgt

ltparam-namegtjspeditltparam-namegt

ltparam-valuegtbookmarkEditjspltparam-valuegt

ltinit-paramgt

ltservletgt

ltservlet-mappinggt

ltservlet-namegtBookmark7ltservlet-namegt

lturl-patterngtBookmark7lturl-patterngt

ltservlet-mappinggt

ltweb-appgt

- 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 webxml and not in the portletxml In the JSR 168 the deployment descriptor is more like the webxml 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 portletxml example would look like when using the JSR 168 deployment descriptor format

JSR 168 PORTLETXML EXAMPLE

ltxml version=10 encoding=UTF-8gt

ltxml version=10encoding=UTF-8gt

ltportlet-app xmlns=httpjavasuncomxmlnsportletportlet-app_1_0xsd version=10

xmlnsxsi=httpwwww3org2001XMLSchema-instance

xsischemaLocation=httpjavasuncomxmlnsportlet-app_1_0xsd

httpjavasuncomxmlnsportletportlet-app_1_0xsdgt

ltportletgt

ltdescription xmllang=ENgtPortlet showing your personalized

bookmarksltdescriptiongt

ltportlet-namegtBookmark Portlet7ltportlet-namegt

ltdisplay-name xmllang=ENgtBookmark Portletltdisplay-namegt

ltportlet-classgtcommycobookmarkBookmarkPortletltportlet-classgt

ltinit-paramgt

ltnamegtjspviewltnamegt

ltvaluegtbookmarkViewjspltvaluegt

ltinit-paramgt

ltinit-paramgt

ltnamegtjspeditltnamegt

ltvaluegtbookmarkEditjspltvaluegt

ltinit-paramgt

ltsupportsgt

ltmime-typegttexthtmlltmime-typegt

ltportlet-modegtviewltportlet-modegt

- 16 -

ltportlet-modegteditltportlet-modegt

ltsupportsgt

ltsupported-localegtENltsupported-localegt

ltportlet-infogt

lttitlegtMy Bookmarks7lttitlegt

ltshort-titlegtBookmarks7ltshort-titlegt

ltkeywordsgtbookmarksltkeywordsgt

ltportlet-infogt

ltportlet-preferencesgt

ltpreferencegt

ltnamegturl1ltnamegt

ltvaluegthttpwwwgooglecomltvaluegt

ltpreferencegt

ltportlet-preferencesgt

ltportletgt

ltportlet-appgt

Here the initialization parameters are directly specified in the portletxml as portlets are independent components in the JSR 168 The following example represents the webxml for the JSR 168 bookmark portlet

JSR 168 WEBXML EXAMPLE

ltxml version=10 encoding=UTF-8gt

ltDOCTYPE web-app PUBLIC -Sun Microsystems IncDTD Web Application 23EN

httpjavasuncomdtdweb-app_2_3dtdgt

ltweb-appgt

ltdisplay-namegtBookmark Application7ltdisplay-namegt

ltweb-appgt

The only item that needs to be specified in the JSR 168 webxml 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 portletxml as portlet application name as there can be several concrete instances of the same abstract application

- 17 -

332 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 331) 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 331) 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

333 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

334 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 instanceentity 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 -

335 Portlet API does not extend servlet API

In the IBM Portlet API portlets extend servlets and all the major interfaces (Request Response Session hellip) 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

336 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

bull defineObjects tag ndash to define the basic portlet API objects RenderRequest RenderResponse and PortletConfig

bull actionURL tag ndash to create an action URL bull renderURL tag ndash to create a render URL bull namespace tag ndash 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 donrsquot need decoding

34 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 -

341 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 (eg 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

342 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

3421 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

3422 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 322) 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

3423 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

3424 Request Response properties

Properties can be used by the portalportlet container to send vendor specific information to the portlet andor the portlet can send vendor specific information to the portalportlet-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

343 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 (eg between portlets or between a portlet and a servlet)

344 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 23 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

345 J2EE role support

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

346 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 -

347 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 PortletRequestgetResponseContentTypes 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 (eg ldquotextrdquo or ldquordquo) 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

348 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 (eg an accounting servlet) in response to an action

349 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

3410 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 vendorrsquos 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)

3411 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 xmllang attribute like the

- 22 -

servlet 24 deployment descriptor Thus the same tag with descriptions in different languages can be used (eg 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

35 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)

351 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

bull ActionEventThe action event maps to the action phase call in the JSR 168

bull MessageEventMessage 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)

bull PortletApplicationSettingsAttributeEventPortletSettingsAttributeEventThese are events that get fired when attributes for the application or of the portlet settings change

bull WindowEventThe portlet will register for window events to get notified if the portlet window is changed via the window decorations

352 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 -

bull PortletPageListener The page listeners provides the portlet with events for the beginning of the page before any markup is written for this page (eg to write JavaScript at the beginning of the page) and the end of the page after all markup is written

bull 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 23 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

bull EventPhaseListener The event phase listener notifies the portlet of the beginning and end of the eventaction phase

353 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

354 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 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

Figure 4

- 24 -

Figure 4 Portlet menu example

355 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

356 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 -

36 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 indicates portlet in what mode to operate for a given request

View edit help + custom modes

view edit help + custom modes

full alignment

Window State the state of the window in which the portlet output will be displayed

minimized normal maximized solo +

custom window states

minimized normal maximized +

custom window states

full alignment (ldquosolordquo is missing in the JSR but can be implemented as a custom state)

URL encoding to allow re-writing URLs created by the portlet

defines how to create URLs to allow re-writing of the URLs either on consumer or producer side

encapsulates URL creation via a Java object

full alignment (the implementation of the Java object can implement the WSRP URL rewriting rules)

Namespace encoding to avoid that several portlets on a page conflicting with each other

defines namespace prefixes for consumer and producer side namespacing

provides a Java method to namespace a String

full alignment (the JSR namespace method can implement the WSRP namespace behavior)

User ndash portlet interaction operations

performBlockingInteraction blocking action processing

getMarkup render the markup

action blocking action processing

render render the makup

full alignment (action invocations carried through performBlockingInteraction render carried through getMarkup)

View state that allows the current portlet fragment to be correctly displayed in sub-sequent render calls

navigational state render parameter full alignment (WSRP navigational state maps to JSR render parameters)

Storing transient state across request

session state concept implemented via a sessionID

utilizes the Http web application session

full alignment (the WSRP sessionID can be used to reference the JSR session)

Storing persistent state to personalize the rendering of the portlet

allows to have properties of arbitrary types

provides String-based preferences

full alignment (JSR String preferences can be mapped to WSRP properties)

Information about the portal calling the portlet

RegistrationData provide information of the consumer to the producer

PortalContext provide a Java interface to access information about the portal calling the portlet

full alignment (all data represented through the PortalContext to the JSR portlet are available in the RegistrationData)

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

Aggregated HTML WML VoiceXML

over HTTPMark-Up Fragments

Transferred via WSRP

Portal

WSRP Service

WSRP Service

WSRP Service

WSRP Consumer WSRP Producer

Use of WSRP Services in Portals

Portal sharing Portlets as WSRP Services

ServerPortalPortals

Huge numberof users Publishing Portal

WSRPWrapperPortalsPortalsPortal

Portlet

Portlet

Portlet

WSRP Consumer WSRP Producer

ProxyPortlet

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

bull 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

bull 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

bull 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

bull 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 CCPP standard allowing a portlet to query the client capabilities and adopting its markup accordingly (eg screen size browser) This API is likely to be included in the next version of the portlet API Also J2EE 14 was finalized during this time period J2EE 14 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 14

bull caching The first version of the JSR 168 API is limited to expiration-based caching (see section 327) 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

bull 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

51 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

511 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

bull portlets are components Portlets are components that implement a specific function Different functions should be distributed to different portlets

bull 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

bull 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

512 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 HttpServletRequestgetSession() call in the JSPs called via the IBM Portlet API needs to be replaced when moving to JSR 168 portlets by the RenderRequestgetPortletSession() 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 HttpServletRequestgetSession() will get the HttpSession and therefore need to access the portlet session via the RenderRequest

513 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

514 Persistent data

Portlets can store customization and personalization data persistently Customization data are related to the portlet and are valid for all users (eg 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 (eg 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

515 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

516 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

52 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

521 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 351 353) 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

522 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

53 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 -

531 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

bull no support of the back button in the browser bull current state of the portlet is not bookmarkable bull 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 bull 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

54 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

541 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 -

542 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

543 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

544 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 wersquoll 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

Figure 7After clicking on the Edit mode button the portlet renders the Edit view shown in

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

Figure 8

After we press the ldquoAddrdquo 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

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

bull use JSPs for rendering the output bull customize the portlet output taking user specific data into account bull 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

61 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 comibmwpssampleswp5

import javaio

import javautil

import orgapachejetspeedportlet

import orgapachejetspeedportletevent

public class IbmBookmark extends PortletAdapter implements ActionListener

public void init(PortletConfig portletConfig) throws UnavailableException

superinit(portletConfig)

- 36 -

public void doView(PortletRequest request PortletResponse response)

throws PortletException IOException

String jspName = thisgetPortletConfig()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 = responsecreateReturnURI()

addURIaddAction(add)

requestsetAttribute(addURI addURItoString())

PortletURI cancelURI = responsecreateReturnURI()

requestsetAttribute(cancelURI cancelURItoString())

String jspName = thisgetPortletConfig()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 ldquocancelrdquo and ldquoaddrdquo URLs are created inside the portlet and attached to the request before including the Edit JSP Both URLs are from type ldquoReturnURIrdquo 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 = eventgetRequest()

String action = eventgetActionString()

PortletLog log = getPortletLog()

if ( action=null )

try

if (actionequals(removeURI))

String removeName = requestgetParameter(remove)

PortletData portData = requestgetData()

portDataremoveAttribute(removeName)

portDatastore()

if (actionequals(add))

PortletData portData = requestgetData()

String name = requestgetParameter(name)

String value = requestgetParameter(value)

portDatasetAttribute(name value)

portDatastore()

catch ( AccessDeniedException ade )

logerror(AccessDeniedException occured when adding or deleting a bookmark)

catch ( IOException ioe )

logerror(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 ldquoaddrdquo or ldquodeleterdquo 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 ldquoaddrdquo or ldquoremoveURIrdquo If the user has clicked on the ldquoremoverdquo button the corresponding link is removed from the portlet data whereas if ldquoaddrdquo was clicked the data entered by the user is added to the portlet data

62 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 comibmwpssamplesjsr

import javaio

import javaxportlet

public class Bookmark extends GenericPortlet

public void init(PortletConfig config) throws PortletException

superinit(config)

public void doView(RenderRequest request RenderResponse response)

throws PortletException IOException

responsesetContentType(texthtml)

String jspName = getPortletConfig()getInitParameter(jspView)

PortletRequestDispatcher rd = getPortletContext()getRequestDispatcher(jspName)

rdinclude(requestresponse)

- 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

responsesetContentType(texthtml)

PortletURL addUrl = responsecreateActionURL()

addUrlsetPortletMode(PortletModeVIEW)

addUrlsetParameter(addadd)

requestsetAttribute(addUrladdUrltoString())

PortletURL cancelUrl = responsecreateRenderURL()

cancelUrlsetPortletMode(PortletModeVIEW)

requestsetAttribute(cancelUrlcancelUrltoString())

String jspName = getPortletConfig()getInitParameter(jspEdit)

PortletRequestDispatcher rd = getPortletContext()getRequestDispatcher(jspName)

rdinclude(requestresponse)

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 ldquoaddrdquo button URL an action URL is created as we need to store the user input of the add form persistently For the ldquocancelrdquo 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 = requestgetParameter(remove)

if (removeName = null)

PortletPreferences prefs = requestgetPreferences()

prefsreset(removeName)

prefsstore()

String add = requestgetParameter(add)

if (add = null)

PortletPreferences prefs = requestgetPreferences()

String name = requestgetParameter(name)

String value = requestgetParameter(value)

prefssetValue(name value)

prefsstore()

catch ( IOException ioe )

getPortletContextlog(An IO error occured when trying to remove a bookmark)

catch ( PortletException pe )

getPortletContextlog(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

bull 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

bull 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

bull Persistent portlet data The JSR 168 persistent data PortletPreferences have an API similar to the JDK 14 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

bull 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

63 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

lt page contentType=texthtml import=javautil comibmwpssampleswp5

orgapachejetspeedportlet session=falsegt

lt taglib uri=WEB-INFtldportlettld prefix=portletAPI gt

- 42 -

ltportletAPIinitgt

ltp class=wpsPortletHeadgtltportletAPItext key=available_bookmarks

bundle=nlsTextgtAvailable BookmarksltportletAPItextgtltpgt

lt

PortletData prefs = portletRequestgetData()

Enumeration e = prefsgetAttributeNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltportletAPItext key=no_bookmarks bundle=nlsTextgtNo

bookmarksltportletAPItextgtltpgt

lt

else

gt

ltp class=wpsIndentMediumgt

lt

while (ehasMoreElements())

String name = (String)enextElement()

String value = (String)prefsgetAttribute(name)

gt

lta href=lt=valuegt target=_blankgtlt=namegtltagtltbr gt

lt

gt

ltpgt

The View JSP first call portletAPIinit 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

lt page contentType=texthtml import=javautil

comibmwpssampleswp5orgapachejetspeedportlet session=falsegt

lt taglib uri=WEB-INFtldportlettld prefix=portletAPI gt

ltjspuseBean id=addURI class=javalangString scope=request gt

ltjspuseBean id=cancelURI class=javalangString scope=request gt

ltportletAPIinitgt

lth4gtltportletAPItext key=available_bookmarks bundle=nlsTextgtAvailable

BookmarksltportletAPItextgtlth4gt

lttable class=wpsTablegt

lttr class=wpsTableRowgt

ltth class=portlet-table-headergtltportletAPItext key=name bundle=nlsTextgtltthgt

ltth class=portlet-table-headergtltportletAPItext key=url bundle=nlsTextgtltthgt

lttdgtlttdgt

lttrgt

lt

PortletData prefs = portletRequestgetData()

Enumeration e = prefsgetAttributeNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltportletAPItext key=no_bookmarks bundle=nlsTextgtNo

bookmarksltportletAPItextgtltpgt

lt

else

while (ehasMoreElements())

- 44 -

String name = (String)enextElement()

String value = (String)prefsgetAttribute(name)

gt

lttr class=wpsTableRowgt

lttdgt lt=namegt lttdgt

lttdgt lt=valuegt lttdgt

lttdgt lta href=ltportletAPIcreateURIgtltportletAPIURIAction

name=removeURIgtltportletAPIURIParameter name=remove

value=lt=namegtgtltportletAPIcreateURIgtgt

(ltportletAPItext key=delete bundle=nlsTextgt)ltagt

lttdgt

lttrgt

lt

gt

ltform action=lt=addURIgt method=POSTgt

lttr class=wpsTableRowgt

lttdgtltinput name=ltportletAPIencodeNamespace value=namegt type=text

class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=ltportletAPIencodeNamespace value=valuegt type=text

class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=ltportletAPIencodeNamespace value=addgt type=submit

value=ltportletAPItext key=add bundle=nlsTextgt class=portlet-form-buttongtlttdgt

lttrgt

ltformgt

lttablegt

- 45 -

ltform action=lt=cancelURIgt method=postgt

ltinput name=ltportletAPIencodeNamespace value=cancelgt type=submit

value=ltportletAPItext key=cancel bundle=nlsTextgt class=portlet-form-buttongt

ltformgt

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 ldquodeleterdquo button for which an URL with the action ldquoremoveURIrdquo 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 ldquocancelrdquo button from the request

64 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

lt page import=javaxportlet javautil session=falsegt

lt taglib uri=httpjavasuncomportlet prefix=portletAPI gt

lt taglib prefix=fmt uri=httpjavasuncomjstlfmt gt

ltportletAPIdefineObjects gt

ltfmtsetBundle basename=nlsTextgt

lt

ResourceBundle myText = ResourceBundlegetBundle(nlsText requestgetLocale())

gt

lth4gtltfmtmessage key=available_bookmarksgtlth4gt

lt

PortletPreferences prefs = renderRequestgetPreferences()

Enumeration e = prefsgetNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltfmtmessage key=no_bookmarksgtltpgt

- 46 -

lt

else

gt

ltpgt

lt

while (ehasMoreElements())

String name = (String)enextElement()

String value = prefsgetValue(namelt+myTextgetString(undefined)+gt)

gt

lta href=lt=valuegt target=_blankgtlt=namegtltagtltbr gt

lt

gt

ltpgt

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 fmtmessage 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

lt page import=javaxportlet javautil session=false gt

lt taglib uri=httpjavasuncomportlet prefix=portletAPI gt

lt taglib prefix=fmt uri=httpjavasuncomjstlfmt gt

ltjspuseBean id=addUrl scope=request class=javalangString gt

ltjspuseBean id=cancelUrl scope=request class=javalangString gt

- 47 -

ltportletAPIdefineObjectsgt

lt

ResourceBundle myText = ResourceBundlegetBundle(nlsText requestgetLocale())

gt

ltfmtsetBundle basename=nlsTextgt

lth4gtltfmtmessage key=available_bookmarksgtlth4gt

lttable class=wpsTablegt

lttr class=wpsTableRowgt

ltth class=wpsTableHeadgtltfmtmessage key=namegtltthgt

ltth class=wpsTableHeadgtltfmtmessage key=urlgtltthgt

lttdgtlttdgt

lttrgt

lt

PortletPreferences prefs = renderRequestgetPreferences()

Enumeration e = prefsgetNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltfmtmessage key=no_bookmarksgtltpgt

lt

else

while (ehasMoreElements())

String name = (String)enextElement()

String value = prefsgetValue(namelt+myTextgetString(undefined)+gt)

gt

lttr class=wpsTableRowgt

lttdgt lt=namegt lttdgt

lttdgt lt=valuegt lttdgt

- 48 -

lttdgt ltportletAPIactionURL var=removeUrlgt

ltportletAPIparam name=remove value=lt=namegtgt

ltportletAPIactionURLgt

lta href=lt=removeUrltoString()gtgt(ltfmtmessage key=deletegt)ltagt

lttdgt

lttrgt

lt

gt

ltform action=lt=addUrlgt method=POSTgt

lttr class=wpsTableRowgt

lttdgtltinput name=name type=text class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=value type=text class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=add type=submit value=ltfmtmessage key=addgt

class=portlet-form-buttongtlttdgt

lttrgt

ltformgt

lttablegt

ltform action=lt=cancelUrlgt method=postgt

ltinput name=cancel type=submit value=ltfmtmessage key=cancelgt class=portlet-

form-buttongt

ltformgt

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 14 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 -

- 51 -

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 (eg eventing) the IBM Portlet API still needs to be used Trademarks bull IBM and WebSphere are trademarks or registered trademarks of IBM Corporation in

the United States other countries or both bull 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 bull Other company product and service names may be trademarks or service marks of

others IBM copyright and trademark information httpwwwibmcomlegalcopytradephtml

  • Introduction
  • JSR 168 and the Java Community Process
  • Comparing concepts
    • Basic concepts
      • Portal
      • Portal page
      • Portlet
      • Portlet Container
        • Concepts that are the same
          • Portlet mode
          • Window state
          • Portlet life cycle and request processing
          • URL encoding
          • Include servletsJSPs
          • Portlet application packaging
          • Expiration-based caching
            • Concepts that differ
              • Portlet application entity
              • Portlet entity
              • Action and Render Request Response objects
              • Window concept
              • Portlet API does not extend servlet API
              • TAG libraries
                • Concepts new in the JSR 168
                  • Render parameter
                  • Extension mechanisms
                    • Custom window states
                    • Custom portlet modes
                    • Custom user info
                    • Request Response properties
                      • Web application session scope
                      • Reuse of the HttpSession listeners
                      • J2EE role support
                      • Resource bundles
                      • Multiple response content types
                      • Redirect in action
                      • Preference validator
                      • Portal context
                      • Localization support
                        • Concepts missing in the JSR 168
                          • Eventing
                          • Additional lifecycle events
                          • Property broker
                          • Portlet Menus
                          • Portlet Services
                          • Invalidation-based caching
                            • Alignment with WSRP
                              • Outlook for the next version of the JSR 168
                              • Guidelines for programming IBM Portlet API portlets
                                • Similar Functionality
                                  • Basic programming model
                                  • Portlet private session
                                  • User profile information
                                  • Persistent data
                                  • Portlet modes and window states
                                  • Expiration-based caching
                                    • Slightly different functionality
                                      • Sharing of data between portlets
                                      • Session listeners
                                        • New JSR 168 functionality
                                          • Navigational state (render parameters)
                                            • Pitfalls
                                              • Request response objects for action and render phase
                                              • Include search path
                                              • Form parameter encoding
                                              • Title setting
                                                  • Examples
                                                    • IBM Portlet API Portlet Code
                                                    • JSR 168 Portlet Code
                                                    • IBM Portlet API JSPs
                                                    • JSR 168 JSPs
                                                      • Summary
Page 11: Difference Bw Jsr168 and Ibm

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

324 URL encoding

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

bull 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

bull 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

325 Include servletsJSPs

In both APIrsquos 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()

contextinclude(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)

rdinclude(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 HttpServetRequestgetSession() 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

326 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 (webxml) and one to specify the portlet resources (portletxml) All web resources that are not portlets must be specified in the webxml deployment descriptor All portlets and portlet related settings must be specified in an additional file called portletxml

- 12 -

Different from JSR 168 in the IBM Portlet API all portlets must also be listed in the webxml as they are also servlets (see also 335 for examples of the deployment descitptors)

327 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

33 Concepts that differ

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

331 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 webxml and concrete portlet applications of concrete portlets based on the abstract ones The following portletxml example shows these two different parts

IBM PORTLET API PORTLETXML EXAMPLE

ltxml version=10 encoding=UTF-8gt

ltDOCTYPE portlet-app-def PUBLIC -IBMDTD Portlet Application 11EN

portlet_11dtdgt

ltportlet-app-defgt

ltportlet-app uid=commycobookmark1234 major-version=7 minor-version=24gt

ltportlet-app-namegtBookmark Application7ltportlet-app-namegt

ltportlet id=Portlet_1 href=WEB-INFwebxmlServlet_1gt

- 13 -

ltportlet-namegtBookmark Portlet7ltportlet-namegt

ltallowsgt

ltmaximizedgt

ltminimizedgt

ltallowsgt

ltsupportsgt

ltmarkup name=htmlgt

ltview output=fragmentgt

ltedit output=fragmentgt

ltmarkupgt

ltsupportsgt

ltportletgt

ltportlet-appgt

ltconcrete-portlet-app uid=commycobookmark12341gt

ltportlet-app-namegtConcreteSamplets_Bookmark7ltportlet-app-namegt

ltconcrete-portlet href=Portlet_1gt

ltportlet-namegtBookmark Portlet7ltportlet-namegt

ltdefault-localegtenltdefault-localegt

ltlanguage locale=engt

lttitlegtMy Bookmarks7lttitlegt

lttitle-shortgtBookmarks7lttitle-shortgt

ltdescriptiongtPortlet showing your personalized bookmarksltdescriptiongt

ltkeywordsgtbookmarksltkeywordsgt

ltlanguagegt

ltconfig-paramgt

ltparam-namegturl1ltparam-namegt

ltparam-valuegthttpwwwgooglecomltparam-valuegt

ltconfig-paramgt

ltconcrete-portletgt

- 14 -

ltconcrete-portlet-appgt

ltportlet-app-defgt

As portlets are servlets in the IBM Portlet API the portletxml has references for each portlet to the servlet in the webxml that represents the portlet The webxml for this example is

IBM PORTLET API WEBXML EXAMPLE

ltxml version=10 encoding=UTF-8gt

ltDOCTYPE web-app

PUBLIC -Sun Microsystems IncDTD Web Application 22EN

httpjavasuncomj2eedtdsweb-app_22dtdgt

ltweb-app id=WebApp_1gt

ltdisplay-namegtbookmark7ltdisplay-namegt

ltservlet id=Servlet_1gt

ltservlet-namegtBookmark7ltservlet-namegt

ltservlet-classgtcommycobookmarkBookmarkPortletltservlet-classgt

ltinit-paramgt

ltparam-namegtjspviewltparam-namegt

ltparam-valuegtbookmarkViewjspltparam-valuegt

ltinit-paramgt

ltinit-paramgt

ltparam-namegtjspeditltparam-namegt

ltparam-valuegtbookmarkEditjspltparam-valuegt

ltinit-paramgt

ltservletgt

ltservlet-mappinggt

ltservlet-namegtBookmark7ltservlet-namegt

lturl-patterngtBookmark7lturl-patterngt

ltservlet-mappinggt

ltweb-appgt

- 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 webxml and not in the portletxml In the JSR 168 the deployment descriptor is more like the webxml 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 portletxml example would look like when using the JSR 168 deployment descriptor format

JSR 168 PORTLETXML EXAMPLE

ltxml version=10 encoding=UTF-8gt

ltxml version=10encoding=UTF-8gt

ltportlet-app xmlns=httpjavasuncomxmlnsportletportlet-app_1_0xsd version=10

xmlnsxsi=httpwwww3org2001XMLSchema-instance

xsischemaLocation=httpjavasuncomxmlnsportlet-app_1_0xsd

httpjavasuncomxmlnsportletportlet-app_1_0xsdgt

ltportletgt

ltdescription xmllang=ENgtPortlet showing your personalized

bookmarksltdescriptiongt

ltportlet-namegtBookmark Portlet7ltportlet-namegt

ltdisplay-name xmllang=ENgtBookmark Portletltdisplay-namegt

ltportlet-classgtcommycobookmarkBookmarkPortletltportlet-classgt

ltinit-paramgt

ltnamegtjspviewltnamegt

ltvaluegtbookmarkViewjspltvaluegt

ltinit-paramgt

ltinit-paramgt

ltnamegtjspeditltnamegt

ltvaluegtbookmarkEditjspltvaluegt

ltinit-paramgt

ltsupportsgt

ltmime-typegttexthtmlltmime-typegt

ltportlet-modegtviewltportlet-modegt

- 16 -

ltportlet-modegteditltportlet-modegt

ltsupportsgt

ltsupported-localegtENltsupported-localegt

ltportlet-infogt

lttitlegtMy Bookmarks7lttitlegt

ltshort-titlegtBookmarks7ltshort-titlegt

ltkeywordsgtbookmarksltkeywordsgt

ltportlet-infogt

ltportlet-preferencesgt

ltpreferencegt

ltnamegturl1ltnamegt

ltvaluegthttpwwwgooglecomltvaluegt

ltpreferencegt

ltportlet-preferencesgt

ltportletgt

ltportlet-appgt

Here the initialization parameters are directly specified in the portletxml as portlets are independent components in the JSR 168 The following example represents the webxml for the JSR 168 bookmark portlet

JSR 168 WEBXML EXAMPLE

ltxml version=10 encoding=UTF-8gt

ltDOCTYPE web-app PUBLIC -Sun Microsystems IncDTD Web Application 23EN

httpjavasuncomdtdweb-app_2_3dtdgt

ltweb-appgt

ltdisplay-namegtBookmark Application7ltdisplay-namegt

ltweb-appgt

The only item that needs to be specified in the JSR 168 webxml 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 portletxml as portlet application name as there can be several concrete instances of the same abstract application

- 17 -

332 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 331) 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 331) 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

333 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

334 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 instanceentity 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 -

335 Portlet API does not extend servlet API

In the IBM Portlet API portlets extend servlets and all the major interfaces (Request Response Session hellip) 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

336 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

bull defineObjects tag ndash to define the basic portlet API objects RenderRequest RenderResponse and PortletConfig

bull actionURL tag ndash to create an action URL bull renderURL tag ndash to create a render URL bull namespace tag ndash 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 donrsquot need decoding

34 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 -

341 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 (eg 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

342 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

3421 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

3422 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 322) 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

3423 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

3424 Request Response properties

Properties can be used by the portalportlet container to send vendor specific information to the portlet andor the portlet can send vendor specific information to the portalportlet-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

343 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 (eg between portlets or between a portlet and a servlet)

344 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 23 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

345 J2EE role support

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

346 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 -

347 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 PortletRequestgetResponseContentTypes 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 (eg ldquotextrdquo or ldquordquo) 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

348 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 (eg an accounting servlet) in response to an action

349 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

3410 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 vendorrsquos 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)

3411 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 xmllang attribute like the

- 22 -

servlet 24 deployment descriptor Thus the same tag with descriptions in different languages can be used (eg 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

35 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)

351 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

bull ActionEventThe action event maps to the action phase call in the JSR 168

bull MessageEventMessage 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)

bull PortletApplicationSettingsAttributeEventPortletSettingsAttributeEventThese are events that get fired when attributes for the application or of the portlet settings change

bull WindowEventThe portlet will register for window events to get notified if the portlet window is changed via the window decorations

352 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 -

bull PortletPageListener The page listeners provides the portlet with events for the beginning of the page before any markup is written for this page (eg to write JavaScript at the beginning of the page) and the end of the page after all markup is written

bull 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 23 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

bull EventPhaseListener The event phase listener notifies the portlet of the beginning and end of the eventaction phase

353 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

354 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 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

Figure 4

- 24 -

Figure 4 Portlet menu example

355 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

356 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 -

36 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 indicates portlet in what mode to operate for a given request

View edit help + custom modes

view edit help + custom modes

full alignment

Window State the state of the window in which the portlet output will be displayed

minimized normal maximized solo +

custom window states

minimized normal maximized +

custom window states

full alignment (ldquosolordquo is missing in the JSR but can be implemented as a custom state)

URL encoding to allow re-writing URLs created by the portlet

defines how to create URLs to allow re-writing of the URLs either on consumer or producer side

encapsulates URL creation via a Java object

full alignment (the implementation of the Java object can implement the WSRP URL rewriting rules)

Namespace encoding to avoid that several portlets on a page conflicting with each other

defines namespace prefixes for consumer and producer side namespacing

provides a Java method to namespace a String

full alignment (the JSR namespace method can implement the WSRP namespace behavior)

User ndash portlet interaction operations

performBlockingInteraction blocking action processing

getMarkup render the markup

action blocking action processing

render render the makup

full alignment (action invocations carried through performBlockingInteraction render carried through getMarkup)

View state that allows the current portlet fragment to be correctly displayed in sub-sequent render calls

navigational state render parameter full alignment (WSRP navigational state maps to JSR render parameters)

Storing transient state across request

session state concept implemented via a sessionID

utilizes the Http web application session

full alignment (the WSRP sessionID can be used to reference the JSR session)

Storing persistent state to personalize the rendering of the portlet

allows to have properties of arbitrary types

provides String-based preferences

full alignment (JSR String preferences can be mapped to WSRP properties)

Information about the portal calling the portlet

RegistrationData provide information of the consumer to the producer

PortalContext provide a Java interface to access information about the portal calling the portlet

full alignment (all data represented through the PortalContext to the JSR portlet are available in the RegistrationData)

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

Aggregated HTML WML VoiceXML

over HTTPMark-Up Fragments

Transferred via WSRP

Portal

WSRP Service

WSRP Service

WSRP Service

WSRP Consumer WSRP Producer

Use of WSRP Services in Portals

Portal sharing Portlets as WSRP Services

ServerPortalPortals

Huge numberof users Publishing Portal

WSRPWrapperPortalsPortalsPortal

Portlet

Portlet

Portlet

WSRP Consumer WSRP Producer

ProxyPortlet

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

bull 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

bull 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

bull 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

bull 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 CCPP standard allowing a portlet to query the client capabilities and adopting its markup accordingly (eg screen size browser) This API is likely to be included in the next version of the portlet API Also J2EE 14 was finalized during this time period J2EE 14 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 14

bull caching The first version of the JSR 168 API is limited to expiration-based caching (see section 327) 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

bull 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

51 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

511 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

bull portlets are components Portlets are components that implement a specific function Different functions should be distributed to different portlets

bull 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

bull 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

512 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 HttpServletRequestgetSession() call in the JSPs called via the IBM Portlet API needs to be replaced when moving to JSR 168 portlets by the RenderRequestgetPortletSession() 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 HttpServletRequestgetSession() will get the HttpSession and therefore need to access the portlet session via the RenderRequest

513 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

514 Persistent data

Portlets can store customization and personalization data persistently Customization data are related to the portlet and are valid for all users (eg 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 (eg 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

515 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

516 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

52 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

521 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 351 353) 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

522 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

53 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 -

531 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

bull no support of the back button in the browser bull current state of the portlet is not bookmarkable bull 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 bull 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

54 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

541 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 -

542 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

543 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

544 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 wersquoll 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

Figure 7After clicking on the Edit mode button the portlet renders the Edit view shown in

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

Figure 8

After we press the ldquoAddrdquo 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

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

bull use JSPs for rendering the output bull customize the portlet output taking user specific data into account bull 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

61 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 comibmwpssampleswp5

import javaio

import javautil

import orgapachejetspeedportlet

import orgapachejetspeedportletevent

public class IbmBookmark extends PortletAdapter implements ActionListener

public void init(PortletConfig portletConfig) throws UnavailableException

superinit(portletConfig)

- 36 -

public void doView(PortletRequest request PortletResponse response)

throws PortletException IOException

String jspName = thisgetPortletConfig()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 = responsecreateReturnURI()

addURIaddAction(add)

requestsetAttribute(addURI addURItoString())

PortletURI cancelURI = responsecreateReturnURI()

requestsetAttribute(cancelURI cancelURItoString())

String jspName = thisgetPortletConfig()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 ldquocancelrdquo and ldquoaddrdquo URLs are created inside the portlet and attached to the request before including the Edit JSP Both URLs are from type ldquoReturnURIrdquo 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 = eventgetRequest()

String action = eventgetActionString()

PortletLog log = getPortletLog()

if ( action=null )

try

if (actionequals(removeURI))

String removeName = requestgetParameter(remove)

PortletData portData = requestgetData()

portDataremoveAttribute(removeName)

portDatastore()

if (actionequals(add))

PortletData portData = requestgetData()

String name = requestgetParameter(name)

String value = requestgetParameter(value)

portDatasetAttribute(name value)

portDatastore()

catch ( AccessDeniedException ade )

logerror(AccessDeniedException occured when adding or deleting a bookmark)

catch ( IOException ioe )

logerror(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 ldquoaddrdquo or ldquodeleterdquo 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 ldquoaddrdquo or ldquoremoveURIrdquo If the user has clicked on the ldquoremoverdquo button the corresponding link is removed from the portlet data whereas if ldquoaddrdquo was clicked the data entered by the user is added to the portlet data

62 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 comibmwpssamplesjsr

import javaio

import javaxportlet

public class Bookmark extends GenericPortlet

public void init(PortletConfig config) throws PortletException

superinit(config)

public void doView(RenderRequest request RenderResponse response)

throws PortletException IOException

responsesetContentType(texthtml)

String jspName = getPortletConfig()getInitParameter(jspView)

PortletRequestDispatcher rd = getPortletContext()getRequestDispatcher(jspName)

rdinclude(requestresponse)

- 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

responsesetContentType(texthtml)

PortletURL addUrl = responsecreateActionURL()

addUrlsetPortletMode(PortletModeVIEW)

addUrlsetParameter(addadd)

requestsetAttribute(addUrladdUrltoString())

PortletURL cancelUrl = responsecreateRenderURL()

cancelUrlsetPortletMode(PortletModeVIEW)

requestsetAttribute(cancelUrlcancelUrltoString())

String jspName = getPortletConfig()getInitParameter(jspEdit)

PortletRequestDispatcher rd = getPortletContext()getRequestDispatcher(jspName)

rdinclude(requestresponse)

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 ldquoaddrdquo button URL an action URL is created as we need to store the user input of the add form persistently For the ldquocancelrdquo 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 = requestgetParameter(remove)

if (removeName = null)

PortletPreferences prefs = requestgetPreferences()

prefsreset(removeName)

prefsstore()

String add = requestgetParameter(add)

if (add = null)

PortletPreferences prefs = requestgetPreferences()

String name = requestgetParameter(name)

String value = requestgetParameter(value)

prefssetValue(name value)

prefsstore()

catch ( IOException ioe )

getPortletContextlog(An IO error occured when trying to remove a bookmark)

catch ( PortletException pe )

getPortletContextlog(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

bull 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

bull 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

bull Persistent portlet data The JSR 168 persistent data PortletPreferences have an API similar to the JDK 14 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

bull 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

63 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

lt page contentType=texthtml import=javautil comibmwpssampleswp5

orgapachejetspeedportlet session=falsegt

lt taglib uri=WEB-INFtldportlettld prefix=portletAPI gt

- 42 -

ltportletAPIinitgt

ltp class=wpsPortletHeadgtltportletAPItext key=available_bookmarks

bundle=nlsTextgtAvailable BookmarksltportletAPItextgtltpgt

lt

PortletData prefs = portletRequestgetData()

Enumeration e = prefsgetAttributeNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltportletAPItext key=no_bookmarks bundle=nlsTextgtNo

bookmarksltportletAPItextgtltpgt

lt

else

gt

ltp class=wpsIndentMediumgt

lt

while (ehasMoreElements())

String name = (String)enextElement()

String value = (String)prefsgetAttribute(name)

gt

lta href=lt=valuegt target=_blankgtlt=namegtltagtltbr gt

lt

gt

ltpgt

The View JSP first call portletAPIinit 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

lt page contentType=texthtml import=javautil

comibmwpssampleswp5orgapachejetspeedportlet session=falsegt

lt taglib uri=WEB-INFtldportlettld prefix=portletAPI gt

ltjspuseBean id=addURI class=javalangString scope=request gt

ltjspuseBean id=cancelURI class=javalangString scope=request gt

ltportletAPIinitgt

lth4gtltportletAPItext key=available_bookmarks bundle=nlsTextgtAvailable

BookmarksltportletAPItextgtlth4gt

lttable class=wpsTablegt

lttr class=wpsTableRowgt

ltth class=portlet-table-headergtltportletAPItext key=name bundle=nlsTextgtltthgt

ltth class=portlet-table-headergtltportletAPItext key=url bundle=nlsTextgtltthgt

lttdgtlttdgt

lttrgt

lt

PortletData prefs = portletRequestgetData()

Enumeration e = prefsgetAttributeNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltportletAPItext key=no_bookmarks bundle=nlsTextgtNo

bookmarksltportletAPItextgtltpgt

lt

else

while (ehasMoreElements())

- 44 -

String name = (String)enextElement()

String value = (String)prefsgetAttribute(name)

gt

lttr class=wpsTableRowgt

lttdgt lt=namegt lttdgt

lttdgt lt=valuegt lttdgt

lttdgt lta href=ltportletAPIcreateURIgtltportletAPIURIAction

name=removeURIgtltportletAPIURIParameter name=remove

value=lt=namegtgtltportletAPIcreateURIgtgt

(ltportletAPItext key=delete bundle=nlsTextgt)ltagt

lttdgt

lttrgt

lt

gt

ltform action=lt=addURIgt method=POSTgt

lttr class=wpsTableRowgt

lttdgtltinput name=ltportletAPIencodeNamespace value=namegt type=text

class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=ltportletAPIencodeNamespace value=valuegt type=text

class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=ltportletAPIencodeNamespace value=addgt type=submit

value=ltportletAPItext key=add bundle=nlsTextgt class=portlet-form-buttongtlttdgt

lttrgt

ltformgt

lttablegt

- 45 -

ltform action=lt=cancelURIgt method=postgt

ltinput name=ltportletAPIencodeNamespace value=cancelgt type=submit

value=ltportletAPItext key=cancel bundle=nlsTextgt class=portlet-form-buttongt

ltformgt

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 ldquodeleterdquo button for which an URL with the action ldquoremoveURIrdquo 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 ldquocancelrdquo button from the request

64 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

lt page import=javaxportlet javautil session=falsegt

lt taglib uri=httpjavasuncomportlet prefix=portletAPI gt

lt taglib prefix=fmt uri=httpjavasuncomjstlfmt gt

ltportletAPIdefineObjects gt

ltfmtsetBundle basename=nlsTextgt

lt

ResourceBundle myText = ResourceBundlegetBundle(nlsText requestgetLocale())

gt

lth4gtltfmtmessage key=available_bookmarksgtlth4gt

lt

PortletPreferences prefs = renderRequestgetPreferences()

Enumeration e = prefsgetNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltfmtmessage key=no_bookmarksgtltpgt

- 46 -

lt

else

gt

ltpgt

lt

while (ehasMoreElements())

String name = (String)enextElement()

String value = prefsgetValue(namelt+myTextgetString(undefined)+gt)

gt

lta href=lt=valuegt target=_blankgtlt=namegtltagtltbr gt

lt

gt

ltpgt

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 fmtmessage 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

lt page import=javaxportlet javautil session=false gt

lt taglib uri=httpjavasuncomportlet prefix=portletAPI gt

lt taglib prefix=fmt uri=httpjavasuncomjstlfmt gt

ltjspuseBean id=addUrl scope=request class=javalangString gt

ltjspuseBean id=cancelUrl scope=request class=javalangString gt

- 47 -

ltportletAPIdefineObjectsgt

lt

ResourceBundle myText = ResourceBundlegetBundle(nlsText requestgetLocale())

gt

ltfmtsetBundle basename=nlsTextgt

lth4gtltfmtmessage key=available_bookmarksgtlth4gt

lttable class=wpsTablegt

lttr class=wpsTableRowgt

ltth class=wpsTableHeadgtltfmtmessage key=namegtltthgt

ltth class=wpsTableHeadgtltfmtmessage key=urlgtltthgt

lttdgtlttdgt

lttrgt

lt

PortletPreferences prefs = renderRequestgetPreferences()

Enumeration e = prefsgetNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltfmtmessage key=no_bookmarksgtltpgt

lt

else

while (ehasMoreElements())

String name = (String)enextElement()

String value = prefsgetValue(namelt+myTextgetString(undefined)+gt)

gt

lttr class=wpsTableRowgt

lttdgt lt=namegt lttdgt

lttdgt lt=valuegt lttdgt

- 48 -

lttdgt ltportletAPIactionURL var=removeUrlgt

ltportletAPIparam name=remove value=lt=namegtgt

ltportletAPIactionURLgt

lta href=lt=removeUrltoString()gtgt(ltfmtmessage key=deletegt)ltagt

lttdgt

lttrgt

lt

gt

ltform action=lt=addUrlgt method=POSTgt

lttr class=wpsTableRowgt

lttdgtltinput name=name type=text class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=value type=text class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=add type=submit value=ltfmtmessage key=addgt

class=portlet-form-buttongtlttdgt

lttrgt

ltformgt

lttablegt

ltform action=lt=cancelUrlgt method=postgt

ltinput name=cancel type=submit value=ltfmtmessage key=cancelgt class=portlet-

form-buttongt

ltformgt

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 14 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 -

- 51 -

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 (eg eventing) the IBM Portlet API still needs to be used Trademarks bull IBM and WebSphere are trademarks or registered trademarks of IBM Corporation in

the United States other countries or both bull 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 bull Other company product and service names may be trademarks or service marks of

others IBM copyright and trademark information httpwwwibmcomlegalcopytradephtml

  • Introduction
  • JSR 168 and the Java Community Process
  • Comparing concepts
    • Basic concepts
      • Portal
      • Portal page
      • Portlet
      • Portlet Container
        • Concepts that are the same
          • Portlet mode
          • Window state
          • Portlet life cycle and request processing
          • URL encoding
          • Include servletsJSPs
          • Portlet application packaging
          • Expiration-based caching
            • Concepts that differ
              • Portlet application entity
              • Portlet entity
              • Action and Render Request Response objects
              • Window concept
              • Portlet API does not extend servlet API
              • TAG libraries
                • Concepts new in the JSR 168
                  • Render parameter
                  • Extension mechanisms
                    • Custom window states
                    • Custom portlet modes
                    • Custom user info
                    • Request Response properties
                      • Web application session scope
                      • Reuse of the HttpSession listeners
                      • J2EE role support
                      • Resource bundles
                      • Multiple response content types
                      • Redirect in action
                      • Preference validator
                      • Portal context
                      • Localization support
                        • Concepts missing in the JSR 168
                          • Eventing
                          • Additional lifecycle events
                          • Property broker
                          • Portlet Menus
                          • Portlet Services
                          • Invalidation-based caching
                            • Alignment with WSRP
                              • Outlook for the next version of the JSR 168
                              • Guidelines for programming IBM Portlet API portlets
                                • Similar Functionality
                                  • Basic programming model
                                  • Portlet private session
                                  • User profile information
                                  • Persistent data
                                  • Portlet modes and window states
                                  • Expiration-based caching
                                    • Slightly different functionality
                                      • Sharing of data between portlets
                                      • Session listeners
                                        • New JSR 168 functionality
                                          • Navigational state (render parameters)
                                            • Pitfalls
                                              • Request response objects for action and render phase
                                              • Include search path
                                              • Form parameter encoding
                                              • Title setting
                                                  • Examples
                                                    • IBM Portlet API Portlet Code
                                                    • JSR 168 Portlet Code
                                                    • IBM Portlet API JSPs
                                                    • JSR 168 JSPs
                                                      • Summary
Page 12: Difference Bw Jsr168 and Ibm

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

325 Include servletsJSPs

In both APIrsquos 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()

contextinclude(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)

rdinclude(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 HttpServetRequestgetSession() 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

326 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 (webxml) and one to specify the portlet resources (portletxml) All web resources that are not portlets must be specified in the webxml deployment descriptor All portlets and portlet related settings must be specified in an additional file called portletxml

- 12 -

Different from JSR 168 in the IBM Portlet API all portlets must also be listed in the webxml as they are also servlets (see also 335 for examples of the deployment descitptors)

327 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

33 Concepts that differ

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

331 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 webxml and concrete portlet applications of concrete portlets based on the abstract ones The following portletxml example shows these two different parts

IBM PORTLET API PORTLETXML EXAMPLE

ltxml version=10 encoding=UTF-8gt

ltDOCTYPE portlet-app-def PUBLIC -IBMDTD Portlet Application 11EN

portlet_11dtdgt

ltportlet-app-defgt

ltportlet-app uid=commycobookmark1234 major-version=7 minor-version=24gt

ltportlet-app-namegtBookmark Application7ltportlet-app-namegt

ltportlet id=Portlet_1 href=WEB-INFwebxmlServlet_1gt

- 13 -

ltportlet-namegtBookmark Portlet7ltportlet-namegt

ltallowsgt

ltmaximizedgt

ltminimizedgt

ltallowsgt

ltsupportsgt

ltmarkup name=htmlgt

ltview output=fragmentgt

ltedit output=fragmentgt

ltmarkupgt

ltsupportsgt

ltportletgt

ltportlet-appgt

ltconcrete-portlet-app uid=commycobookmark12341gt

ltportlet-app-namegtConcreteSamplets_Bookmark7ltportlet-app-namegt

ltconcrete-portlet href=Portlet_1gt

ltportlet-namegtBookmark Portlet7ltportlet-namegt

ltdefault-localegtenltdefault-localegt

ltlanguage locale=engt

lttitlegtMy Bookmarks7lttitlegt

lttitle-shortgtBookmarks7lttitle-shortgt

ltdescriptiongtPortlet showing your personalized bookmarksltdescriptiongt

ltkeywordsgtbookmarksltkeywordsgt

ltlanguagegt

ltconfig-paramgt

ltparam-namegturl1ltparam-namegt

ltparam-valuegthttpwwwgooglecomltparam-valuegt

ltconfig-paramgt

ltconcrete-portletgt

- 14 -

ltconcrete-portlet-appgt

ltportlet-app-defgt

As portlets are servlets in the IBM Portlet API the portletxml has references for each portlet to the servlet in the webxml that represents the portlet The webxml for this example is

IBM PORTLET API WEBXML EXAMPLE

ltxml version=10 encoding=UTF-8gt

ltDOCTYPE web-app

PUBLIC -Sun Microsystems IncDTD Web Application 22EN

httpjavasuncomj2eedtdsweb-app_22dtdgt

ltweb-app id=WebApp_1gt

ltdisplay-namegtbookmark7ltdisplay-namegt

ltservlet id=Servlet_1gt

ltservlet-namegtBookmark7ltservlet-namegt

ltservlet-classgtcommycobookmarkBookmarkPortletltservlet-classgt

ltinit-paramgt

ltparam-namegtjspviewltparam-namegt

ltparam-valuegtbookmarkViewjspltparam-valuegt

ltinit-paramgt

ltinit-paramgt

ltparam-namegtjspeditltparam-namegt

ltparam-valuegtbookmarkEditjspltparam-valuegt

ltinit-paramgt

ltservletgt

ltservlet-mappinggt

ltservlet-namegtBookmark7ltservlet-namegt

lturl-patterngtBookmark7lturl-patterngt

ltservlet-mappinggt

ltweb-appgt

- 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 webxml and not in the portletxml In the JSR 168 the deployment descriptor is more like the webxml 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 portletxml example would look like when using the JSR 168 deployment descriptor format

JSR 168 PORTLETXML EXAMPLE

ltxml version=10 encoding=UTF-8gt

ltxml version=10encoding=UTF-8gt

ltportlet-app xmlns=httpjavasuncomxmlnsportletportlet-app_1_0xsd version=10

xmlnsxsi=httpwwww3org2001XMLSchema-instance

xsischemaLocation=httpjavasuncomxmlnsportlet-app_1_0xsd

httpjavasuncomxmlnsportletportlet-app_1_0xsdgt

ltportletgt

ltdescription xmllang=ENgtPortlet showing your personalized

bookmarksltdescriptiongt

ltportlet-namegtBookmark Portlet7ltportlet-namegt

ltdisplay-name xmllang=ENgtBookmark Portletltdisplay-namegt

ltportlet-classgtcommycobookmarkBookmarkPortletltportlet-classgt

ltinit-paramgt

ltnamegtjspviewltnamegt

ltvaluegtbookmarkViewjspltvaluegt

ltinit-paramgt

ltinit-paramgt

ltnamegtjspeditltnamegt

ltvaluegtbookmarkEditjspltvaluegt

ltinit-paramgt

ltsupportsgt

ltmime-typegttexthtmlltmime-typegt

ltportlet-modegtviewltportlet-modegt

- 16 -

ltportlet-modegteditltportlet-modegt

ltsupportsgt

ltsupported-localegtENltsupported-localegt

ltportlet-infogt

lttitlegtMy Bookmarks7lttitlegt

ltshort-titlegtBookmarks7ltshort-titlegt

ltkeywordsgtbookmarksltkeywordsgt

ltportlet-infogt

ltportlet-preferencesgt

ltpreferencegt

ltnamegturl1ltnamegt

ltvaluegthttpwwwgooglecomltvaluegt

ltpreferencegt

ltportlet-preferencesgt

ltportletgt

ltportlet-appgt

Here the initialization parameters are directly specified in the portletxml as portlets are independent components in the JSR 168 The following example represents the webxml for the JSR 168 bookmark portlet

JSR 168 WEBXML EXAMPLE

ltxml version=10 encoding=UTF-8gt

ltDOCTYPE web-app PUBLIC -Sun Microsystems IncDTD Web Application 23EN

httpjavasuncomdtdweb-app_2_3dtdgt

ltweb-appgt

ltdisplay-namegtBookmark Application7ltdisplay-namegt

ltweb-appgt

The only item that needs to be specified in the JSR 168 webxml 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 portletxml as portlet application name as there can be several concrete instances of the same abstract application

- 17 -

332 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 331) 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 331) 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

333 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

334 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 instanceentity 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 -

335 Portlet API does not extend servlet API

In the IBM Portlet API portlets extend servlets and all the major interfaces (Request Response Session hellip) 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

336 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

bull defineObjects tag ndash to define the basic portlet API objects RenderRequest RenderResponse and PortletConfig

bull actionURL tag ndash to create an action URL bull renderURL tag ndash to create a render URL bull namespace tag ndash 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 donrsquot need decoding

34 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 -

341 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 (eg 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

342 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

3421 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

3422 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 322) 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

3423 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

3424 Request Response properties

Properties can be used by the portalportlet container to send vendor specific information to the portlet andor the portlet can send vendor specific information to the portalportlet-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

343 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 (eg between portlets or between a portlet and a servlet)

344 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 23 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

345 J2EE role support

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

346 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 -

347 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 PortletRequestgetResponseContentTypes 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 (eg ldquotextrdquo or ldquordquo) 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

348 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 (eg an accounting servlet) in response to an action

349 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

3410 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 vendorrsquos 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)

3411 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 xmllang attribute like the

- 22 -

servlet 24 deployment descriptor Thus the same tag with descriptions in different languages can be used (eg 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

35 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)

351 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

bull ActionEventThe action event maps to the action phase call in the JSR 168

bull MessageEventMessage 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)

bull PortletApplicationSettingsAttributeEventPortletSettingsAttributeEventThese are events that get fired when attributes for the application or of the portlet settings change

bull WindowEventThe portlet will register for window events to get notified if the portlet window is changed via the window decorations

352 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 -

bull PortletPageListener The page listeners provides the portlet with events for the beginning of the page before any markup is written for this page (eg to write JavaScript at the beginning of the page) and the end of the page after all markup is written

bull 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 23 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

bull EventPhaseListener The event phase listener notifies the portlet of the beginning and end of the eventaction phase

353 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

354 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 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

Figure 4

- 24 -

Figure 4 Portlet menu example

355 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

356 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 -

36 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 indicates portlet in what mode to operate for a given request

View edit help + custom modes

view edit help + custom modes

full alignment

Window State the state of the window in which the portlet output will be displayed

minimized normal maximized solo +

custom window states

minimized normal maximized +

custom window states

full alignment (ldquosolordquo is missing in the JSR but can be implemented as a custom state)

URL encoding to allow re-writing URLs created by the portlet

defines how to create URLs to allow re-writing of the URLs either on consumer or producer side

encapsulates URL creation via a Java object

full alignment (the implementation of the Java object can implement the WSRP URL rewriting rules)

Namespace encoding to avoid that several portlets on a page conflicting with each other

defines namespace prefixes for consumer and producer side namespacing

provides a Java method to namespace a String

full alignment (the JSR namespace method can implement the WSRP namespace behavior)

User ndash portlet interaction operations

performBlockingInteraction blocking action processing

getMarkup render the markup

action blocking action processing

render render the makup

full alignment (action invocations carried through performBlockingInteraction render carried through getMarkup)

View state that allows the current portlet fragment to be correctly displayed in sub-sequent render calls

navigational state render parameter full alignment (WSRP navigational state maps to JSR render parameters)

Storing transient state across request

session state concept implemented via a sessionID

utilizes the Http web application session

full alignment (the WSRP sessionID can be used to reference the JSR session)

Storing persistent state to personalize the rendering of the portlet

allows to have properties of arbitrary types

provides String-based preferences

full alignment (JSR String preferences can be mapped to WSRP properties)

Information about the portal calling the portlet

RegistrationData provide information of the consumer to the producer

PortalContext provide a Java interface to access information about the portal calling the portlet

full alignment (all data represented through the PortalContext to the JSR portlet are available in the RegistrationData)

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

Aggregated HTML WML VoiceXML

over HTTPMark-Up Fragments

Transferred via WSRP

Portal

WSRP Service

WSRP Service

WSRP Service

WSRP Consumer WSRP Producer

Use of WSRP Services in Portals

Portal sharing Portlets as WSRP Services

ServerPortalPortals

Huge numberof users Publishing Portal

WSRPWrapperPortalsPortalsPortal

Portlet

Portlet

Portlet

WSRP Consumer WSRP Producer

ProxyPortlet

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

bull 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

bull 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

bull 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

bull 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 CCPP standard allowing a portlet to query the client capabilities and adopting its markup accordingly (eg screen size browser) This API is likely to be included in the next version of the portlet API Also J2EE 14 was finalized during this time period J2EE 14 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 14

bull caching The first version of the JSR 168 API is limited to expiration-based caching (see section 327) 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

bull 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

51 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

511 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

bull portlets are components Portlets are components that implement a specific function Different functions should be distributed to different portlets

bull 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

bull 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

512 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 HttpServletRequestgetSession() call in the JSPs called via the IBM Portlet API needs to be replaced when moving to JSR 168 portlets by the RenderRequestgetPortletSession() 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 HttpServletRequestgetSession() will get the HttpSession and therefore need to access the portlet session via the RenderRequest

513 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

514 Persistent data

Portlets can store customization and personalization data persistently Customization data are related to the portlet and are valid for all users (eg 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 (eg 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

515 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

516 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

52 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

521 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 351 353) 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

522 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

53 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 -

531 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

bull no support of the back button in the browser bull current state of the portlet is not bookmarkable bull 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 bull 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

54 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

541 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 -

542 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

543 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

544 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 wersquoll 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

Figure 7After clicking on the Edit mode button the portlet renders the Edit view shown in

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

Figure 8

After we press the ldquoAddrdquo 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

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

bull use JSPs for rendering the output bull customize the portlet output taking user specific data into account bull 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

61 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 comibmwpssampleswp5

import javaio

import javautil

import orgapachejetspeedportlet

import orgapachejetspeedportletevent

public class IbmBookmark extends PortletAdapter implements ActionListener

public void init(PortletConfig portletConfig) throws UnavailableException

superinit(portletConfig)

- 36 -

public void doView(PortletRequest request PortletResponse response)

throws PortletException IOException

String jspName = thisgetPortletConfig()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 = responsecreateReturnURI()

addURIaddAction(add)

requestsetAttribute(addURI addURItoString())

PortletURI cancelURI = responsecreateReturnURI()

requestsetAttribute(cancelURI cancelURItoString())

String jspName = thisgetPortletConfig()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 ldquocancelrdquo and ldquoaddrdquo URLs are created inside the portlet and attached to the request before including the Edit JSP Both URLs are from type ldquoReturnURIrdquo 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 = eventgetRequest()

String action = eventgetActionString()

PortletLog log = getPortletLog()

if ( action=null )

try

if (actionequals(removeURI))

String removeName = requestgetParameter(remove)

PortletData portData = requestgetData()

portDataremoveAttribute(removeName)

portDatastore()

if (actionequals(add))

PortletData portData = requestgetData()

String name = requestgetParameter(name)

String value = requestgetParameter(value)

portDatasetAttribute(name value)

portDatastore()

catch ( AccessDeniedException ade )

logerror(AccessDeniedException occured when adding or deleting a bookmark)

catch ( IOException ioe )

logerror(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 ldquoaddrdquo or ldquodeleterdquo 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 ldquoaddrdquo or ldquoremoveURIrdquo If the user has clicked on the ldquoremoverdquo button the corresponding link is removed from the portlet data whereas if ldquoaddrdquo was clicked the data entered by the user is added to the portlet data

62 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 comibmwpssamplesjsr

import javaio

import javaxportlet

public class Bookmark extends GenericPortlet

public void init(PortletConfig config) throws PortletException

superinit(config)

public void doView(RenderRequest request RenderResponse response)

throws PortletException IOException

responsesetContentType(texthtml)

String jspName = getPortletConfig()getInitParameter(jspView)

PortletRequestDispatcher rd = getPortletContext()getRequestDispatcher(jspName)

rdinclude(requestresponse)

- 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

responsesetContentType(texthtml)

PortletURL addUrl = responsecreateActionURL()

addUrlsetPortletMode(PortletModeVIEW)

addUrlsetParameter(addadd)

requestsetAttribute(addUrladdUrltoString())

PortletURL cancelUrl = responsecreateRenderURL()

cancelUrlsetPortletMode(PortletModeVIEW)

requestsetAttribute(cancelUrlcancelUrltoString())

String jspName = getPortletConfig()getInitParameter(jspEdit)

PortletRequestDispatcher rd = getPortletContext()getRequestDispatcher(jspName)

rdinclude(requestresponse)

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 ldquoaddrdquo button URL an action URL is created as we need to store the user input of the add form persistently For the ldquocancelrdquo 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 = requestgetParameter(remove)

if (removeName = null)

PortletPreferences prefs = requestgetPreferences()

prefsreset(removeName)

prefsstore()

String add = requestgetParameter(add)

if (add = null)

PortletPreferences prefs = requestgetPreferences()

String name = requestgetParameter(name)

String value = requestgetParameter(value)

prefssetValue(name value)

prefsstore()

catch ( IOException ioe )

getPortletContextlog(An IO error occured when trying to remove a bookmark)

catch ( PortletException pe )

getPortletContextlog(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

bull 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

bull 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

bull Persistent portlet data The JSR 168 persistent data PortletPreferences have an API similar to the JDK 14 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

bull 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

63 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

lt page contentType=texthtml import=javautil comibmwpssampleswp5

orgapachejetspeedportlet session=falsegt

lt taglib uri=WEB-INFtldportlettld prefix=portletAPI gt

- 42 -

ltportletAPIinitgt

ltp class=wpsPortletHeadgtltportletAPItext key=available_bookmarks

bundle=nlsTextgtAvailable BookmarksltportletAPItextgtltpgt

lt

PortletData prefs = portletRequestgetData()

Enumeration e = prefsgetAttributeNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltportletAPItext key=no_bookmarks bundle=nlsTextgtNo

bookmarksltportletAPItextgtltpgt

lt

else

gt

ltp class=wpsIndentMediumgt

lt

while (ehasMoreElements())

String name = (String)enextElement()

String value = (String)prefsgetAttribute(name)

gt

lta href=lt=valuegt target=_blankgtlt=namegtltagtltbr gt

lt

gt

ltpgt

The View JSP first call portletAPIinit 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

lt page contentType=texthtml import=javautil

comibmwpssampleswp5orgapachejetspeedportlet session=falsegt

lt taglib uri=WEB-INFtldportlettld prefix=portletAPI gt

ltjspuseBean id=addURI class=javalangString scope=request gt

ltjspuseBean id=cancelURI class=javalangString scope=request gt

ltportletAPIinitgt

lth4gtltportletAPItext key=available_bookmarks bundle=nlsTextgtAvailable

BookmarksltportletAPItextgtlth4gt

lttable class=wpsTablegt

lttr class=wpsTableRowgt

ltth class=portlet-table-headergtltportletAPItext key=name bundle=nlsTextgtltthgt

ltth class=portlet-table-headergtltportletAPItext key=url bundle=nlsTextgtltthgt

lttdgtlttdgt

lttrgt

lt

PortletData prefs = portletRequestgetData()

Enumeration e = prefsgetAttributeNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltportletAPItext key=no_bookmarks bundle=nlsTextgtNo

bookmarksltportletAPItextgtltpgt

lt

else

while (ehasMoreElements())

- 44 -

String name = (String)enextElement()

String value = (String)prefsgetAttribute(name)

gt

lttr class=wpsTableRowgt

lttdgt lt=namegt lttdgt

lttdgt lt=valuegt lttdgt

lttdgt lta href=ltportletAPIcreateURIgtltportletAPIURIAction

name=removeURIgtltportletAPIURIParameter name=remove

value=lt=namegtgtltportletAPIcreateURIgtgt

(ltportletAPItext key=delete bundle=nlsTextgt)ltagt

lttdgt

lttrgt

lt

gt

ltform action=lt=addURIgt method=POSTgt

lttr class=wpsTableRowgt

lttdgtltinput name=ltportletAPIencodeNamespace value=namegt type=text

class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=ltportletAPIencodeNamespace value=valuegt type=text

class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=ltportletAPIencodeNamespace value=addgt type=submit

value=ltportletAPItext key=add bundle=nlsTextgt class=portlet-form-buttongtlttdgt

lttrgt

ltformgt

lttablegt

- 45 -

ltform action=lt=cancelURIgt method=postgt

ltinput name=ltportletAPIencodeNamespace value=cancelgt type=submit

value=ltportletAPItext key=cancel bundle=nlsTextgt class=portlet-form-buttongt

ltformgt

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 ldquodeleterdquo button for which an URL with the action ldquoremoveURIrdquo 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 ldquocancelrdquo button from the request

64 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

lt page import=javaxportlet javautil session=falsegt

lt taglib uri=httpjavasuncomportlet prefix=portletAPI gt

lt taglib prefix=fmt uri=httpjavasuncomjstlfmt gt

ltportletAPIdefineObjects gt

ltfmtsetBundle basename=nlsTextgt

lt

ResourceBundle myText = ResourceBundlegetBundle(nlsText requestgetLocale())

gt

lth4gtltfmtmessage key=available_bookmarksgtlth4gt

lt

PortletPreferences prefs = renderRequestgetPreferences()

Enumeration e = prefsgetNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltfmtmessage key=no_bookmarksgtltpgt

- 46 -

lt

else

gt

ltpgt

lt

while (ehasMoreElements())

String name = (String)enextElement()

String value = prefsgetValue(namelt+myTextgetString(undefined)+gt)

gt

lta href=lt=valuegt target=_blankgtlt=namegtltagtltbr gt

lt

gt

ltpgt

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 fmtmessage 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

lt page import=javaxportlet javautil session=false gt

lt taglib uri=httpjavasuncomportlet prefix=portletAPI gt

lt taglib prefix=fmt uri=httpjavasuncomjstlfmt gt

ltjspuseBean id=addUrl scope=request class=javalangString gt

ltjspuseBean id=cancelUrl scope=request class=javalangString gt

- 47 -

ltportletAPIdefineObjectsgt

lt

ResourceBundle myText = ResourceBundlegetBundle(nlsText requestgetLocale())

gt

ltfmtsetBundle basename=nlsTextgt

lth4gtltfmtmessage key=available_bookmarksgtlth4gt

lttable class=wpsTablegt

lttr class=wpsTableRowgt

ltth class=wpsTableHeadgtltfmtmessage key=namegtltthgt

ltth class=wpsTableHeadgtltfmtmessage key=urlgtltthgt

lttdgtlttdgt

lttrgt

lt

PortletPreferences prefs = renderRequestgetPreferences()

Enumeration e = prefsgetNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltfmtmessage key=no_bookmarksgtltpgt

lt

else

while (ehasMoreElements())

String name = (String)enextElement()

String value = prefsgetValue(namelt+myTextgetString(undefined)+gt)

gt

lttr class=wpsTableRowgt

lttdgt lt=namegt lttdgt

lttdgt lt=valuegt lttdgt

- 48 -

lttdgt ltportletAPIactionURL var=removeUrlgt

ltportletAPIparam name=remove value=lt=namegtgt

ltportletAPIactionURLgt

lta href=lt=removeUrltoString()gtgt(ltfmtmessage key=deletegt)ltagt

lttdgt

lttrgt

lt

gt

ltform action=lt=addUrlgt method=POSTgt

lttr class=wpsTableRowgt

lttdgtltinput name=name type=text class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=value type=text class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=add type=submit value=ltfmtmessage key=addgt

class=portlet-form-buttongtlttdgt

lttrgt

ltformgt

lttablegt

ltform action=lt=cancelUrlgt method=postgt

ltinput name=cancel type=submit value=ltfmtmessage key=cancelgt class=portlet-

form-buttongt

ltformgt

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 14 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 -

- 51 -

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 (eg eventing) the IBM Portlet API still needs to be used Trademarks bull IBM and WebSphere are trademarks or registered trademarks of IBM Corporation in

the United States other countries or both bull 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 bull Other company product and service names may be trademarks or service marks of

others IBM copyright and trademark information httpwwwibmcomlegalcopytradephtml

  • Introduction
  • JSR 168 and the Java Community Process
  • Comparing concepts
    • Basic concepts
      • Portal
      • Portal page
      • Portlet
      • Portlet Container
        • Concepts that are the same
          • Portlet mode
          • Window state
          • Portlet life cycle and request processing
          • URL encoding
          • Include servletsJSPs
          • Portlet application packaging
          • Expiration-based caching
            • Concepts that differ
              • Portlet application entity
              • Portlet entity
              • Action and Render Request Response objects
              • Window concept
              • Portlet API does not extend servlet API
              • TAG libraries
                • Concepts new in the JSR 168
                  • Render parameter
                  • Extension mechanisms
                    • Custom window states
                    • Custom portlet modes
                    • Custom user info
                    • Request Response properties
                      • Web application session scope
                      • Reuse of the HttpSession listeners
                      • J2EE role support
                      • Resource bundles
                      • Multiple response content types
                      • Redirect in action
                      • Preference validator
                      • Portal context
                      • Localization support
                        • Concepts missing in the JSR 168
                          • Eventing
                          • Additional lifecycle events
                          • Property broker
                          • Portlet Menus
                          • Portlet Services
                          • Invalidation-based caching
                            • Alignment with WSRP
                              • Outlook for the next version of the JSR 168
                              • Guidelines for programming IBM Portlet API portlets
                                • Similar Functionality
                                  • Basic programming model
                                  • Portlet private session
                                  • User profile information
                                  • Persistent data
                                  • Portlet modes and window states
                                  • Expiration-based caching
                                    • Slightly different functionality
                                      • Sharing of data between portlets
                                      • Session listeners
                                        • New JSR 168 functionality
                                          • Navigational state (render parameters)
                                            • Pitfalls
                                              • Request response objects for action and render phase
                                              • Include search path
                                              • Form parameter encoding
                                              • Title setting
                                                  • Examples
                                                    • IBM Portlet API Portlet Code
                                                    • JSR 168 Portlet Code
                                                    • IBM Portlet API JSPs
                                                    • JSR 168 JSPs
                                                      • Summary
Page 13: Difference Bw Jsr168 and Ibm

Different from JSR 168 in the IBM Portlet API all portlets must also be listed in the webxml as they are also servlets (see also 335 for examples of the deployment descitptors)

327 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

33 Concepts that differ

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

331 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 webxml and concrete portlet applications of concrete portlets based on the abstract ones The following portletxml example shows these two different parts

IBM PORTLET API PORTLETXML EXAMPLE

ltxml version=10 encoding=UTF-8gt

ltDOCTYPE portlet-app-def PUBLIC -IBMDTD Portlet Application 11EN

portlet_11dtdgt

ltportlet-app-defgt

ltportlet-app uid=commycobookmark1234 major-version=7 minor-version=24gt

ltportlet-app-namegtBookmark Application7ltportlet-app-namegt

ltportlet id=Portlet_1 href=WEB-INFwebxmlServlet_1gt

- 13 -

ltportlet-namegtBookmark Portlet7ltportlet-namegt

ltallowsgt

ltmaximizedgt

ltminimizedgt

ltallowsgt

ltsupportsgt

ltmarkup name=htmlgt

ltview output=fragmentgt

ltedit output=fragmentgt

ltmarkupgt

ltsupportsgt

ltportletgt

ltportlet-appgt

ltconcrete-portlet-app uid=commycobookmark12341gt

ltportlet-app-namegtConcreteSamplets_Bookmark7ltportlet-app-namegt

ltconcrete-portlet href=Portlet_1gt

ltportlet-namegtBookmark Portlet7ltportlet-namegt

ltdefault-localegtenltdefault-localegt

ltlanguage locale=engt

lttitlegtMy Bookmarks7lttitlegt

lttitle-shortgtBookmarks7lttitle-shortgt

ltdescriptiongtPortlet showing your personalized bookmarksltdescriptiongt

ltkeywordsgtbookmarksltkeywordsgt

ltlanguagegt

ltconfig-paramgt

ltparam-namegturl1ltparam-namegt

ltparam-valuegthttpwwwgooglecomltparam-valuegt

ltconfig-paramgt

ltconcrete-portletgt

- 14 -

ltconcrete-portlet-appgt

ltportlet-app-defgt

As portlets are servlets in the IBM Portlet API the portletxml has references for each portlet to the servlet in the webxml that represents the portlet The webxml for this example is

IBM PORTLET API WEBXML EXAMPLE

ltxml version=10 encoding=UTF-8gt

ltDOCTYPE web-app

PUBLIC -Sun Microsystems IncDTD Web Application 22EN

httpjavasuncomj2eedtdsweb-app_22dtdgt

ltweb-app id=WebApp_1gt

ltdisplay-namegtbookmark7ltdisplay-namegt

ltservlet id=Servlet_1gt

ltservlet-namegtBookmark7ltservlet-namegt

ltservlet-classgtcommycobookmarkBookmarkPortletltservlet-classgt

ltinit-paramgt

ltparam-namegtjspviewltparam-namegt

ltparam-valuegtbookmarkViewjspltparam-valuegt

ltinit-paramgt

ltinit-paramgt

ltparam-namegtjspeditltparam-namegt

ltparam-valuegtbookmarkEditjspltparam-valuegt

ltinit-paramgt

ltservletgt

ltservlet-mappinggt

ltservlet-namegtBookmark7ltservlet-namegt

lturl-patterngtBookmark7lturl-patterngt

ltservlet-mappinggt

ltweb-appgt

- 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 webxml and not in the portletxml In the JSR 168 the deployment descriptor is more like the webxml 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 portletxml example would look like when using the JSR 168 deployment descriptor format

JSR 168 PORTLETXML EXAMPLE

ltxml version=10 encoding=UTF-8gt

ltxml version=10encoding=UTF-8gt

ltportlet-app xmlns=httpjavasuncomxmlnsportletportlet-app_1_0xsd version=10

xmlnsxsi=httpwwww3org2001XMLSchema-instance

xsischemaLocation=httpjavasuncomxmlnsportlet-app_1_0xsd

httpjavasuncomxmlnsportletportlet-app_1_0xsdgt

ltportletgt

ltdescription xmllang=ENgtPortlet showing your personalized

bookmarksltdescriptiongt

ltportlet-namegtBookmark Portlet7ltportlet-namegt

ltdisplay-name xmllang=ENgtBookmark Portletltdisplay-namegt

ltportlet-classgtcommycobookmarkBookmarkPortletltportlet-classgt

ltinit-paramgt

ltnamegtjspviewltnamegt

ltvaluegtbookmarkViewjspltvaluegt

ltinit-paramgt

ltinit-paramgt

ltnamegtjspeditltnamegt

ltvaluegtbookmarkEditjspltvaluegt

ltinit-paramgt

ltsupportsgt

ltmime-typegttexthtmlltmime-typegt

ltportlet-modegtviewltportlet-modegt

- 16 -

ltportlet-modegteditltportlet-modegt

ltsupportsgt

ltsupported-localegtENltsupported-localegt

ltportlet-infogt

lttitlegtMy Bookmarks7lttitlegt

ltshort-titlegtBookmarks7ltshort-titlegt

ltkeywordsgtbookmarksltkeywordsgt

ltportlet-infogt

ltportlet-preferencesgt

ltpreferencegt

ltnamegturl1ltnamegt

ltvaluegthttpwwwgooglecomltvaluegt

ltpreferencegt

ltportlet-preferencesgt

ltportletgt

ltportlet-appgt

Here the initialization parameters are directly specified in the portletxml as portlets are independent components in the JSR 168 The following example represents the webxml for the JSR 168 bookmark portlet

JSR 168 WEBXML EXAMPLE

ltxml version=10 encoding=UTF-8gt

ltDOCTYPE web-app PUBLIC -Sun Microsystems IncDTD Web Application 23EN

httpjavasuncomdtdweb-app_2_3dtdgt

ltweb-appgt

ltdisplay-namegtBookmark Application7ltdisplay-namegt

ltweb-appgt

The only item that needs to be specified in the JSR 168 webxml 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 portletxml as portlet application name as there can be several concrete instances of the same abstract application

- 17 -

332 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 331) 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 331) 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

333 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

334 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 instanceentity 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 -

335 Portlet API does not extend servlet API

In the IBM Portlet API portlets extend servlets and all the major interfaces (Request Response Session hellip) 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

336 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

bull defineObjects tag ndash to define the basic portlet API objects RenderRequest RenderResponse and PortletConfig

bull actionURL tag ndash to create an action URL bull renderURL tag ndash to create a render URL bull namespace tag ndash 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 donrsquot need decoding

34 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 -

341 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 (eg 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

342 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

3421 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

3422 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 322) 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

3423 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

3424 Request Response properties

Properties can be used by the portalportlet container to send vendor specific information to the portlet andor the portlet can send vendor specific information to the portalportlet-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

343 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 (eg between portlets or between a portlet and a servlet)

344 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 23 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

345 J2EE role support

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

346 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 -

347 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 PortletRequestgetResponseContentTypes 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 (eg ldquotextrdquo or ldquordquo) 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

348 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 (eg an accounting servlet) in response to an action

349 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

3410 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 vendorrsquos 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)

3411 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 xmllang attribute like the

- 22 -

servlet 24 deployment descriptor Thus the same tag with descriptions in different languages can be used (eg 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

35 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)

351 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

bull ActionEventThe action event maps to the action phase call in the JSR 168

bull MessageEventMessage 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)

bull PortletApplicationSettingsAttributeEventPortletSettingsAttributeEventThese are events that get fired when attributes for the application or of the portlet settings change

bull WindowEventThe portlet will register for window events to get notified if the portlet window is changed via the window decorations

352 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 -

bull PortletPageListener The page listeners provides the portlet with events for the beginning of the page before any markup is written for this page (eg to write JavaScript at the beginning of the page) and the end of the page after all markup is written

bull 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 23 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

bull EventPhaseListener The event phase listener notifies the portlet of the beginning and end of the eventaction phase

353 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

354 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 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

Figure 4

- 24 -

Figure 4 Portlet menu example

355 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

356 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 -

36 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 indicates portlet in what mode to operate for a given request

View edit help + custom modes

view edit help + custom modes

full alignment

Window State the state of the window in which the portlet output will be displayed

minimized normal maximized solo +

custom window states

minimized normal maximized +

custom window states

full alignment (ldquosolordquo is missing in the JSR but can be implemented as a custom state)

URL encoding to allow re-writing URLs created by the portlet

defines how to create URLs to allow re-writing of the URLs either on consumer or producer side

encapsulates URL creation via a Java object

full alignment (the implementation of the Java object can implement the WSRP URL rewriting rules)

Namespace encoding to avoid that several portlets on a page conflicting with each other

defines namespace prefixes for consumer and producer side namespacing

provides a Java method to namespace a String

full alignment (the JSR namespace method can implement the WSRP namespace behavior)

User ndash portlet interaction operations

performBlockingInteraction blocking action processing

getMarkup render the markup

action blocking action processing

render render the makup

full alignment (action invocations carried through performBlockingInteraction render carried through getMarkup)

View state that allows the current portlet fragment to be correctly displayed in sub-sequent render calls

navigational state render parameter full alignment (WSRP navigational state maps to JSR render parameters)

Storing transient state across request

session state concept implemented via a sessionID

utilizes the Http web application session

full alignment (the WSRP sessionID can be used to reference the JSR session)

Storing persistent state to personalize the rendering of the portlet

allows to have properties of arbitrary types

provides String-based preferences

full alignment (JSR String preferences can be mapped to WSRP properties)

Information about the portal calling the portlet

RegistrationData provide information of the consumer to the producer

PortalContext provide a Java interface to access information about the portal calling the portlet

full alignment (all data represented through the PortalContext to the JSR portlet are available in the RegistrationData)

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

Aggregated HTML WML VoiceXML

over HTTPMark-Up Fragments

Transferred via WSRP

Portal

WSRP Service

WSRP Service

WSRP Service

WSRP Consumer WSRP Producer

Use of WSRP Services in Portals

Portal sharing Portlets as WSRP Services

ServerPortalPortals

Huge numberof users Publishing Portal

WSRPWrapperPortalsPortalsPortal

Portlet

Portlet

Portlet

WSRP Consumer WSRP Producer

ProxyPortlet

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

bull 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

bull 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

bull 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

bull 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 CCPP standard allowing a portlet to query the client capabilities and adopting its markup accordingly (eg screen size browser) This API is likely to be included in the next version of the portlet API Also J2EE 14 was finalized during this time period J2EE 14 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 14

bull caching The first version of the JSR 168 API is limited to expiration-based caching (see section 327) 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

bull 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

51 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

511 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

bull portlets are components Portlets are components that implement a specific function Different functions should be distributed to different portlets

bull 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

bull 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

512 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 HttpServletRequestgetSession() call in the JSPs called via the IBM Portlet API needs to be replaced when moving to JSR 168 portlets by the RenderRequestgetPortletSession() 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 HttpServletRequestgetSession() will get the HttpSession and therefore need to access the portlet session via the RenderRequest

513 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

514 Persistent data

Portlets can store customization and personalization data persistently Customization data are related to the portlet and are valid for all users (eg 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 (eg 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

515 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

516 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

52 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

521 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 351 353) 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

522 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

53 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 -

531 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

bull no support of the back button in the browser bull current state of the portlet is not bookmarkable bull 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 bull 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

54 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

541 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 -

542 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

543 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

544 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 wersquoll 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

Figure 7After clicking on the Edit mode button the portlet renders the Edit view shown in

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

Figure 8

After we press the ldquoAddrdquo 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

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

bull use JSPs for rendering the output bull customize the portlet output taking user specific data into account bull 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

61 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 comibmwpssampleswp5

import javaio

import javautil

import orgapachejetspeedportlet

import orgapachejetspeedportletevent

public class IbmBookmark extends PortletAdapter implements ActionListener

public void init(PortletConfig portletConfig) throws UnavailableException

superinit(portletConfig)

- 36 -

public void doView(PortletRequest request PortletResponse response)

throws PortletException IOException

String jspName = thisgetPortletConfig()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 = responsecreateReturnURI()

addURIaddAction(add)

requestsetAttribute(addURI addURItoString())

PortletURI cancelURI = responsecreateReturnURI()

requestsetAttribute(cancelURI cancelURItoString())

String jspName = thisgetPortletConfig()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 ldquocancelrdquo and ldquoaddrdquo URLs are created inside the portlet and attached to the request before including the Edit JSP Both URLs are from type ldquoReturnURIrdquo 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 = eventgetRequest()

String action = eventgetActionString()

PortletLog log = getPortletLog()

if ( action=null )

try

if (actionequals(removeURI))

String removeName = requestgetParameter(remove)

PortletData portData = requestgetData()

portDataremoveAttribute(removeName)

portDatastore()

if (actionequals(add))

PortletData portData = requestgetData()

String name = requestgetParameter(name)

String value = requestgetParameter(value)

portDatasetAttribute(name value)

portDatastore()

catch ( AccessDeniedException ade )

logerror(AccessDeniedException occured when adding or deleting a bookmark)

catch ( IOException ioe )

logerror(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 ldquoaddrdquo or ldquodeleterdquo 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 ldquoaddrdquo or ldquoremoveURIrdquo If the user has clicked on the ldquoremoverdquo button the corresponding link is removed from the portlet data whereas if ldquoaddrdquo was clicked the data entered by the user is added to the portlet data

62 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 comibmwpssamplesjsr

import javaio

import javaxportlet

public class Bookmark extends GenericPortlet

public void init(PortletConfig config) throws PortletException

superinit(config)

public void doView(RenderRequest request RenderResponse response)

throws PortletException IOException

responsesetContentType(texthtml)

String jspName = getPortletConfig()getInitParameter(jspView)

PortletRequestDispatcher rd = getPortletContext()getRequestDispatcher(jspName)

rdinclude(requestresponse)

- 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

responsesetContentType(texthtml)

PortletURL addUrl = responsecreateActionURL()

addUrlsetPortletMode(PortletModeVIEW)

addUrlsetParameter(addadd)

requestsetAttribute(addUrladdUrltoString())

PortletURL cancelUrl = responsecreateRenderURL()

cancelUrlsetPortletMode(PortletModeVIEW)

requestsetAttribute(cancelUrlcancelUrltoString())

String jspName = getPortletConfig()getInitParameter(jspEdit)

PortletRequestDispatcher rd = getPortletContext()getRequestDispatcher(jspName)

rdinclude(requestresponse)

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 ldquoaddrdquo button URL an action URL is created as we need to store the user input of the add form persistently For the ldquocancelrdquo 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 = requestgetParameter(remove)

if (removeName = null)

PortletPreferences prefs = requestgetPreferences()

prefsreset(removeName)

prefsstore()

String add = requestgetParameter(add)

if (add = null)

PortletPreferences prefs = requestgetPreferences()

String name = requestgetParameter(name)

String value = requestgetParameter(value)

prefssetValue(name value)

prefsstore()

catch ( IOException ioe )

getPortletContextlog(An IO error occured when trying to remove a bookmark)

catch ( PortletException pe )

getPortletContextlog(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

bull 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

bull 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

bull Persistent portlet data The JSR 168 persistent data PortletPreferences have an API similar to the JDK 14 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

bull 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

63 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

lt page contentType=texthtml import=javautil comibmwpssampleswp5

orgapachejetspeedportlet session=falsegt

lt taglib uri=WEB-INFtldportlettld prefix=portletAPI gt

- 42 -

ltportletAPIinitgt

ltp class=wpsPortletHeadgtltportletAPItext key=available_bookmarks

bundle=nlsTextgtAvailable BookmarksltportletAPItextgtltpgt

lt

PortletData prefs = portletRequestgetData()

Enumeration e = prefsgetAttributeNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltportletAPItext key=no_bookmarks bundle=nlsTextgtNo

bookmarksltportletAPItextgtltpgt

lt

else

gt

ltp class=wpsIndentMediumgt

lt

while (ehasMoreElements())

String name = (String)enextElement()

String value = (String)prefsgetAttribute(name)

gt

lta href=lt=valuegt target=_blankgtlt=namegtltagtltbr gt

lt

gt

ltpgt

The View JSP first call portletAPIinit 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

lt page contentType=texthtml import=javautil

comibmwpssampleswp5orgapachejetspeedportlet session=falsegt

lt taglib uri=WEB-INFtldportlettld prefix=portletAPI gt

ltjspuseBean id=addURI class=javalangString scope=request gt

ltjspuseBean id=cancelURI class=javalangString scope=request gt

ltportletAPIinitgt

lth4gtltportletAPItext key=available_bookmarks bundle=nlsTextgtAvailable

BookmarksltportletAPItextgtlth4gt

lttable class=wpsTablegt

lttr class=wpsTableRowgt

ltth class=portlet-table-headergtltportletAPItext key=name bundle=nlsTextgtltthgt

ltth class=portlet-table-headergtltportletAPItext key=url bundle=nlsTextgtltthgt

lttdgtlttdgt

lttrgt

lt

PortletData prefs = portletRequestgetData()

Enumeration e = prefsgetAttributeNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltportletAPItext key=no_bookmarks bundle=nlsTextgtNo

bookmarksltportletAPItextgtltpgt

lt

else

while (ehasMoreElements())

- 44 -

String name = (String)enextElement()

String value = (String)prefsgetAttribute(name)

gt

lttr class=wpsTableRowgt

lttdgt lt=namegt lttdgt

lttdgt lt=valuegt lttdgt

lttdgt lta href=ltportletAPIcreateURIgtltportletAPIURIAction

name=removeURIgtltportletAPIURIParameter name=remove

value=lt=namegtgtltportletAPIcreateURIgtgt

(ltportletAPItext key=delete bundle=nlsTextgt)ltagt

lttdgt

lttrgt

lt

gt

ltform action=lt=addURIgt method=POSTgt

lttr class=wpsTableRowgt

lttdgtltinput name=ltportletAPIencodeNamespace value=namegt type=text

class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=ltportletAPIencodeNamespace value=valuegt type=text

class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=ltportletAPIencodeNamespace value=addgt type=submit

value=ltportletAPItext key=add bundle=nlsTextgt class=portlet-form-buttongtlttdgt

lttrgt

ltformgt

lttablegt

- 45 -

ltform action=lt=cancelURIgt method=postgt

ltinput name=ltportletAPIencodeNamespace value=cancelgt type=submit

value=ltportletAPItext key=cancel bundle=nlsTextgt class=portlet-form-buttongt

ltformgt

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 ldquodeleterdquo button for which an URL with the action ldquoremoveURIrdquo 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 ldquocancelrdquo button from the request

64 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

lt page import=javaxportlet javautil session=falsegt

lt taglib uri=httpjavasuncomportlet prefix=portletAPI gt

lt taglib prefix=fmt uri=httpjavasuncomjstlfmt gt

ltportletAPIdefineObjects gt

ltfmtsetBundle basename=nlsTextgt

lt

ResourceBundle myText = ResourceBundlegetBundle(nlsText requestgetLocale())

gt

lth4gtltfmtmessage key=available_bookmarksgtlth4gt

lt

PortletPreferences prefs = renderRequestgetPreferences()

Enumeration e = prefsgetNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltfmtmessage key=no_bookmarksgtltpgt

- 46 -

lt

else

gt

ltpgt

lt

while (ehasMoreElements())

String name = (String)enextElement()

String value = prefsgetValue(namelt+myTextgetString(undefined)+gt)

gt

lta href=lt=valuegt target=_blankgtlt=namegtltagtltbr gt

lt

gt

ltpgt

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 fmtmessage 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

lt page import=javaxportlet javautil session=false gt

lt taglib uri=httpjavasuncomportlet prefix=portletAPI gt

lt taglib prefix=fmt uri=httpjavasuncomjstlfmt gt

ltjspuseBean id=addUrl scope=request class=javalangString gt

ltjspuseBean id=cancelUrl scope=request class=javalangString gt

- 47 -

ltportletAPIdefineObjectsgt

lt

ResourceBundle myText = ResourceBundlegetBundle(nlsText requestgetLocale())

gt

ltfmtsetBundle basename=nlsTextgt

lth4gtltfmtmessage key=available_bookmarksgtlth4gt

lttable class=wpsTablegt

lttr class=wpsTableRowgt

ltth class=wpsTableHeadgtltfmtmessage key=namegtltthgt

ltth class=wpsTableHeadgtltfmtmessage key=urlgtltthgt

lttdgtlttdgt

lttrgt

lt

PortletPreferences prefs = renderRequestgetPreferences()

Enumeration e = prefsgetNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltfmtmessage key=no_bookmarksgtltpgt

lt

else

while (ehasMoreElements())

String name = (String)enextElement()

String value = prefsgetValue(namelt+myTextgetString(undefined)+gt)

gt

lttr class=wpsTableRowgt

lttdgt lt=namegt lttdgt

lttdgt lt=valuegt lttdgt

- 48 -

lttdgt ltportletAPIactionURL var=removeUrlgt

ltportletAPIparam name=remove value=lt=namegtgt

ltportletAPIactionURLgt

lta href=lt=removeUrltoString()gtgt(ltfmtmessage key=deletegt)ltagt

lttdgt

lttrgt

lt

gt

ltform action=lt=addUrlgt method=POSTgt

lttr class=wpsTableRowgt

lttdgtltinput name=name type=text class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=value type=text class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=add type=submit value=ltfmtmessage key=addgt

class=portlet-form-buttongtlttdgt

lttrgt

ltformgt

lttablegt

ltform action=lt=cancelUrlgt method=postgt

ltinput name=cancel type=submit value=ltfmtmessage key=cancelgt class=portlet-

form-buttongt

ltformgt

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 14 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 -

- 51 -

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 (eg eventing) the IBM Portlet API still needs to be used Trademarks bull IBM and WebSphere are trademarks or registered trademarks of IBM Corporation in

the United States other countries or both bull 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 bull Other company product and service names may be trademarks or service marks of

others IBM copyright and trademark information httpwwwibmcomlegalcopytradephtml

  • Introduction
  • JSR 168 and the Java Community Process
  • Comparing concepts
    • Basic concepts
      • Portal
      • Portal page
      • Portlet
      • Portlet Container
        • Concepts that are the same
          • Portlet mode
          • Window state
          • Portlet life cycle and request processing
          • URL encoding
          • Include servletsJSPs
          • Portlet application packaging
          • Expiration-based caching
            • Concepts that differ
              • Portlet application entity
              • Portlet entity
              • Action and Render Request Response objects
              • Window concept
              • Portlet API does not extend servlet API
              • TAG libraries
                • Concepts new in the JSR 168
                  • Render parameter
                  • Extension mechanisms
                    • Custom window states
                    • Custom portlet modes
                    • Custom user info
                    • Request Response properties
                      • Web application session scope
                      • Reuse of the HttpSession listeners
                      • J2EE role support
                      • Resource bundles
                      • Multiple response content types
                      • Redirect in action
                      • Preference validator
                      • Portal context
                      • Localization support
                        • Concepts missing in the JSR 168
                          • Eventing
                          • Additional lifecycle events
                          • Property broker
                          • Portlet Menus
                          • Portlet Services
                          • Invalidation-based caching
                            • Alignment with WSRP
                              • Outlook for the next version of the JSR 168
                              • Guidelines for programming IBM Portlet API portlets
                                • Similar Functionality
                                  • Basic programming model
                                  • Portlet private session
                                  • User profile information
                                  • Persistent data
                                  • Portlet modes and window states
                                  • Expiration-based caching
                                    • Slightly different functionality
                                      • Sharing of data between portlets
                                      • Session listeners
                                        • New JSR 168 functionality
                                          • Navigational state (render parameters)
                                            • Pitfalls
                                              • Request response objects for action and render phase
                                              • Include search path
                                              • Form parameter encoding
                                              • Title setting
                                                  • Examples
                                                    • IBM Portlet API Portlet Code
                                                    • JSR 168 Portlet Code
                                                    • IBM Portlet API JSPs
                                                    • JSR 168 JSPs
                                                      • Summary
Page 14: Difference Bw Jsr168 and Ibm

ltportlet-namegtBookmark Portlet7ltportlet-namegt

ltallowsgt

ltmaximizedgt

ltminimizedgt

ltallowsgt

ltsupportsgt

ltmarkup name=htmlgt

ltview output=fragmentgt

ltedit output=fragmentgt

ltmarkupgt

ltsupportsgt

ltportletgt

ltportlet-appgt

ltconcrete-portlet-app uid=commycobookmark12341gt

ltportlet-app-namegtConcreteSamplets_Bookmark7ltportlet-app-namegt

ltconcrete-portlet href=Portlet_1gt

ltportlet-namegtBookmark Portlet7ltportlet-namegt

ltdefault-localegtenltdefault-localegt

ltlanguage locale=engt

lttitlegtMy Bookmarks7lttitlegt

lttitle-shortgtBookmarks7lttitle-shortgt

ltdescriptiongtPortlet showing your personalized bookmarksltdescriptiongt

ltkeywordsgtbookmarksltkeywordsgt

ltlanguagegt

ltconfig-paramgt

ltparam-namegturl1ltparam-namegt

ltparam-valuegthttpwwwgooglecomltparam-valuegt

ltconfig-paramgt

ltconcrete-portletgt

- 14 -

ltconcrete-portlet-appgt

ltportlet-app-defgt

As portlets are servlets in the IBM Portlet API the portletxml has references for each portlet to the servlet in the webxml that represents the portlet The webxml for this example is

IBM PORTLET API WEBXML EXAMPLE

ltxml version=10 encoding=UTF-8gt

ltDOCTYPE web-app

PUBLIC -Sun Microsystems IncDTD Web Application 22EN

httpjavasuncomj2eedtdsweb-app_22dtdgt

ltweb-app id=WebApp_1gt

ltdisplay-namegtbookmark7ltdisplay-namegt

ltservlet id=Servlet_1gt

ltservlet-namegtBookmark7ltservlet-namegt

ltservlet-classgtcommycobookmarkBookmarkPortletltservlet-classgt

ltinit-paramgt

ltparam-namegtjspviewltparam-namegt

ltparam-valuegtbookmarkViewjspltparam-valuegt

ltinit-paramgt

ltinit-paramgt

ltparam-namegtjspeditltparam-namegt

ltparam-valuegtbookmarkEditjspltparam-valuegt

ltinit-paramgt

ltservletgt

ltservlet-mappinggt

ltservlet-namegtBookmark7ltservlet-namegt

lturl-patterngtBookmark7lturl-patterngt

ltservlet-mappinggt

ltweb-appgt

- 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 webxml and not in the portletxml In the JSR 168 the deployment descriptor is more like the webxml 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 portletxml example would look like when using the JSR 168 deployment descriptor format

JSR 168 PORTLETXML EXAMPLE

ltxml version=10 encoding=UTF-8gt

ltxml version=10encoding=UTF-8gt

ltportlet-app xmlns=httpjavasuncomxmlnsportletportlet-app_1_0xsd version=10

xmlnsxsi=httpwwww3org2001XMLSchema-instance

xsischemaLocation=httpjavasuncomxmlnsportlet-app_1_0xsd

httpjavasuncomxmlnsportletportlet-app_1_0xsdgt

ltportletgt

ltdescription xmllang=ENgtPortlet showing your personalized

bookmarksltdescriptiongt

ltportlet-namegtBookmark Portlet7ltportlet-namegt

ltdisplay-name xmllang=ENgtBookmark Portletltdisplay-namegt

ltportlet-classgtcommycobookmarkBookmarkPortletltportlet-classgt

ltinit-paramgt

ltnamegtjspviewltnamegt

ltvaluegtbookmarkViewjspltvaluegt

ltinit-paramgt

ltinit-paramgt

ltnamegtjspeditltnamegt

ltvaluegtbookmarkEditjspltvaluegt

ltinit-paramgt

ltsupportsgt

ltmime-typegttexthtmlltmime-typegt

ltportlet-modegtviewltportlet-modegt

- 16 -

ltportlet-modegteditltportlet-modegt

ltsupportsgt

ltsupported-localegtENltsupported-localegt

ltportlet-infogt

lttitlegtMy Bookmarks7lttitlegt

ltshort-titlegtBookmarks7ltshort-titlegt

ltkeywordsgtbookmarksltkeywordsgt

ltportlet-infogt

ltportlet-preferencesgt

ltpreferencegt

ltnamegturl1ltnamegt

ltvaluegthttpwwwgooglecomltvaluegt

ltpreferencegt

ltportlet-preferencesgt

ltportletgt

ltportlet-appgt

Here the initialization parameters are directly specified in the portletxml as portlets are independent components in the JSR 168 The following example represents the webxml for the JSR 168 bookmark portlet

JSR 168 WEBXML EXAMPLE

ltxml version=10 encoding=UTF-8gt

ltDOCTYPE web-app PUBLIC -Sun Microsystems IncDTD Web Application 23EN

httpjavasuncomdtdweb-app_2_3dtdgt

ltweb-appgt

ltdisplay-namegtBookmark Application7ltdisplay-namegt

ltweb-appgt

The only item that needs to be specified in the JSR 168 webxml 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 portletxml as portlet application name as there can be several concrete instances of the same abstract application

- 17 -

332 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 331) 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 331) 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

333 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

334 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 instanceentity 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 -

335 Portlet API does not extend servlet API

In the IBM Portlet API portlets extend servlets and all the major interfaces (Request Response Session hellip) 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

336 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

bull defineObjects tag ndash to define the basic portlet API objects RenderRequest RenderResponse and PortletConfig

bull actionURL tag ndash to create an action URL bull renderURL tag ndash to create a render URL bull namespace tag ndash 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 donrsquot need decoding

34 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 -

341 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 (eg 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

342 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

3421 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

3422 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 322) 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

3423 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

3424 Request Response properties

Properties can be used by the portalportlet container to send vendor specific information to the portlet andor the portlet can send vendor specific information to the portalportlet-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

343 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 (eg between portlets or between a portlet and a servlet)

344 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 23 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

345 J2EE role support

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

346 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 -

347 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 PortletRequestgetResponseContentTypes 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 (eg ldquotextrdquo or ldquordquo) 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

348 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 (eg an accounting servlet) in response to an action

349 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

3410 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 vendorrsquos 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)

3411 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 xmllang attribute like the

- 22 -

servlet 24 deployment descriptor Thus the same tag with descriptions in different languages can be used (eg 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

35 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)

351 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

bull ActionEventThe action event maps to the action phase call in the JSR 168

bull MessageEventMessage 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)

bull PortletApplicationSettingsAttributeEventPortletSettingsAttributeEventThese are events that get fired when attributes for the application or of the portlet settings change

bull WindowEventThe portlet will register for window events to get notified if the portlet window is changed via the window decorations

352 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 -

bull PortletPageListener The page listeners provides the portlet with events for the beginning of the page before any markup is written for this page (eg to write JavaScript at the beginning of the page) and the end of the page after all markup is written

bull 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 23 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

bull EventPhaseListener The event phase listener notifies the portlet of the beginning and end of the eventaction phase

353 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

354 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 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

Figure 4

- 24 -

Figure 4 Portlet menu example

355 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

356 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 -

36 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 indicates portlet in what mode to operate for a given request

View edit help + custom modes

view edit help + custom modes

full alignment

Window State the state of the window in which the portlet output will be displayed

minimized normal maximized solo +

custom window states

minimized normal maximized +

custom window states

full alignment (ldquosolordquo is missing in the JSR but can be implemented as a custom state)

URL encoding to allow re-writing URLs created by the portlet

defines how to create URLs to allow re-writing of the URLs either on consumer or producer side

encapsulates URL creation via a Java object

full alignment (the implementation of the Java object can implement the WSRP URL rewriting rules)

Namespace encoding to avoid that several portlets on a page conflicting with each other

defines namespace prefixes for consumer and producer side namespacing

provides a Java method to namespace a String

full alignment (the JSR namespace method can implement the WSRP namespace behavior)

User ndash portlet interaction operations

performBlockingInteraction blocking action processing

getMarkup render the markup

action blocking action processing

render render the makup

full alignment (action invocations carried through performBlockingInteraction render carried through getMarkup)

View state that allows the current portlet fragment to be correctly displayed in sub-sequent render calls

navigational state render parameter full alignment (WSRP navigational state maps to JSR render parameters)

Storing transient state across request

session state concept implemented via a sessionID

utilizes the Http web application session

full alignment (the WSRP sessionID can be used to reference the JSR session)

Storing persistent state to personalize the rendering of the portlet

allows to have properties of arbitrary types

provides String-based preferences

full alignment (JSR String preferences can be mapped to WSRP properties)

Information about the portal calling the portlet

RegistrationData provide information of the consumer to the producer

PortalContext provide a Java interface to access information about the portal calling the portlet

full alignment (all data represented through the PortalContext to the JSR portlet are available in the RegistrationData)

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

Aggregated HTML WML VoiceXML

over HTTPMark-Up Fragments

Transferred via WSRP

Portal

WSRP Service

WSRP Service

WSRP Service

WSRP Consumer WSRP Producer

Use of WSRP Services in Portals

Portal sharing Portlets as WSRP Services

ServerPortalPortals

Huge numberof users Publishing Portal

WSRPWrapperPortalsPortalsPortal

Portlet

Portlet

Portlet

WSRP Consumer WSRP Producer

ProxyPortlet

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

bull 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

bull 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

bull 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

bull 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 CCPP standard allowing a portlet to query the client capabilities and adopting its markup accordingly (eg screen size browser) This API is likely to be included in the next version of the portlet API Also J2EE 14 was finalized during this time period J2EE 14 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 14

bull caching The first version of the JSR 168 API is limited to expiration-based caching (see section 327) 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

bull 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

51 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

511 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

bull portlets are components Portlets are components that implement a specific function Different functions should be distributed to different portlets

bull 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

bull 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

512 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 HttpServletRequestgetSession() call in the JSPs called via the IBM Portlet API needs to be replaced when moving to JSR 168 portlets by the RenderRequestgetPortletSession() 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 HttpServletRequestgetSession() will get the HttpSession and therefore need to access the portlet session via the RenderRequest

513 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

514 Persistent data

Portlets can store customization and personalization data persistently Customization data are related to the portlet and are valid for all users (eg 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 (eg 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

515 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

516 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

52 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

521 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 351 353) 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

522 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

53 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 -

531 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

bull no support of the back button in the browser bull current state of the portlet is not bookmarkable bull 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 bull 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

54 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

541 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 -

542 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

543 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

544 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 wersquoll 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

Figure 7After clicking on the Edit mode button the portlet renders the Edit view shown in

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

Figure 8

After we press the ldquoAddrdquo 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

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

bull use JSPs for rendering the output bull customize the portlet output taking user specific data into account bull 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

61 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 comibmwpssampleswp5

import javaio

import javautil

import orgapachejetspeedportlet

import orgapachejetspeedportletevent

public class IbmBookmark extends PortletAdapter implements ActionListener

public void init(PortletConfig portletConfig) throws UnavailableException

superinit(portletConfig)

- 36 -

public void doView(PortletRequest request PortletResponse response)

throws PortletException IOException

String jspName = thisgetPortletConfig()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 = responsecreateReturnURI()

addURIaddAction(add)

requestsetAttribute(addURI addURItoString())

PortletURI cancelURI = responsecreateReturnURI()

requestsetAttribute(cancelURI cancelURItoString())

String jspName = thisgetPortletConfig()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 ldquocancelrdquo and ldquoaddrdquo URLs are created inside the portlet and attached to the request before including the Edit JSP Both URLs are from type ldquoReturnURIrdquo 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 = eventgetRequest()

String action = eventgetActionString()

PortletLog log = getPortletLog()

if ( action=null )

try

if (actionequals(removeURI))

String removeName = requestgetParameter(remove)

PortletData portData = requestgetData()

portDataremoveAttribute(removeName)

portDatastore()

if (actionequals(add))

PortletData portData = requestgetData()

String name = requestgetParameter(name)

String value = requestgetParameter(value)

portDatasetAttribute(name value)

portDatastore()

catch ( AccessDeniedException ade )

logerror(AccessDeniedException occured when adding or deleting a bookmark)

catch ( IOException ioe )

logerror(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 ldquoaddrdquo or ldquodeleterdquo 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 ldquoaddrdquo or ldquoremoveURIrdquo If the user has clicked on the ldquoremoverdquo button the corresponding link is removed from the portlet data whereas if ldquoaddrdquo was clicked the data entered by the user is added to the portlet data

62 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 comibmwpssamplesjsr

import javaio

import javaxportlet

public class Bookmark extends GenericPortlet

public void init(PortletConfig config) throws PortletException

superinit(config)

public void doView(RenderRequest request RenderResponse response)

throws PortletException IOException

responsesetContentType(texthtml)

String jspName = getPortletConfig()getInitParameter(jspView)

PortletRequestDispatcher rd = getPortletContext()getRequestDispatcher(jspName)

rdinclude(requestresponse)

- 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

responsesetContentType(texthtml)

PortletURL addUrl = responsecreateActionURL()

addUrlsetPortletMode(PortletModeVIEW)

addUrlsetParameter(addadd)

requestsetAttribute(addUrladdUrltoString())

PortletURL cancelUrl = responsecreateRenderURL()

cancelUrlsetPortletMode(PortletModeVIEW)

requestsetAttribute(cancelUrlcancelUrltoString())

String jspName = getPortletConfig()getInitParameter(jspEdit)

PortletRequestDispatcher rd = getPortletContext()getRequestDispatcher(jspName)

rdinclude(requestresponse)

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 ldquoaddrdquo button URL an action URL is created as we need to store the user input of the add form persistently For the ldquocancelrdquo 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 = requestgetParameter(remove)

if (removeName = null)

PortletPreferences prefs = requestgetPreferences()

prefsreset(removeName)

prefsstore()

String add = requestgetParameter(add)

if (add = null)

PortletPreferences prefs = requestgetPreferences()

String name = requestgetParameter(name)

String value = requestgetParameter(value)

prefssetValue(name value)

prefsstore()

catch ( IOException ioe )

getPortletContextlog(An IO error occured when trying to remove a bookmark)

catch ( PortletException pe )

getPortletContextlog(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

bull 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

bull 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

bull Persistent portlet data The JSR 168 persistent data PortletPreferences have an API similar to the JDK 14 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

bull 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

63 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

lt page contentType=texthtml import=javautil comibmwpssampleswp5

orgapachejetspeedportlet session=falsegt

lt taglib uri=WEB-INFtldportlettld prefix=portletAPI gt

- 42 -

ltportletAPIinitgt

ltp class=wpsPortletHeadgtltportletAPItext key=available_bookmarks

bundle=nlsTextgtAvailable BookmarksltportletAPItextgtltpgt

lt

PortletData prefs = portletRequestgetData()

Enumeration e = prefsgetAttributeNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltportletAPItext key=no_bookmarks bundle=nlsTextgtNo

bookmarksltportletAPItextgtltpgt

lt

else

gt

ltp class=wpsIndentMediumgt

lt

while (ehasMoreElements())

String name = (String)enextElement()

String value = (String)prefsgetAttribute(name)

gt

lta href=lt=valuegt target=_blankgtlt=namegtltagtltbr gt

lt

gt

ltpgt

The View JSP first call portletAPIinit 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

lt page contentType=texthtml import=javautil

comibmwpssampleswp5orgapachejetspeedportlet session=falsegt

lt taglib uri=WEB-INFtldportlettld prefix=portletAPI gt

ltjspuseBean id=addURI class=javalangString scope=request gt

ltjspuseBean id=cancelURI class=javalangString scope=request gt

ltportletAPIinitgt

lth4gtltportletAPItext key=available_bookmarks bundle=nlsTextgtAvailable

BookmarksltportletAPItextgtlth4gt

lttable class=wpsTablegt

lttr class=wpsTableRowgt

ltth class=portlet-table-headergtltportletAPItext key=name bundle=nlsTextgtltthgt

ltth class=portlet-table-headergtltportletAPItext key=url bundle=nlsTextgtltthgt

lttdgtlttdgt

lttrgt

lt

PortletData prefs = portletRequestgetData()

Enumeration e = prefsgetAttributeNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltportletAPItext key=no_bookmarks bundle=nlsTextgtNo

bookmarksltportletAPItextgtltpgt

lt

else

while (ehasMoreElements())

- 44 -

String name = (String)enextElement()

String value = (String)prefsgetAttribute(name)

gt

lttr class=wpsTableRowgt

lttdgt lt=namegt lttdgt

lttdgt lt=valuegt lttdgt

lttdgt lta href=ltportletAPIcreateURIgtltportletAPIURIAction

name=removeURIgtltportletAPIURIParameter name=remove

value=lt=namegtgtltportletAPIcreateURIgtgt

(ltportletAPItext key=delete bundle=nlsTextgt)ltagt

lttdgt

lttrgt

lt

gt

ltform action=lt=addURIgt method=POSTgt

lttr class=wpsTableRowgt

lttdgtltinput name=ltportletAPIencodeNamespace value=namegt type=text

class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=ltportletAPIencodeNamespace value=valuegt type=text

class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=ltportletAPIencodeNamespace value=addgt type=submit

value=ltportletAPItext key=add bundle=nlsTextgt class=portlet-form-buttongtlttdgt

lttrgt

ltformgt

lttablegt

- 45 -

ltform action=lt=cancelURIgt method=postgt

ltinput name=ltportletAPIencodeNamespace value=cancelgt type=submit

value=ltportletAPItext key=cancel bundle=nlsTextgt class=portlet-form-buttongt

ltformgt

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 ldquodeleterdquo button for which an URL with the action ldquoremoveURIrdquo 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 ldquocancelrdquo button from the request

64 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

lt page import=javaxportlet javautil session=falsegt

lt taglib uri=httpjavasuncomportlet prefix=portletAPI gt

lt taglib prefix=fmt uri=httpjavasuncomjstlfmt gt

ltportletAPIdefineObjects gt

ltfmtsetBundle basename=nlsTextgt

lt

ResourceBundle myText = ResourceBundlegetBundle(nlsText requestgetLocale())

gt

lth4gtltfmtmessage key=available_bookmarksgtlth4gt

lt

PortletPreferences prefs = renderRequestgetPreferences()

Enumeration e = prefsgetNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltfmtmessage key=no_bookmarksgtltpgt

- 46 -

lt

else

gt

ltpgt

lt

while (ehasMoreElements())

String name = (String)enextElement()

String value = prefsgetValue(namelt+myTextgetString(undefined)+gt)

gt

lta href=lt=valuegt target=_blankgtlt=namegtltagtltbr gt

lt

gt

ltpgt

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 fmtmessage 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

lt page import=javaxportlet javautil session=false gt

lt taglib uri=httpjavasuncomportlet prefix=portletAPI gt

lt taglib prefix=fmt uri=httpjavasuncomjstlfmt gt

ltjspuseBean id=addUrl scope=request class=javalangString gt

ltjspuseBean id=cancelUrl scope=request class=javalangString gt

- 47 -

ltportletAPIdefineObjectsgt

lt

ResourceBundle myText = ResourceBundlegetBundle(nlsText requestgetLocale())

gt

ltfmtsetBundle basename=nlsTextgt

lth4gtltfmtmessage key=available_bookmarksgtlth4gt

lttable class=wpsTablegt

lttr class=wpsTableRowgt

ltth class=wpsTableHeadgtltfmtmessage key=namegtltthgt

ltth class=wpsTableHeadgtltfmtmessage key=urlgtltthgt

lttdgtlttdgt

lttrgt

lt

PortletPreferences prefs = renderRequestgetPreferences()

Enumeration e = prefsgetNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltfmtmessage key=no_bookmarksgtltpgt

lt

else

while (ehasMoreElements())

String name = (String)enextElement()

String value = prefsgetValue(namelt+myTextgetString(undefined)+gt)

gt

lttr class=wpsTableRowgt

lttdgt lt=namegt lttdgt

lttdgt lt=valuegt lttdgt

- 48 -

lttdgt ltportletAPIactionURL var=removeUrlgt

ltportletAPIparam name=remove value=lt=namegtgt

ltportletAPIactionURLgt

lta href=lt=removeUrltoString()gtgt(ltfmtmessage key=deletegt)ltagt

lttdgt

lttrgt

lt

gt

ltform action=lt=addUrlgt method=POSTgt

lttr class=wpsTableRowgt

lttdgtltinput name=name type=text class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=value type=text class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=add type=submit value=ltfmtmessage key=addgt

class=portlet-form-buttongtlttdgt

lttrgt

ltformgt

lttablegt

ltform action=lt=cancelUrlgt method=postgt

ltinput name=cancel type=submit value=ltfmtmessage key=cancelgt class=portlet-

form-buttongt

ltformgt

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 14 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 -

- 51 -

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 (eg eventing) the IBM Portlet API still needs to be used Trademarks bull IBM and WebSphere are trademarks or registered trademarks of IBM Corporation in

the United States other countries or both bull 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 bull Other company product and service names may be trademarks or service marks of

others IBM copyright and trademark information httpwwwibmcomlegalcopytradephtml

  • Introduction
  • JSR 168 and the Java Community Process
  • Comparing concepts
    • Basic concepts
      • Portal
      • Portal page
      • Portlet
      • Portlet Container
        • Concepts that are the same
          • Portlet mode
          • Window state
          • Portlet life cycle and request processing
          • URL encoding
          • Include servletsJSPs
          • Portlet application packaging
          • Expiration-based caching
            • Concepts that differ
              • Portlet application entity
              • Portlet entity
              • Action and Render Request Response objects
              • Window concept
              • Portlet API does not extend servlet API
              • TAG libraries
                • Concepts new in the JSR 168
                  • Render parameter
                  • Extension mechanisms
                    • Custom window states
                    • Custom portlet modes
                    • Custom user info
                    • Request Response properties
                      • Web application session scope
                      • Reuse of the HttpSession listeners
                      • J2EE role support
                      • Resource bundles
                      • Multiple response content types
                      • Redirect in action
                      • Preference validator
                      • Portal context
                      • Localization support
                        • Concepts missing in the JSR 168
                          • Eventing
                          • Additional lifecycle events
                          • Property broker
                          • Portlet Menus
                          • Portlet Services
                          • Invalidation-based caching
                            • Alignment with WSRP
                              • Outlook for the next version of the JSR 168
                              • Guidelines for programming IBM Portlet API portlets
                                • Similar Functionality
                                  • Basic programming model
                                  • Portlet private session
                                  • User profile information
                                  • Persistent data
                                  • Portlet modes and window states
                                  • Expiration-based caching
                                    • Slightly different functionality
                                      • Sharing of data between portlets
                                      • Session listeners
                                        • New JSR 168 functionality
                                          • Navigational state (render parameters)
                                            • Pitfalls
                                              • Request response objects for action and render phase
                                              • Include search path
                                              • Form parameter encoding
                                              • Title setting
                                                  • Examples
                                                    • IBM Portlet API Portlet Code
                                                    • JSR 168 Portlet Code
                                                    • IBM Portlet API JSPs
                                                    • JSR 168 JSPs
                                                      • Summary
Page 15: Difference Bw Jsr168 and Ibm

ltconcrete-portlet-appgt

ltportlet-app-defgt

As portlets are servlets in the IBM Portlet API the portletxml has references for each portlet to the servlet in the webxml that represents the portlet The webxml for this example is

IBM PORTLET API WEBXML EXAMPLE

ltxml version=10 encoding=UTF-8gt

ltDOCTYPE web-app

PUBLIC -Sun Microsystems IncDTD Web Application 22EN

httpjavasuncomj2eedtdsweb-app_22dtdgt

ltweb-app id=WebApp_1gt

ltdisplay-namegtbookmark7ltdisplay-namegt

ltservlet id=Servlet_1gt

ltservlet-namegtBookmark7ltservlet-namegt

ltservlet-classgtcommycobookmarkBookmarkPortletltservlet-classgt

ltinit-paramgt

ltparam-namegtjspviewltparam-namegt

ltparam-valuegtbookmarkViewjspltparam-valuegt

ltinit-paramgt

ltinit-paramgt

ltparam-namegtjspeditltparam-namegt

ltparam-valuegtbookmarkEditjspltparam-valuegt

ltinit-paramgt

ltservletgt

ltservlet-mappinggt

ltservlet-namegtBookmark7ltservlet-namegt

lturl-patterngtBookmark7lturl-patterngt

ltservlet-mappinggt

ltweb-appgt

- 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 webxml and not in the portletxml In the JSR 168 the deployment descriptor is more like the webxml 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 portletxml example would look like when using the JSR 168 deployment descriptor format

JSR 168 PORTLETXML EXAMPLE

ltxml version=10 encoding=UTF-8gt

ltxml version=10encoding=UTF-8gt

ltportlet-app xmlns=httpjavasuncomxmlnsportletportlet-app_1_0xsd version=10

xmlnsxsi=httpwwww3org2001XMLSchema-instance

xsischemaLocation=httpjavasuncomxmlnsportlet-app_1_0xsd

httpjavasuncomxmlnsportletportlet-app_1_0xsdgt

ltportletgt

ltdescription xmllang=ENgtPortlet showing your personalized

bookmarksltdescriptiongt

ltportlet-namegtBookmark Portlet7ltportlet-namegt

ltdisplay-name xmllang=ENgtBookmark Portletltdisplay-namegt

ltportlet-classgtcommycobookmarkBookmarkPortletltportlet-classgt

ltinit-paramgt

ltnamegtjspviewltnamegt

ltvaluegtbookmarkViewjspltvaluegt

ltinit-paramgt

ltinit-paramgt

ltnamegtjspeditltnamegt

ltvaluegtbookmarkEditjspltvaluegt

ltinit-paramgt

ltsupportsgt

ltmime-typegttexthtmlltmime-typegt

ltportlet-modegtviewltportlet-modegt

- 16 -

ltportlet-modegteditltportlet-modegt

ltsupportsgt

ltsupported-localegtENltsupported-localegt

ltportlet-infogt

lttitlegtMy Bookmarks7lttitlegt

ltshort-titlegtBookmarks7ltshort-titlegt

ltkeywordsgtbookmarksltkeywordsgt

ltportlet-infogt

ltportlet-preferencesgt

ltpreferencegt

ltnamegturl1ltnamegt

ltvaluegthttpwwwgooglecomltvaluegt

ltpreferencegt

ltportlet-preferencesgt

ltportletgt

ltportlet-appgt

Here the initialization parameters are directly specified in the portletxml as portlets are independent components in the JSR 168 The following example represents the webxml for the JSR 168 bookmark portlet

JSR 168 WEBXML EXAMPLE

ltxml version=10 encoding=UTF-8gt

ltDOCTYPE web-app PUBLIC -Sun Microsystems IncDTD Web Application 23EN

httpjavasuncomdtdweb-app_2_3dtdgt

ltweb-appgt

ltdisplay-namegtBookmark Application7ltdisplay-namegt

ltweb-appgt

The only item that needs to be specified in the JSR 168 webxml 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 portletxml as portlet application name as there can be several concrete instances of the same abstract application

- 17 -

332 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 331) 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 331) 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

333 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

334 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 instanceentity 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 -

335 Portlet API does not extend servlet API

In the IBM Portlet API portlets extend servlets and all the major interfaces (Request Response Session hellip) 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

336 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

bull defineObjects tag ndash to define the basic portlet API objects RenderRequest RenderResponse and PortletConfig

bull actionURL tag ndash to create an action URL bull renderURL tag ndash to create a render URL bull namespace tag ndash 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 donrsquot need decoding

34 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 -

341 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 (eg 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

342 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

3421 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

3422 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 322) 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

3423 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

3424 Request Response properties

Properties can be used by the portalportlet container to send vendor specific information to the portlet andor the portlet can send vendor specific information to the portalportlet-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

343 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 (eg between portlets or between a portlet and a servlet)

344 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 23 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

345 J2EE role support

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

346 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 -

347 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 PortletRequestgetResponseContentTypes 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 (eg ldquotextrdquo or ldquordquo) 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

348 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 (eg an accounting servlet) in response to an action

349 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

3410 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 vendorrsquos 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)

3411 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 xmllang attribute like the

- 22 -

servlet 24 deployment descriptor Thus the same tag with descriptions in different languages can be used (eg 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

35 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)

351 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

bull ActionEventThe action event maps to the action phase call in the JSR 168

bull MessageEventMessage 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)

bull PortletApplicationSettingsAttributeEventPortletSettingsAttributeEventThese are events that get fired when attributes for the application or of the portlet settings change

bull WindowEventThe portlet will register for window events to get notified if the portlet window is changed via the window decorations

352 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 -

bull PortletPageListener The page listeners provides the portlet with events for the beginning of the page before any markup is written for this page (eg to write JavaScript at the beginning of the page) and the end of the page after all markup is written

bull 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 23 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

bull EventPhaseListener The event phase listener notifies the portlet of the beginning and end of the eventaction phase

353 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

354 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 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

Figure 4

- 24 -

Figure 4 Portlet menu example

355 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

356 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 -

36 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 indicates portlet in what mode to operate for a given request

View edit help + custom modes

view edit help + custom modes

full alignment

Window State the state of the window in which the portlet output will be displayed

minimized normal maximized solo +

custom window states

minimized normal maximized +

custom window states

full alignment (ldquosolordquo is missing in the JSR but can be implemented as a custom state)

URL encoding to allow re-writing URLs created by the portlet

defines how to create URLs to allow re-writing of the URLs either on consumer or producer side

encapsulates URL creation via a Java object

full alignment (the implementation of the Java object can implement the WSRP URL rewriting rules)

Namespace encoding to avoid that several portlets on a page conflicting with each other

defines namespace prefixes for consumer and producer side namespacing

provides a Java method to namespace a String

full alignment (the JSR namespace method can implement the WSRP namespace behavior)

User ndash portlet interaction operations

performBlockingInteraction blocking action processing

getMarkup render the markup

action blocking action processing

render render the makup

full alignment (action invocations carried through performBlockingInteraction render carried through getMarkup)

View state that allows the current portlet fragment to be correctly displayed in sub-sequent render calls

navigational state render parameter full alignment (WSRP navigational state maps to JSR render parameters)

Storing transient state across request

session state concept implemented via a sessionID

utilizes the Http web application session

full alignment (the WSRP sessionID can be used to reference the JSR session)

Storing persistent state to personalize the rendering of the portlet

allows to have properties of arbitrary types

provides String-based preferences

full alignment (JSR String preferences can be mapped to WSRP properties)

Information about the portal calling the portlet

RegistrationData provide information of the consumer to the producer

PortalContext provide a Java interface to access information about the portal calling the portlet

full alignment (all data represented through the PortalContext to the JSR portlet are available in the RegistrationData)

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

Aggregated HTML WML VoiceXML

over HTTPMark-Up Fragments

Transferred via WSRP

Portal

WSRP Service

WSRP Service

WSRP Service

WSRP Consumer WSRP Producer

Use of WSRP Services in Portals

Portal sharing Portlets as WSRP Services

ServerPortalPortals

Huge numberof users Publishing Portal

WSRPWrapperPortalsPortalsPortal

Portlet

Portlet

Portlet

WSRP Consumer WSRP Producer

ProxyPortlet

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

bull 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

bull 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

bull 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

bull 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 CCPP standard allowing a portlet to query the client capabilities and adopting its markup accordingly (eg screen size browser) This API is likely to be included in the next version of the portlet API Also J2EE 14 was finalized during this time period J2EE 14 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 14

bull caching The first version of the JSR 168 API is limited to expiration-based caching (see section 327) 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

bull 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

51 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

511 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

bull portlets are components Portlets are components that implement a specific function Different functions should be distributed to different portlets

bull 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

bull 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

512 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 HttpServletRequestgetSession() call in the JSPs called via the IBM Portlet API needs to be replaced when moving to JSR 168 portlets by the RenderRequestgetPortletSession() 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 HttpServletRequestgetSession() will get the HttpSession and therefore need to access the portlet session via the RenderRequest

513 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

514 Persistent data

Portlets can store customization and personalization data persistently Customization data are related to the portlet and are valid for all users (eg 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 (eg 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

515 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

516 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

52 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

521 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 351 353) 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

522 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

53 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 -

531 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

bull no support of the back button in the browser bull current state of the portlet is not bookmarkable bull 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 bull 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

54 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

541 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 -

542 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

543 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

544 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 wersquoll 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

Figure 7After clicking on the Edit mode button the portlet renders the Edit view shown in

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

Figure 8

After we press the ldquoAddrdquo 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

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

bull use JSPs for rendering the output bull customize the portlet output taking user specific data into account bull 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

61 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 comibmwpssampleswp5

import javaio

import javautil

import orgapachejetspeedportlet

import orgapachejetspeedportletevent

public class IbmBookmark extends PortletAdapter implements ActionListener

public void init(PortletConfig portletConfig) throws UnavailableException

superinit(portletConfig)

- 36 -

public void doView(PortletRequest request PortletResponse response)

throws PortletException IOException

String jspName = thisgetPortletConfig()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 = responsecreateReturnURI()

addURIaddAction(add)

requestsetAttribute(addURI addURItoString())

PortletURI cancelURI = responsecreateReturnURI()

requestsetAttribute(cancelURI cancelURItoString())

String jspName = thisgetPortletConfig()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 ldquocancelrdquo and ldquoaddrdquo URLs are created inside the portlet and attached to the request before including the Edit JSP Both URLs are from type ldquoReturnURIrdquo 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 = eventgetRequest()

String action = eventgetActionString()

PortletLog log = getPortletLog()

if ( action=null )

try

if (actionequals(removeURI))

String removeName = requestgetParameter(remove)

PortletData portData = requestgetData()

portDataremoveAttribute(removeName)

portDatastore()

if (actionequals(add))

PortletData portData = requestgetData()

String name = requestgetParameter(name)

String value = requestgetParameter(value)

portDatasetAttribute(name value)

portDatastore()

catch ( AccessDeniedException ade )

logerror(AccessDeniedException occured when adding or deleting a bookmark)

catch ( IOException ioe )

logerror(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 ldquoaddrdquo or ldquodeleterdquo 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 ldquoaddrdquo or ldquoremoveURIrdquo If the user has clicked on the ldquoremoverdquo button the corresponding link is removed from the portlet data whereas if ldquoaddrdquo was clicked the data entered by the user is added to the portlet data

62 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 comibmwpssamplesjsr

import javaio

import javaxportlet

public class Bookmark extends GenericPortlet

public void init(PortletConfig config) throws PortletException

superinit(config)

public void doView(RenderRequest request RenderResponse response)

throws PortletException IOException

responsesetContentType(texthtml)

String jspName = getPortletConfig()getInitParameter(jspView)

PortletRequestDispatcher rd = getPortletContext()getRequestDispatcher(jspName)

rdinclude(requestresponse)

- 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

responsesetContentType(texthtml)

PortletURL addUrl = responsecreateActionURL()

addUrlsetPortletMode(PortletModeVIEW)

addUrlsetParameter(addadd)

requestsetAttribute(addUrladdUrltoString())

PortletURL cancelUrl = responsecreateRenderURL()

cancelUrlsetPortletMode(PortletModeVIEW)

requestsetAttribute(cancelUrlcancelUrltoString())

String jspName = getPortletConfig()getInitParameter(jspEdit)

PortletRequestDispatcher rd = getPortletContext()getRequestDispatcher(jspName)

rdinclude(requestresponse)

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 ldquoaddrdquo button URL an action URL is created as we need to store the user input of the add form persistently For the ldquocancelrdquo 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 = requestgetParameter(remove)

if (removeName = null)

PortletPreferences prefs = requestgetPreferences()

prefsreset(removeName)

prefsstore()

String add = requestgetParameter(add)

if (add = null)

PortletPreferences prefs = requestgetPreferences()

String name = requestgetParameter(name)

String value = requestgetParameter(value)

prefssetValue(name value)

prefsstore()

catch ( IOException ioe )

getPortletContextlog(An IO error occured when trying to remove a bookmark)

catch ( PortletException pe )

getPortletContextlog(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

bull 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

bull 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

bull Persistent portlet data The JSR 168 persistent data PortletPreferences have an API similar to the JDK 14 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

bull 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

63 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

lt page contentType=texthtml import=javautil comibmwpssampleswp5

orgapachejetspeedportlet session=falsegt

lt taglib uri=WEB-INFtldportlettld prefix=portletAPI gt

- 42 -

ltportletAPIinitgt

ltp class=wpsPortletHeadgtltportletAPItext key=available_bookmarks

bundle=nlsTextgtAvailable BookmarksltportletAPItextgtltpgt

lt

PortletData prefs = portletRequestgetData()

Enumeration e = prefsgetAttributeNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltportletAPItext key=no_bookmarks bundle=nlsTextgtNo

bookmarksltportletAPItextgtltpgt

lt

else

gt

ltp class=wpsIndentMediumgt

lt

while (ehasMoreElements())

String name = (String)enextElement()

String value = (String)prefsgetAttribute(name)

gt

lta href=lt=valuegt target=_blankgtlt=namegtltagtltbr gt

lt

gt

ltpgt

The View JSP first call portletAPIinit 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

lt page contentType=texthtml import=javautil

comibmwpssampleswp5orgapachejetspeedportlet session=falsegt

lt taglib uri=WEB-INFtldportlettld prefix=portletAPI gt

ltjspuseBean id=addURI class=javalangString scope=request gt

ltjspuseBean id=cancelURI class=javalangString scope=request gt

ltportletAPIinitgt

lth4gtltportletAPItext key=available_bookmarks bundle=nlsTextgtAvailable

BookmarksltportletAPItextgtlth4gt

lttable class=wpsTablegt

lttr class=wpsTableRowgt

ltth class=portlet-table-headergtltportletAPItext key=name bundle=nlsTextgtltthgt

ltth class=portlet-table-headergtltportletAPItext key=url bundle=nlsTextgtltthgt

lttdgtlttdgt

lttrgt

lt

PortletData prefs = portletRequestgetData()

Enumeration e = prefsgetAttributeNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltportletAPItext key=no_bookmarks bundle=nlsTextgtNo

bookmarksltportletAPItextgtltpgt

lt

else

while (ehasMoreElements())

- 44 -

String name = (String)enextElement()

String value = (String)prefsgetAttribute(name)

gt

lttr class=wpsTableRowgt

lttdgt lt=namegt lttdgt

lttdgt lt=valuegt lttdgt

lttdgt lta href=ltportletAPIcreateURIgtltportletAPIURIAction

name=removeURIgtltportletAPIURIParameter name=remove

value=lt=namegtgtltportletAPIcreateURIgtgt

(ltportletAPItext key=delete bundle=nlsTextgt)ltagt

lttdgt

lttrgt

lt

gt

ltform action=lt=addURIgt method=POSTgt

lttr class=wpsTableRowgt

lttdgtltinput name=ltportletAPIencodeNamespace value=namegt type=text

class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=ltportletAPIencodeNamespace value=valuegt type=text

class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=ltportletAPIencodeNamespace value=addgt type=submit

value=ltportletAPItext key=add bundle=nlsTextgt class=portlet-form-buttongtlttdgt

lttrgt

ltformgt

lttablegt

- 45 -

ltform action=lt=cancelURIgt method=postgt

ltinput name=ltportletAPIencodeNamespace value=cancelgt type=submit

value=ltportletAPItext key=cancel bundle=nlsTextgt class=portlet-form-buttongt

ltformgt

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 ldquodeleterdquo button for which an URL with the action ldquoremoveURIrdquo 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 ldquocancelrdquo button from the request

64 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

lt page import=javaxportlet javautil session=falsegt

lt taglib uri=httpjavasuncomportlet prefix=portletAPI gt

lt taglib prefix=fmt uri=httpjavasuncomjstlfmt gt

ltportletAPIdefineObjects gt

ltfmtsetBundle basename=nlsTextgt

lt

ResourceBundle myText = ResourceBundlegetBundle(nlsText requestgetLocale())

gt

lth4gtltfmtmessage key=available_bookmarksgtlth4gt

lt

PortletPreferences prefs = renderRequestgetPreferences()

Enumeration e = prefsgetNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltfmtmessage key=no_bookmarksgtltpgt

- 46 -

lt

else

gt

ltpgt

lt

while (ehasMoreElements())

String name = (String)enextElement()

String value = prefsgetValue(namelt+myTextgetString(undefined)+gt)

gt

lta href=lt=valuegt target=_blankgtlt=namegtltagtltbr gt

lt

gt

ltpgt

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 fmtmessage 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

lt page import=javaxportlet javautil session=false gt

lt taglib uri=httpjavasuncomportlet prefix=portletAPI gt

lt taglib prefix=fmt uri=httpjavasuncomjstlfmt gt

ltjspuseBean id=addUrl scope=request class=javalangString gt

ltjspuseBean id=cancelUrl scope=request class=javalangString gt

- 47 -

ltportletAPIdefineObjectsgt

lt

ResourceBundle myText = ResourceBundlegetBundle(nlsText requestgetLocale())

gt

ltfmtsetBundle basename=nlsTextgt

lth4gtltfmtmessage key=available_bookmarksgtlth4gt

lttable class=wpsTablegt

lttr class=wpsTableRowgt

ltth class=wpsTableHeadgtltfmtmessage key=namegtltthgt

ltth class=wpsTableHeadgtltfmtmessage key=urlgtltthgt

lttdgtlttdgt

lttrgt

lt

PortletPreferences prefs = renderRequestgetPreferences()

Enumeration e = prefsgetNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltfmtmessage key=no_bookmarksgtltpgt

lt

else

while (ehasMoreElements())

String name = (String)enextElement()

String value = prefsgetValue(namelt+myTextgetString(undefined)+gt)

gt

lttr class=wpsTableRowgt

lttdgt lt=namegt lttdgt

lttdgt lt=valuegt lttdgt

- 48 -

lttdgt ltportletAPIactionURL var=removeUrlgt

ltportletAPIparam name=remove value=lt=namegtgt

ltportletAPIactionURLgt

lta href=lt=removeUrltoString()gtgt(ltfmtmessage key=deletegt)ltagt

lttdgt

lttrgt

lt

gt

ltform action=lt=addUrlgt method=POSTgt

lttr class=wpsTableRowgt

lttdgtltinput name=name type=text class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=value type=text class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=add type=submit value=ltfmtmessage key=addgt

class=portlet-form-buttongtlttdgt

lttrgt

ltformgt

lttablegt

ltform action=lt=cancelUrlgt method=postgt

ltinput name=cancel type=submit value=ltfmtmessage key=cancelgt class=portlet-

form-buttongt

ltformgt

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 14 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 -

- 51 -

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 (eg eventing) the IBM Portlet API still needs to be used Trademarks bull IBM and WebSphere are trademarks or registered trademarks of IBM Corporation in

the United States other countries or both bull 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 bull Other company product and service names may be trademarks or service marks of

others IBM copyright and trademark information httpwwwibmcomlegalcopytradephtml

  • Introduction
  • JSR 168 and the Java Community Process
  • Comparing concepts
    • Basic concepts
      • Portal
      • Portal page
      • Portlet
      • Portlet Container
        • Concepts that are the same
          • Portlet mode
          • Window state
          • Portlet life cycle and request processing
          • URL encoding
          • Include servletsJSPs
          • Portlet application packaging
          • Expiration-based caching
            • Concepts that differ
              • Portlet application entity
              • Portlet entity
              • Action and Render Request Response objects
              • Window concept
              • Portlet API does not extend servlet API
              • TAG libraries
                • Concepts new in the JSR 168
                  • Render parameter
                  • Extension mechanisms
                    • Custom window states
                    • Custom portlet modes
                    • Custom user info
                    • Request Response properties
                      • Web application session scope
                      • Reuse of the HttpSession listeners
                      • J2EE role support
                      • Resource bundles
                      • Multiple response content types
                      • Redirect in action
                      • Preference validator
                      • Portal context
                      • Localization support
                        • Concepts missing in the JSR 168
                          • Eventing
                          • Additional lifecycle events
                          • Property broker
                          • Portlet Menus
                          • Portlet Services
                          • Invalidation-based caching
                            • Alignment with WSRP
                              • Outlook for the next version of the JSR 168
                              • Guidelines for programming IBM Portlet API portlets
                                • Similar Functionality
                                  • Basic programming model
                                  • Portlet private session
                                  • User profile information
                                  • Persistent data
                                  • Portlet modes and window states
                                  • Expiration-based caching
                                    • Slightly different functionality
                                      • Sharing of data between portlets
                                      • Session listeners
                                        • New JSR 168 functionality
                                          • Navigational state (render parameters)
                                            • Pitfalls
                                              • Request response objects for action and render phase
                                              • Include search path
                                              • Form parameter encoding
                                              • Title setting
                                                  • Examples
                                                    • IBM Portlet API Portlet Code
                                                    • JSR 168 Portlet Code
                                                    • IBM Portlet API JSPs
                                                    • JSR 168 JSPs
                                                      • Summary
Page 16: Difference Bw Jsr168 and Ibm

Another result of portlets being servlets is that the initialization parameters of the portlets need to be specified in the servlet section of the webxml and not in the portletxml In the JSR 168 the deployment descriptor is more like the webxml 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 portletxml example would look like when using the JSR 168 deployment descriptor format

JSR 168 PORTLETXML EXAMPLE

ltxml version=10 encoding=UTF-8gt

ltxml version=10encoding=UTF-8gt

ltportlet-app xmlns=httpjavasuncomxmlnsportletportlet-app_1_0xsd version=10

xmlnsxsi=httpwwww3org2001XMLSchema-instance

xsischemaLocation=httpjavasuncomxmlnsportlet-app_1_0xsd

httpjavasuncomxmlnsportletportlet-app_1_0xsdgt

ltportletgt

ltdescription xmllang=ENgtPortlet showing your personalized

bookmarksltdescriptiongt

ltportlet-namegtBookmark Portlet7ltportlet-namegt

ltdisplay-name xmllang=ENgtBookmark Portletltdisplay-namegt

ltportlet-classgtcommycobookmarkBookmarkPortletltportlet-classgt

ltinit-paramgt

ltnamegtjspviewltnamegt

ltvaluegtbookmarkViewjspltvaluegt

ltinit-paramgt

ltinit-paramgt

ltnamegtjspeditltnamegt

ltvaluegtbookmarkEditjspltvaluegt

ltinit-paramgt

ltsupportsgt

ltmime-typegttexthtmlltmime-typegt

ltportlet-modegtviewltportlet-modegt

- 16 -

ltportlet-modegteditltportlet-modegt

ltsupportsgt

ltsupported-localegtENltsupported-localegt

ltportlet-infogt

lttitlegtMy Bookmarks7lttitlegt

ltshort-titlegtBookmarks7ltshort-titlegt

ltkeywordsgtbookmarksltkeywordsgt

ltportlet-infogt

ltportlet-preferencesgt

ltpreferencegt

ltnamegturl1ltnamegt

ltvaluegthttpwwwgooglecomltvaluegt

ltpreferencegt

ltportlet-preferencesgt

ltportletgt

ltportlet-appgt

Here the initialization parameters are directly specified in the portletxml as portlets are independent components in the JSR 168 The following example represents the webxml for the JSR 168 bookmark portlet

JSR 168 WEBXML EXAMPLE

ltxml version=10 encoding=UTF-8gt

ltDOCTYPE web-app PUBLIC -Sun Microsystems IncDTD Web Application 23EN

httpjavasuncomdtdweb-app_2_3dtdgt

ltweb-appgt

ltdisplay-namegtBookmark Application7ltdisplay-namegt

ltweb-appgt

The only item that needs to be specified in the JSR 168 webxml 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 portletxml as portlet application name as there can be several concrete instances of the same abstract application

- 17 -

332 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 331) 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 331) 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

333 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

334 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 instanceentity 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 -

335 Portlet API does not extend servlet API

In the IBM Portlet API portlets extend servlets and all the major interfaces (Request Response Session hellip) 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

336 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

bull defineObjects tag ndash to define the basic portlet API objects RenderRequest RenderResponse and PortletConfig

bull actionURL tag ndash to create an action URL bull renderURL tag ndash to create a render URL bull namespace tag ndash 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 donrsquot need decoding

34 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 -

341 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 (eg 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

342 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

3421 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

3422 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 322) 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

3423 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

3424 Request Response properties

Properties can be used by the portalportlet container to send vendor specific information to the portlet andor the portlet can send vendor specific information to the portalportlet-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

343 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 (eg between portlets or between a portlet and a servlet)

344 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 23 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

345 J2EE role support

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

346 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 -

347 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 PortletRequestgetResponseContentTypes 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 (eg ldquotextrdquo or ldquordquo) 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

348 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 (eg an accounting servlet) in response to an action

349 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

3410 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 vendorrsquos 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)

3411 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 xmllang attribute like the

- 22 -

servlet 24 deployment descriptor Thus the same tag with descriptions in different languages can be used (eg 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

35 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)

351 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

bull ActionEventThe action event maps to the action phase call in the JSR 168

bull MessageEventMessage 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)

bull PortletApplicationSettingsAttributeEventPortletSettingsAttributeEventThese are events that get fired when attributes for the application or of the portlet settings change

bull WindowEventThe portlet will register for window events to get notified if the portlet window is changed via the window decorations

352 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 -

bull PortletPageListener The page listeners provides the portlet with events for the beginning of the page before any markup is written for this page (eg to write JavaScript at the beginning of the page) and the end of the page after all markup is written

bull 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 23 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

bull EventPhaseListener The event phase listener notifies the portlet of the beginning and end of the eventaction phase

353 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

354 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 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

Figure 4

- 24 -

Figure 4 Portlet menu example

355 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

356 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 -

36 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 indicates portlet in what mode to operate for a given request

View edit help + custom modes

view edit help + custom modes

full alignment

Window State the state of the window in which the portlet output will be displayed

minimized normal maximized solo +

custom window states

minimized normal maximized +

custom window states

full alignment (ldquosolordquo is missing in the JSR but can be implemented as a custom state)

URL encoding to allow re-writing URLs created by the portlet

defines how to create URLs to allow re-writing of the URLs either on consumer or producer side

encapsulates URL creation via a Java object

full alignment (the implementation of the Java object can implement the WSRP URL rewriting rules)

Namespace encoding to avoid that several portlets on a page conflicting with each other

defines namespace prefixes for consumer and producer side namespacing

provides a Java method to namespace a String

full alignment (the JSR namespace method can implement the WSRP namespace behavior)

User ndash portlet interaction operations

performBlockingInteraction blocking action processing

getMarkup render the markup

action blocking action processing

render render the makup

full alignment (action invocations carried through performBlockingInteraction render carried through getMarkup)

View state that allows the current portlet fragment to be correctly displayed in sub-sequent render calls

navigational state render parameter full alignment (WSRP navigational state maps to JSR render parameters)

Storing transient state across request

session state concept implemented via a sessionID

utilizes the Http web application session

full alignment (the WSRP sessionID can be used to reference the JSR session)

Storing persistent state to personalize the rendering of the portlet

allows to have properties of arbitrary types

provides String-based preferences

full alignment (JSR String preferences can be mapped to WSRP properties)

Information about the portal calling the portlet

RegistrationData provide information of the consumer to the producer

PortalContext provide a Java interface to access information about the portal calling the portlet

full alignment (all data represented through the PortalContext to the JSR portlet are available in the RegistrationData)

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

Aggregated HTML WML VoiceXML

over HTTPMark-Up Fragments

Transferred via WSRP

Portal

WSRP Service

WSRP Service

WSRP Service

WSRP Consumer WSRP Producer

Use of WSRP Services in Portals

Portal sharing Portlets as WSRP Services

ServerPortalPortals

Huge numberof users Publishing Portal

WSRPWrapperPortalsPortalsPortal

Portlet

Portlet

Portlet

WSRP Consumer WSRP Producer

ProxyPortlet

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

bull 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

bull 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

bull 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

bull 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 CCPP standard allowing a portlet to query the client capabilities and adopting its markup accordingly (eg screen size browser) This API is likely to be included in the next version of the portlet API Also J2EE 14 was finalized during this time period J2EE 14 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 14

bull caching The first version of the JSR 168 API is limited to expiration-based caching (see section 327) 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

bull 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

51 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

511 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

bull portlets are components Portlets are components that implement a specific function Different functions should be distributed to different portlets

bull 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

bull 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

512 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 HttpServletRequestgetSession() call in the JSPs called via the IBM Portlet API needs to be replaced when moving to JSR 168 portlets by the RenderRequestgetPortletSession() 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 HttpServletRequestgetSession() will get the HttpSession and therefore need to access the portlet session via the RenderRequest

513 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

514 Persistent data

Portlets can store customization and personalization data persistently Customization data are related to the portlet and are valid for all users (eg 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 (eg 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

515 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

516 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

52 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

521 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 351 353) 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

522 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

53 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 -

531 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

bull no support of the back button in the browser bull current state of the portlet is not bookmarkable bull 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 bull 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

54 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

541 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 -

542 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

543 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

544 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 wersquoll 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

Figure 7After clicking on the Edit mode button the portlet renders the Edit view shown in

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

Figure 8

After we press the ldquoAddrdquo 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

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

bull use JSPs for rendering the output bull customize the portlet output taking user specific data into account bull 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

61 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 comibmwpssampleswp5

import javaio

import javautil

import orgapachejetspeedportlet

import orgapachejetspeedportletevent

public class IbmBookmark extends PortletAdapter implements ActionListener

public void init(PortletConfig portletConfig) throws UnavailableException

superinit(portletConfig)

- 36 -

public void doView(PortletRequest request PortletResponse response)

throws PortletException IOException

String jspName = thisgetPortletConfig()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 = responsecreateReturnURI()

addURIaddAction(add)

requestsetAttribute(addURI addURItoString())

PortletURI cancelURI = responsecreateReturnURI()

requestsetAttribute(cancelURI cancelURItoString())

String jspName = thisgetPortletConfig()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 ldquocancelrdquo and ldquoaddrdquo URLs are created inside the portlet and attached to the request before including the Edit JSP Both URLs are from type ldquoReturnURIrdquo 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 = eventgetRequest()

String action = eventgetActionString()

PortletLog log = getPortletLog()

if ( action=null )

try

if (actionequals(removeURI))

String removeName = requestgetParameter(remove)

PortletData portData = requestgetData()

portDataremoveAttribute(removeName)

portDatastore()

if (actionequals(add))

PortletData portData = requestgetData()

String name = requestgetParameter(name)

String value = requestgetParameter(value)

portDatasetAttribute(name value)

portDatastore()

catch ( AccessDeniedException ade )

logerror(AccessDeniedException occured when adding or deleting a bookmark)

catch ( IOException ioe )

logerror(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 ldquoaddrdquo or ldquodeleterdquo 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 ldquoaddrdquo or ldquoremoveURIrdquo If the user has clicked on the ldquoremoverdquo button the corresponding link is removed from the portlet data whereas if ldquoaddrdquo was clicked the data entered by the user is added to the portlet data

62 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 comibmwpssamplesjsr

import javaio

import javaxportlet

public class Bookmark extends GenericPortlet

public void init(PortletConfig config) throws PortletException

superinit(config)

public void doView(RenderRequest request RenderResponse response)

throws PortletException IOException

responsesetContentType(texthtml)

String jspName = getPortletConfig()getInitParameter(jspView)

PortletRequestDispatcher rd = getPortletContext()getRequestDispatcher(jspName)

rdinclude(requestresponse)

- 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

responsesetContentType(texthtml)

PortletURL addUrl = responsecreateActionURL()

addUrlsetPortletMode(PortletModeVIEW)

addUrlsetParameter(addadd)

requestsetAttribute(addUrladdUrltoString())

PortletURL cancelUrl = responsecreateRenderURL()

cancelUrlsetPortletMode(PortletModeVIEW)

requestsetAttribute(cancelUrlcancelUrltoString())

String jspName = getPortletConfig()getInitParameter(jspEdit)

PortletRequestDispatcher rd = getPortletContext()getRequestDispatcher(jspName)

rdinclude(requestresponse)

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 ldquoaddrdquo button URL an action URL is created as we need to store the user input of the add form persistently For the ldquocancelrdquo 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 = requestgetParameter(remove)

if (removeName = null)

PortletPreferences prefs = requestgetPreferences()

prefsreset(removeName)

prefsstore()

String add = requestgetParameter(add)

if (add = null)

PortletPreferences prefs = requestgetPreferences()

String name = requestgetParameter(name)

String value = requestgetParameter(value)

prefssetValue(name value)

prefsstore()

catch ( IOException ioe )

getPortletContextlog(An IO error occured when trying to remove a bookmark)

catch ( PortletException pe )

getPortletContextlog(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

bull 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

bull 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

bull Persistent portlet data The JSR 168 persistent data PortletPreferences have an API similar to the JDK 14 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

bull 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

63 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

lt page contentType=texthtml import=javautil comibmwpssampleswp5

orgapachejetspeedportlet session=falsegt

lt taglib uri=WEB-INFtldportlettld prefix=portletAPI gt

- 42 -

ltportletAPIinitgt

ltp class=wpsPortletHeadgtltportletAPItext key=available_bookmarks

bundle=nlsTextgtAvailable BookmarksltportletAPItextgtltpgt

lt

PortletData prefs = portletRequestgetData()

Enumeration e = prefsgetAttributeNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltportletAPItext key=no_bookmarks bundle=nlsTextgtNo

bookmarksltportletAPItextgtltpgt

lt

else

gt

ltp class=wpsIndentMediumgt

lt

while (ehasMoreElements())

String name = (String)enextElement()

String value = (String)prefsgetAttribute(name)

gt

lta href=lt=valuegt target=_blankgtlt=namegtltagtltbr gt

lt

gt

ltpgt

The View JSP first call portletAPIinit 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

lt page contentType=texthtml import=javautil

comibmwpssampleswp5orgapachejetspeedportlet session=falsegt

lt taglib uri=WEB-INFtldportlettld prefix=portletAPI gt

ltjspuseBean id=addURI class=javalangString scope=request gt

ltjspuseBean id=cancelURI class=javalangString scope=request gt

ltportletAPIinitgt

lth4gtltportletAPItext key=available_bookmarks bundle=nlsTextgtAvailable

BookmarksltportletAPItextgtlth4gt

lttable class=wpsTablegt

lttr class=wpsTableRowgt

ltth class=portlet-table-headergtltportletAPItext key=name bundle=nlsTextgtltthgt

ltth class=portlet-table-headergtltportletAPItext key=url bundle=nlsTextgtltthgt

lttdgtlttdgt

lttrgt

lt

PortletData prefs = portletRequestgetData()

Enumeration e = prefsgetAttributeNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltportletAPItext key=no_bookmarks bundle=nlsTextgtNo

bookmarksltportletAPItextgtltpgt

lt

else

while (ehasMoreElements())

- 44 -

String name = (String)enextElement()

String value = (String)prefsgetAttribute(name)

gt

lttr class=wpsTableRowgt

lttdgt lt=namegt lttdgt

lttdgt lt=valuegt lttdgt

lttdgt lta href=ltportletAPIcreateURIgtltportletAPIURIAction

name=removeURIgtltportletAPIURIParameter name=remove

value=lt=namegtgtltportletAPIcreateURIgtgt

(ltportletAPItext key=delete bundle=nlsTextgt)ltagt

lttdgt

lttrgt

lt

gt

ltform action=lt=addURIgt method=POSTgt

lttr class=wpsTableRowgt

lttdgtltinput name=ltportletAPIencodeNamespace value=namegt type=text

class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=ltportletAPIencodeNamespace value=valuegt type=text

class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=ltportletAPIencodeNamespace value=addgt type=submit

value=ltportletAPItext key=add bundle=nlsTextgt class=portlet-form-buttongtlttdgt

lttrgt

ltformgt

lttablegt

- 45 -

ltform action=lt=cancelURIgt method=postgt

ltinput name=ltportletAPIencodeNamespace value=cancelgt type=submit

value=ltportletAPItext key=cancel bundle=nlsTextgt class=portlet-form-buttongt

ltformgt

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 ldquodeleterdquo button for which an URL with the action ldquoremoveURIrdquo 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 ldquocancelrdquo button from the request

64 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

lt page import=javaxportlet javautil session=falsegt

lt taglib uri=httpjavasuncomportlet prefix=portletAPI gt

lt taglib prefix=fmt uri=httpjavasuncomjstlfmt gt

ltportletAPIdefineObjects gt

ltfmtsetBundle basename=nlsTextgt

lt

ResourceBundle myText = ResourceBundlegetBundle(nlsText requestgetLocale())

gt

lth4gtltfmtmessage key=available_bookmarksgtlth4gt

lt

PortletPreferences prefs = renderRequestgetPreferences()

Enumeration e = prefsgetNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltfmtmessage key=no_bookmarksgtltpgt

- 46 -

lt

else

gt

ltpgt

lt

while (ehasMoreElements())

String name = (String)enextElement()

String value = prefsgetValue(namelt+myTextgetString(undefined)+gt)

gt

lta href=lt=valuegt target=_blankgtlt=namegtltagtltbr gt

lt

gt

ltpgt

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 fmtmessage 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

lt page import=javaxportlet javautil session=false gt

lt taglib uri=httpjavasuncomportlet prefix=portletAPI gt

lt taglib prefix=fmt uri=httpjavasuncomjstlfmt gt

ltjspuseBean id=addUrl scope=request class=javalangString gt

ltjspuseBean id=cancelUrl scope=request class=javalangString gt

- 47 -

ltportletAPIdefineObjectsgt

lt

ResourceBundle myText = ResourceBundlegetBundle(nlsText requestgetLocale())

gt

ltfmtsetBundle basename=nlsTextgt

lth4gtltfmtmessage key=available_bookmarksgtlth4gt

lttable class=wpsTablegt

lttr class=wpsTableRowgt

ltth class=wpsTableHeadgtltfmtmessage key=namegtltthgt

ltth class=wpsTableHeadgtltfmtmessage key=urlgtltthgt

lttdgtlttdgt

lttrgt

lt

PortletPreferences prefs = renderRequestgetPreferences()

Enumeration e = prefsgetNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltfmtmessage key=no_bookmarksgtltpgt

lt

else

while (ehasMoreElements())

String name = (String)enextElement()

String value = prefsgetValue(namelt+myTextgetString(undefined)+gt)

gt

lttr class=wpsTableRowgt

lttdgt lt=namegt lttdgt

lttdgt lt=valuegt lttdgt

- 48 -

lttdgt ltportletAPIactionURL var=removeUrlgt

ltportletAPIparam name=remove value=lt=namegtgt

ltportletAPIactionURLgt

lta href=lt=removeUrltoString()gtgt(ltfmtmessage key=deletegt)ltagt

lttdgt

lttrgt

lt

gt

ltform action=lt=addUrlgt method=POSTgt

lttr class=wpsTableRowgt

lttdgtltinput name=name type=text class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=value type=text class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=add type=submit value=ltfmtmessage key=addgt

class=portlet-form-buttongtlttdgt

lttrgt

ltformgt

lttablegt

ltform action=lt=cancelUrlgt method=postgt

ltinput name=cancel type=submit value=ltfmtmessage key=cancelgt class=portlet-

form-buttongt

ltformgt

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 14 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 -

- 51 -

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 (eg eventing) the IBM Portlet API still needs to be used Trademarks bull IBM and WebSphere are trademarks or registered trademarks of IBM Corporation in

the United States other countries or both bull 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 bull Other company product and service names may be trademarks or service marks of

others IBM copyright and trademark information httpwwwibmcomlegalcopytradephtml

  • Introduction
  • JSR 168 and the Java Community Process
  • Comparing concepts
    • Basic concepts
      • Portal
      • Portal page
      • Portlet
      • Portlet Container
        • Concepts that are the same
          • Portlet mode
          • Window state
          • Portlet life cycle and request processing
          • URL encoding
          • Include servletsJSPs
          • Portlet application packaging
          • Expiration-based caching
            • Concepts that differ
              • Portlet application entity
              • Portlet entity
              • Action and Render Request Response objects
              • Window concept
              • Portlet API does not extend servlet API
              • TAG libraries
                • Concepts new in the JSR 168
                  • Render parameter
                  • Extension mechanisms
                    • Custom window states
                    • Custom portlet modes
                    • Custom user info
                    • Request Response properties
                      • Web application session scope
                      • Reuse of the HttpSession listeners
                      • J2EE role support
                      • Resource bundles
                      • Multiple response content types
                      • Redirect in action
                      • Preference validator
                      • Portal context
                      • Localization support
                        • Concepts missing in the JSR 168
                          • Eventing
                          • Additional lifecycle events
                          • Property broker
                          • Portlet Menus
                          • Portlet Services
                          • Invalidation-based caching
                            • Alignment with WSRP
                              • Outlook for the next version of the JSR 168
                              • Guidelines for programming IBM Portlet API portlets
                                • Similar Functionality
                                  • Basic programming model
                                  • Portlet private session
                                  • User profile information
                                  • Persistent data
                                  • Portlet modes and window states
                                  • Expiration-based caching
                                    • Slightly different functionality
                                      • Sharing of data between portlets
                                      • Session listeners
                                        • New JSR 168 functionality
                                          • Navigational state (render parameters)
                                            • Pitfalls
                                              • Request response objects for action and render phase
                                              • Include search path
                                              • Form parameter encoding
                                              • Title setting
                                                  • Examples
                                                    • IBM Portlet API Portlet Code
                                                    • JSR 168 Portlet Code
                                                    • IBM Portlet API JSPs
                                                    • JSR 168 JSPs
                                                      • Summary
Page 17: Difference Bw Jsr168 and Ibm

ltportlet-modegteditltportlet-modegt

ltsupportsgt

ltsupported-localegtENltsupported-localegt

ltportlet-infogt

lttitlegtMy Bookmarks7lttitlegt

ltshort-titlegtBookmarks7ltshort-titlegt

ltkeywordsgtbookmarksltkeywordsgt

ltportlet-infogt

ltportlet-preferencesgt

ltpreferencegt

ltnamegturl1ltnamegt

ltvaluegthttpwwwgooglecomltvaluegt

ltpreferencegt

ltportlet-preferencesgt

ltportletgt

ltportlet-appgt

Here the initialization parameters are directly specified in the portletxml as portlets are independent components in the JSR 168 The following example represents the webxml for the JSR 168 bookmark portlet

JSR 168 WEBXML EXAMPLE

ltxml version=10 encoding=UTF-8gt

ltDOCTYPE web-app PUBLIC -Sun Microsystems IncDTD Web Application 23EN

httpjavasuncomdtdweb-app_2_3dtdgt

ltweb-appgt

ltdisplay-namegtBookmark Application7ltdisplay-namegt

ltweb-appgt

The only item that needs to be specified in the JSR 168 webxml 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 portletxml as portlet application name as there can be several concrete instances of the same abstract application

- 17 -

332 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 331) 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 331) 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

333 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

334 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 instanceentity 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 -

335 Portlet API does not extend servlet API

In the IBM Portlet API portlets extend servlets and all the major interfaces (Request Response Session hellip) 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

336 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

bull defineObjects tag ndash to define the basic portlet API objects RenderRequest RenderResponse and PortletConfig

bull actionURL tag ndash to create an action URL bull renderURL tag ndash to create a render URL bull namespace tag ndash 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 donrsquot need decoding

34 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 -

341 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 (eg 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

342 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

3421 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

3422 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 322) 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

3423 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

3424 Request Response properties

Properties can be used by the portalportlet container to send vendor specific information to the portlet andor the portlet can send vendor specific information to the portalportlet-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

343 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 (eg between portlets or between a portlet and a servlet)

344 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 23 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

345 J2EE role support

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

346 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 -

347 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 PortletRequestgetResponseContentTypes 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 (eg ldquotextrdquo or ldquordquo) 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

348 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 (eg an accounting servlet) in response to an action

349 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

3410 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 vendorrsquos 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)

3411 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 xmllang attribute like the

- 22 -

servlet 24 deployment descriptor Thus the same tag with descriptions in different languages can be used (eg 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

35 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)

351 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

bull ActionEventThe action event maps to the action phase call in the JSR 168

bull MessageEventMessage 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)

bull PortletApplicationSettingsAttributeEventPortletSettingsAttributeEventThese are events that get fired when attributes for the application or of the portlet settings change

bull WindowEventThe portlet will register for window events to get notified if the portlet window is changed via the window decorations

352 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 -

bull PortletPageListener The page listeners provides the portlet with events for the beginning of the page before any markup is written for this page (eg to write JavaScript at the beginning of the page) and the end of the page after all markup is written

bull 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 23 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

bull EventPhaseListener The event phase listener notifies the portlet of the beginning and end of the eventaction phase

353 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

354 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 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

Figure 4

- 24 -

Figure 4 Portlet menu example

355 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

356 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 -

36 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 indicates portlet in what mode to operate for a given request

View edit help + custom modes

view edit help + custom modes

full alignment

Window State the state of the window in which the portlet output will be displayed

minimized normal maximized solo +

custom window states

minimized normal maximized +

custom window states

full alignment (ldquosolordquo is missing in the JSR but can be implemented as a custom state)

URL encoding to allow re-writing URLs created by the portlet

defines how to create URLs to allow re-writing of the URLs either on consumer or producer side

encapsulates URL creation via a Java object

full alignment (the implementation of the Java object can implement the WSRP URL rewriting rules)

Namespace encoding to avoid that several portlets on a page conflicting with each other

defines namespace prefixes for consumer and producer side namespacing

provides a Java method to namespace a String

full alignment (the JSR namespace method can implement the WSRP namespace behavior)

User ndash portlet interaction operations

performBlockingInteraction blocking action processing

getMarkup render the markup

action blocking action processing

render render the makup

full alignment (action invocations carried through performBlockingInteraction render carried through getMarkup)

View state that allows the current portlet fragment to be correctly displayed in sub-sequent render calls

navigational state render parameter full alignment (WSRP navigational state maps to JSR render parameters)

Storing transient state across request

session state concept implemented via a sessionID

utilizes the Http web application session

full alignment (the WSRP sessionID can be used to reference the JSR session)

Storing persistent state to personalize the rendering of the portlet

allows to have properties of arbitrary types

provides String-based preferences

full alignment (JSR String preferences can be mapped to WSRP properties)

Information about the portal calling the portlet

RegistrationData provide information of the consumer to the producer

PortalContext provide a Java interface to access information about the portal calling the portlet

full alignment (all data represented through the PortalContext to the JSR portlet are available in the RegistrationData)

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

Aggregated HTML WML VoiceXML

over HTTPMark-Up Fragments

Transferred via WSRP

Portal

WSRP Service

WSRP Service

WSRP Service

WSRP Consumer WSRP Producer

Use of WSRP Services in Portals

Portal sharing Portlets as WSRP Services

ServerPortalPortals

Huge numberof users Publishing Portal

WSRPWrapperPortalsPortalsPortal

Portlet

Portlet

Portlet

WSRP Consumer WSRP Producer

ProxyPortlet

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

bull 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

bull 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

bull 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

bull 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 CCPP standard allowing a portlet to query the client capabilities and adopting its markup accordingly (eg screen size browser) This API is likely to be included in the next version of the portlet API Also J2EE 14 was finalized during this time period J2EE 14 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 14

bull caching The first version of the JSR 168 API is limited to expiration-based caching (see section 327) 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

bull 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

51 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

511 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

bull portlets are components Portlets are components that implement a specific function Different functions should be distributed to different portlets

bull 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

bull 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

512 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 HttpServletRequestgetSession() call in the JSPs called via the IBM Portlet API needs to be replaced when moving to JSR 168 portlets by the RenderRequestgetPortletSession() 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 HttpServletRequestgetSession() will get the HttpSession and therefore need to access the portlet session via the RenderRequest

513 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

514 Persistent data

Portlets can store customization and personalization data persistently Customization data are related to the portlet and are valid for all users (eg 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 (eg 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

515 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

516 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

52 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

521 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 351 353) 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

522 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

53 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 -

531 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

bull no support of the back button in the browser bull current state of the portlet is not bookmarkable bull 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 bull 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

54 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

541 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 -

542 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

543 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

544 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 wersquoll 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

Figure 7After clicking on the Edit mode button the portlet renders the Edit view shown in

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

Figure 8

After we press the ldquoAddrdquo 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

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

bull use JSPs for rendering the output bull customize the portlet output taking user specific data into account bull 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

61 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 comibmwpssampleswp5

import javaio

import javautil

import orgapachejetspeedportlet

import orgapachejetspeedportletevent

public class IbmBookmark extends PortletAdapter implements ActionListener

public void init(PortletConfig portletConfig) throws UnavailableException

superinit(portletConfig)

- 36 -

public void doView(PortletRequest request PortletResponse response)

throws PortletException IOException

String jspName = thisgetPortletConfig()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 = responsecreateReturnURI()

addURIaddAction(add)

requestsetAttribute(addURI addURItoString())

PortletURI cancelURI = responsecreateReturnURI()

requestsetAttribute(cancelURI cancelURItoString())

String jspName = thisgetPortletConfig()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 ldquocancelrdquo and ldquoaddrdquo URLs are created inside the portlet and attached to the request before including the Edit JSP Both URLs are from type ldquoReturnURIrdquo 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 = eventgetRequest()

String action = eventgetActionString()

PortletLog log = getPortletLog()

if ( action=null )

try

if (actionequals(removeURI))

String removeName = requestgetParameter(remove)

PortletData portData = requestgetData()

portDataremoveAttribute(removeName)

portDatastore()

if (actionequals(add))

PortletData portData = requestgetData()

String name = requestgetParameter(name)

String value = requestgetParameter(value)

portDatasetAttribute(name value)

portDatastore()

catch ( AccessDeniedException ade )

logerror(AccessDeniedException occured when adding or deleting a bookmark)

catch ( IOException ioe )

logerror(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 ldquoaddrdquo or ldquodeleterdquo 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 ldquoaddrdquo or ldquoremoveURIrdquo If the user has clicked on the ldquoremoverdquo button the corresponding link is removed from the portlet data whereas if ldquoaddrdquo was clicked the data entered by the user is added to the portlet data

62 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 comibmwpssamplesjsr

import javaio

import javaxportlet

public class Bookmark extends GenericPortlet

public void init(PortletConfig config) throws PortletException

superinit(config)

public void doView(RenderRequest request RenderResponse response)

throws PortletException IOException

responsesetContentType(texthtml)

String jspName = getPortletConfig()getInitParameter(jspView)

PortletRequestDispatcher rd = getPortletContext()getRequestDispatcher(jspName)

rdinclude(requestresponse)

- 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

responsesetContentType(texthtml)

PortletURL addUrl = responsecreateActionURL()

addUrlsetPortletMode(PortletModeVIEW)

addUrlsetParameter(addadd)

requestsetAttribute(addUrladdUrltoString())

PortletURL cancelUrl = responsecreateRenderURL()

cancelUrlsetPortletMode(PortletModeVIEW)

requestsetAttribute(cancelUrlcancelUrltoString())

String jspName = getPortletConfig()getInitParameter(jspEdit)

PortletRequestDispatcher rd = getPortletContext()getRequestDispatcher(jspName)

rdinclude(requestresponse)

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 ldquoaddrdquo button URL an action URL is created as we need to store the user input of the add form persistently For the ldquocancelrdquo 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 = requestgetParameter(remove)

if (removeName = null)

PortletPreferences prefs = requestgetPreferences()

prefsreset(removeName)

prefsstore()

String add = requestgetParameter(add)

if (add = null)

PortletPreferences prefs = requestgetPreferences()

String name = requestgetParameter(name)

String value = requestgetParameter(value)

prefssetValue(name value)

prefsstore()

catch ( IOException ioe )

getPortletContextlog(An IO error occured when trying to remove a bookmark)

catch ( PortletException pe )

getPortletContextlog(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

bull 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

bull 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

bull Persistent portlet data The JSR 168 persistent data PortletPreferences have an API similar to the JDK 14 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

bull 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

63 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

lt page contentType=texthtml import=javautil comibmwpssampleswp5

orgapachejetspeedportlet session=falsegt

lt taglib uri=WEB-INFtldportlettld prefix=portletAPI gt

- 42 -

ltportletAPIinitgt

ltp class=wpsPortletHeadgtltportletAPItext key=available_bookmarks

bundle=nlsTextgtAvailable BookmarksltportletAPItextgtltpgt

lt

PortletData prefs = portletRequestgetData()

Enumeration e = prefsgetAttributeNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltportletAPItext key=no_bookmarks bundle=nlsTextgtNo

bookmarksltportletAPItextgtltpgt

lt

else

gt

ltp class=wpsIndentMediumgt

lt

while (ehasMoreElements())

String name = (String)enextElement()

String value = (String)prefsgetAttribute(name)

gt

lta href=lt=valuegt target=_blankgtlt=namegtltagtltbr gt

lt

gt

ltpgt

The View JSP first call portletAPIinit 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

lt page contentType=texthtml import=javautil

comibmwpssampleswp5orgapachejetspeedportlet session=falsegt

lt taglib uri=WEB-INFtldportlettld prefix=portletAPI gt

ltjspuseBean id=addURI class=javalangString scope=request gt

ltjspuseBean id=cancelURI class=javalangString scope=request gt

ltportletAPIinitgt

lth4gtltportletAPItext key=available_bookmarks bundle=nlsTextgtAvailable

BookmarksltportletAPItextgtlth4gt

lttable class=wpsTablegt

lttr class=wpsTableRowgt

ltth class=portlet-table-headergtltportletAPItext key=name bundle=nlsTextgtltthgt

ltth class=portlet-table-headergtltportletAPItext key=url bundle=nlsTextgtltthgt

lttdgtlttdgt

lttrgt

lt

PortletData prefs = portletRequestgetData()

Enumeration e = prefsgetAttributeNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltportletAPItext key=no_bookmarks bundle=nlsTextgtNo

bookmarksltportletAPItextgtltpgt

lt

else

while (ehasMoreElements())

- 44 -

String name = (String)enextElement()

String value = (String)prefsgetAttribute(name)

gt

lttr class=wpsTableRowgt

lttdgt lt=namegt lttdgt

lttdgt lt=valuegt lttdgt

lttdgt lta href=ltportletAPIcreateURIgtltportletAPIURIAction

name=removeURIgtltportletAPIURIParameter name=remove

value=lt=namegtgtltportletAPIcreateURIgtgt

(ltportletAPItext key=delete bundle=nlsTextgt)ltagt

lttdgt

lttrgt

lt

gt

ltform action=lt=addURIgt method=POSTgt

lttr class=wpsTableRowgt

lttdgtltinput name=ltportletAPIencodeNamespace value=namegt type=text

class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=ltportletAPIencodeNamespace value=valuegt type=text

class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=ltportletAPIencodeNamespace value=addgt type=submit

value=ltportletAPItext key=add bundle=nlsTextgt class=portlet-form-buttongtlttdgt

lttrgt

ltformgt

lttablegt

- 45 -

ltform action=lt=cancelURIgt method=postgt

ltinput name=ltportletAPIencodeNamespace value=cancelgt type=submit

value=ltportletAPItext key=cancel bundle=nlsTextgt class=portlet-form-buttongt

ltformgt

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 ldquodeleterdquo button for which an URL with the action ldquoremoveURIrdquo 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 ldquocancelrdquo button from the request

64 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

lt page import=javaxportlet javautil session=falsegt

lt taglib uri=httpjavasuncomportlet prefix=portletAPI gt

lt taglib prefix=fmt uri=httpjavasuncomjstlfmt gt

ltportletAPIdefineObjects gt

ltfmtsetBundle basename=nlsTextgt

lt

ResourceBundle myText = ResourceBundlegetBundle(nlsText requestgetLocale())

gt

lth4gtltfmtmessage key=available_bookmarksgtlth4gt

lt

PortletPreferences prefs = renderRequestgetPreferences()

Enumeration e = prefsgetNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltfmtmessage key=no_bookmarksgtltpgt

- 46 -

lt

else

gt

ltpgt

lt

while (ehasMoreElements())

String name = (String)enextElement()

String value = prefsgetValue(namelt+myTextgetString(undefined)+gt)

gt

lta href=lt=valuegt target=_blankgtlt=namegtltagtltbr gt

lt

gt

ltpgt

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 fmtmessage 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

lt page import=javaxportlet javautil session=false gt

lt taglib uri=httpjavasuncomportlet prefix=portletAPI gt

lt taglib prefix=fmt uri=httpjavasuncomjstlfmt gt

ltjspuseBean id=addUrl scope=request class=javalangString gt

ltjspuseBean id=cancelUrl scope=request class=javalangString gt

- 47 -

ltportletAPIdefineObjectsgt

lt

ResourceBundle myText = ResourceBundlegetBundle(nlsText requestgetLocale())

gt

ltfmtsetBundle basename=nlsTextgt

lth4gtltfmtmessage key=available_bookmarksgtlth4gt

lttable class=wpsTablegt

lttr class=wpsTableRowgt

ltth class=wpsTableHeadgtltfmtmessage key=namegtltthgt

ltth class=wpsTableHeadgtltfmtmessage key=urlgtltthgt

lttdgtlttdgt

lttrgt

lt

PortletPreferences prefs = renderRequestgetPreferences()

Enumeration e = prefsgetNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltfmtmessage key=no_bookmarksgtltpgt

lt

else

while (ehasMoreElements())

String name = (String)enextElement()

String value = prefsgetValue(namelt+myTextgetString(undefined)+gt)

gt

lttr class=wpsTableRowgt

lttdgt lt=namegt lttdgt

lttdgt lt=valuegt lttdgt

- 48 -

lttdgt ltportletAPIactionURL var=removeUrlgt

ltportletAPIparam name=remove value=lt=namegtgt

ltportletAPIactionURLgt

lta href=lt=removeUrltoString()gtgt(ltfmtmessage key=deletegt)ltagt

lttdgt

lttrgt

lt

gt

ltform action=lt=addUrlgt method=POSTgt

lttr class=wpsTableRowgt

lttdgtltinput name=name type=text class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=value type=text class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=add type=submit value=ltfmtmessage key=addgt

class=portlet-form-buttongtlttdgt

lttrgt

ltformgt

lttablegt

ltform action=lt=cancelUrlgt method=postgt

ltinput name=cancel type=submit value=ltfmtmessage key=cancelgt class=portlet-

form-buttongt

ltformgt

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 14 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 -

- 51 -

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 (eg eventing) the IBM Portlet API still needs to be used Trademarks bull IBM and WebSphere are trademarks or registered trademarks of IBM Corporation in

the United States other countries or both bull 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 bull Other company product and service names may be trademarks or service marks of

others IBM copyright and trademark information httpwwwibmcomlegalcopytradephtml

  • Introduction
  • JSR 168 and the Java Community Process
  • Comparing concepts
    • Basic concepts
      • Portal
      • Portal page
      • Portlet
      • Portlet Container
        • Concepts that are the same
          • Portlet mode
          • Window state
          • Portlet life cycle and request processing
          • URL encoding
          • Include servletsJSPs
          • Portlet application packaging
          • Expiration-based caching
            • Concepts that differ
              • Portlet application entity
              • Portlet entity
              • Action and Render Request Response objects
              • Window concept
              • Portlet API does not extend servlet API
              • TAG libraries
                • Concepts new in the JSR 168
                  • Render parameter
                  • Extension mechanisms
                    • Custom window states
                    • Custom portlet modes
                    • Custom user info
                    • Request Response properties
                      • Web application session scope
                      • Reuse of the HttpSession listeners
                      • J2EE role support
                      • Resource bundles
                      • Multiple response content types
                      • Redirect in action
                      • Preference validator
                      • Portal context
                      • Localization support
                        • Concepts missing in the JSR 168
                          • Eventing
                          • Additional lifecycle events
                          • Property broker
                          • Portlet Menus
                          • Portlet Services
                          • Invalidation-based caching
                            • Alignment with WSRP
                              • Outlook for the next version of the JSR 168
                              • Guidelines for programming IBM Portlet API portlets
                                • Similar Functionality
                                  • Basic programming model
                                  • Portlet private session
                                  • User profile information
                                  • Persistent data
                                  • Portlet modes and window states
                                  • Expiration-based caching
                                    • Slightly different functionality
                                      • Sharing of data between portlets
                                      • Session listeners
                                        • New JSR 168 functionality
                                          • Navigational state (render parameters)
                                            • Pitfalls
                                              • Request response objects for action and render phase
                                              • Include search path
                                              • Form parameter encoding
                                              • Title setting
                                                  • Examples
                                                    • IBM Portlet API Portlet Code
                                                    • JSR 168 Portlet Code
                                                    • IBM Portlet API JSPs
                                                    • JSR 168 JSPs
                                                      • Summary
Page 18: Difference Bw Jsr168 and Ibm

332 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 331) 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 331) 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

333 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

334 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 instanceentity 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 -

335 Portlet API does not extend servlet API

In the IBM Portlet API portlets extend servlets and all the major interfaces (Request Response Session hellip) 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

336 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

bull defineObjects tag ndash to define the basic portlet API objects RenderRequest RenderResponse and PortletConfig

bull actionURL tag ndash to create an action URL bull renderURL tag ndash to create a render URL bull namespace tag ndash 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 donrsquot need decoding

34 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 -

341 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 (eg 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

342 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

3421 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

3422 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 322) 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

3423 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

3424 Request Response properties

Properties can be used by the portalportlet container to send vendor specific information to the portlet andor the portlet can send vendor specific information to the portalportlet-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

343 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 (eg between portlets or between a portlet and a servlet)

344 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 23 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

345 J2EE role support

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

346 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 -

347 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 PortletRequestgetResponseContentTypes 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 (eg ldquotextrdquo or ldquordquo) 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

348 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 (eg an accounting servlet) in response to an action

349 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

3410 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 vendorrsquos 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)

3411 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 xmllang attribute like the

- 22 -

servlet 24 deployment descriptor Thus the same tag with descriptions in different languages can be used (eg 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

35 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)

351 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

bull ActionEventThe action event maps to the action phase call in the JSR 168

bull MessageEventMessage 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)

bull PortletApplicationSettingsAttributeEventPortletSettingsAttributeEventThese are events that get fired when attributes for the application or of the portlet settings change

bull WindowEventThe portlet will register for window events to get notified if the portlet window is changed via the window decorations

352 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 -

bull PortletPageListener The page listeners provides the portlet with events for the beginning of the page before any markup is written for this page (eg to write JavaScript at the beginning of the page) and the end of the page after all markup is written

bull 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 23 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

bull EventPhaseListener The event phase listener notifies the portlet of the beginning and end of the eventaction phase

353 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

354 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 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

Figure 4

- 24 -

Figure 4 Portlet menu example

355 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

356 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 -

36 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 indicates portlet in what mode to operate for a given request

View edit help + custom modes

view edit help + custom modes

full alignment

Window State the state of the window in which the portlet output will be displayed

minimized normal maximized solo +

custom window states

minimized normal maximized +

custom window states

full alignment (ldquosolordquo is missing in the JSR but can be implemented as a custom state)

URL encoding to allow re-writing URLs created by the portlet

defines how to create URLs to allow re-writing of the URLs either on consumer or producer side

encapsulates URL creation via a Java object

full alignment (the implementation of the Java object can implement the WSRP URL rewriting rules)

Namespace encoding to avoid that several portlets on a page conflicting with each other

defines namespace prefixes for consumer and producer side namespacing

provides a Java method to namespace a String

full alignment (the JSR namespace method can implement the WSRP namespace behavior)

User ndash portlet interaction operations

performBlockingInteraction blocking action processing

getMarkup render the markup

action blocking action processing

render render the makup

full alignment (action invocations carried through performBlockingInteraction render carried through getMarkup)

View state that allows the current portlet fragment to be correctly displayed in sub-sequent render calls

navigational state render parameter full alignment (WSRP navigational state maps to JSR render parameters)

Storing transient state across request

session state concept implemented via a sessionID

utilizes the Http web application session

full alignment (the WSRP sessionID can be used to reference the JSR session)

Storing persistent state to personalize the rendering of the portlet

allows to have properties of arbitrary types

provides String-based preferences

full alignment (JSR String preferences can be mapped to WSRP properties)

Information about the portal calling the portlet

RegistrationData provide information of the consumer to the producer

PortalContext provide a Java interface to access information about the portal calling the portlet

full alignment (all data represented through the PortalContext to the JSR portlet are available in the RegistrationData)

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

Aggregated HTML WML VoiceXML

over HTTPMark-Up Fragments

Transferred via WSRP

Portal

WSRP Service

WSRP Service

WSRP Service

WSRP Consumer WSRP Producer

Use of WSRP Services in Portals

Portal sharing Portlets as WSRP Services

ServerPortalPortals

Huge numberof users Publishing Portal

WSRPWrapperPortalsPortalsPortal

Portlet

Portlet

Portlet

WSRP Consumer WSRP Producer

ProxyPortlet

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

bull 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

bull 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

bull 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

bull 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 CCPP standard allowing a portlet to query the client capabilities and adopting its markup accordingly (eg screen size browser) This API is likely to be included in the next version of the portlet API Also J2EE 14 was finalized during this time period J2EE 14 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 14

bull caching The first version of the JSR 168 API is limited to expiration-based caching (see section 327) 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

bull 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

51 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

511 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

bull portlets are components Portlets are components that implement a specific function Different functions should be distributed to different portlets

bull 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

bull 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

512 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 HttpServletRequestgetSession() call in the JSPs called via the IBM Portlet API needs to be replaced when moving to JSR 168 portlets by the RenderRequestgetPortletSession() 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 HttpServletRequestgetSession() will get the HttpSession and therefore need to access the portlet session via the RenderRequest

513 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

514 Persistent data

Portlets can store customization and personalization data persistently Customization data are related to the portlet and are valid for all users (eg 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 (eg 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

515 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

516 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

52 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

521 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 351 353) 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

522 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

53 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 -

531 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

bull no support of the back button in the browser bull current state of the portlet is not bookmarkable bull 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 bull 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

54 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

541 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 -

542 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

543 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

544 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 wersquoll 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

Figure 7After clicking on the Edit mode button the portlet renders the Edit view shown in

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

Figure 8

After we press the ldquoAddrdquo 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

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

bull use JSPs for rendering the output bull customize the portlet output taking user specific data into account bull 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

61 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 comibmwpssampleswp5

import javaio

import javautil

import orgapachejetspeedportlet

import orgapachejetspeedportletevent

public class IbmBookmark extends PortletAdapter implements ActionListener

public void init(PortletConfig portletConfig) throws UnavailableException

superinit(portletConfig)

- 36 -

public void doView(PortletRequest request PortletResponse response)

throws PortletException IOException

String jspName = thisgetPortletConfig()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 = responsecreateReturnURI()

addURIaddAction(add)

requestsetAttribute(addURI addURItoString())

PortletURI cancelURI = responsecreateReturnURI()

requestsetAttribute(cancelURI cancelURItoString())

String jspName = thisgetPortletConfig()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 ldquocancelrdquo and ldquoaddrdquo URLs are created inside the portlet and attached to the request before including the Edit JSP Both URLs are from type ldquoReturnURIrdquo 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 = eventgetRequest()

String action = eventgetActionString()

PortletLog log = getPortletLog()

if ( action=null )

try

if (actionequals(removeURI))

String removeName = requestgetParameter(remove)

PortletData portData = requestgetData()

portDataremoveAttribute(removeName)

portDatastore()

if (actionequals(add))

PortletData portData = requestgetData()

String name = requestgetParameter(name)

String value = requestgetParameter(value)

portDatasetAttribute(name value)

portDatastore()

catch ( AccessDeniedException ade )

logerror(AccessDeniedException occured when adding or deleting a bookmark)

catch ( IOException ioe )

logerror(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 ldquoaddrdquo or ldquodeleterdquo 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 ldquoaddrdquo or ldquoremoveURIrdquo If the user has clicked on the ldquoremoverdquo button the corresponding link is removed from the portlet data whereas if ldquoaddrdquo was clicked the data entered by the user is added to the portlet data

62 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 comibmwpssamplesjsr

import javaio

import javaxportlet

public class Bookmark extends GenericPortlet

public void init(PortletConfig config) throws PortletException

superinit(config)

public void doView(RenderRequest request RenderResponse response)

throws PortletException IOException

responsesetContentType(texthtml)

String jspName = getPortletConfig()getInitParameter(jspView)

PortletRequestDispatcher rd = getPortletContext()getRequestDispatcher(jspName)

rdinclude(requestresponse)

- 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

responsesetContentType(texthtml)

PortletURL addUrl = responsecreateActionURL()

addUrlsetPortletMode(PortletModeVIEW)

addUrlsetParameter(addadd)

requestsetAttribute(addUrladdUrltoString())

PortletURL cancelUrl = responsecreateRenderURL()

cancelUrlsetPortletMode(PortletModeVIEW)

requestsetAttribute(cancelUrlcancelUrltoString())

String jspName = getPortletConfig()getInitParameter(jspEdit)

PortletRequestDispatcher rd = getPortletContext()getRequestDispatcher(jspName)

rdinclude(requestresponse)

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 ldquoaddrdquo button URL an action URL is created as we need to store the user input of the add form persistently For the ldquocancelrdquo 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 = requestgetParameter(remove)

if (removeName = null)

PortletPreferences prefs = requestgetPreferences()

prefsreset(removeName)

prefsstore()

String add = requestgetParameter(add)

if (add = null)

PortletPreferences prefs = requestgetPreferences()

String name = requestgetParameter(name)

String value = requestgetParameter(value)

prefssetValue(name value)

prefsstore()

catch ( IOException ioe )

getPortletContextlog(An IO error occured when trying to remove a bookmark)

catch ( PortletException pe )

getPortletContextlog(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

bull 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

bull 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

bull Persistent portlet data The JSR 168 persistent data PortletPreferences have an API similar to the JDK 14 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

bull 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

63 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

lt page contentType=texthtml import=javautil comibmwpssampleswp5

orgapachejetspeedportlet session=falsegt

lt taglib uri=WEB-INFtldportlettld prefix=portletAPI gt

- 42 -

ltportletAPIinitgt

ltp class=wpsPortletHeadgtltportletAPItext key=available_bookmarks

bundle=nlsTextgtAvailable BookmarksltportletAPItextgtltpgt

lt

PortletData prefs = portletRequestgetData()

Enumeration e = prefsgetAttributeNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltportletAPItext key=no_bookmarks bundle=nlsTextgtNo

bookmarksltportletAPItextgtltpgt

lt

else

gt

ltp class=wpsIndentMediumgt

lt

while (ehasMoreElements())

String name = (String)enextElement()

String value = (String)prefsgetAttribute(name)

gt

lta href=lt=valuegt target=_blankgtlt=namegtltagtltbr gt

lt

gt

ltpgt

The View JSP first call portletAPIinit 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

lt page contentType=texthtml import=javautil

comibmwpssampleswp5orgapachejetspeedportlet session=falsegt

lt taglib uri=WEB-INFtldportlettld prefix=portletAPI gt

ltjspuseBean id=addURI class=javalangString scope=request gt

ltjspuseBean id=cancelURI class=javalangString scope=request gt

ltportletAPIinitgt

lth4gtltportletAPItext key=available_bookmarks bundle=nlsTextgtAvailable

BookmarksltportletAPItextgtlth4gt

lttable class=wpsTablegt

lttr class=wpsTableRowgt

ltth class=portlet-table-headergtltportletAPItext key=name bundle=nlsTextgtltthgt

ltth class=portlet-table-headergtltportletAPItext key=url bundle=nlsTextgtltthgt

lttdgtlttdgt

lttrgt

lt

PortletData prefs = portletRequestgetData()

Enumeration e = prefsgetAttributeNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltportletAPItext key=no_bookmarks bundle=nlsTextgtNo

bookmarksltportletAPItextgtltpgt

lt

else

while (ehasMoreElements())

- 44 -

String name = (String)enextElement()

String value = (String)prefsgetAttribute(name)

gt

lttr class=wpsTableRowgt

lttdgt lt=namegt lttdgt

lttdgt lt=valuegt lttdgt

lttdgt lta href=ltportletAPIcreateURIgtltportletAPIURIAction

name=removeURIgtltportletAPIURIParameter name=remove

value=lt=namegtgtltportletAPIcreateURIgtgt

(ltportletAPItext key=delete bundle=nlsTextgt)ltagt

lttdgt

lttrgt

lt

gt

ltform action=lt=addURIgt method=POSTgt

lttr class=wpsTableRowgt

lttdgtltinput name=ltportletAPIencodeNamespace value=namegt type=text

class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=ltportletAPIencodeNamespace value=valuegt type=text

class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=ltportletAPIencodeNamespace value=addgt type=submit

value=ltportletAPItext key=add bundle=nlsTextgt class=portlet-form-buttongtlttdgt

lttrgt

ltformgt

lttablegt

- 45 -

ltform action=lt=cancelURIgt method=postgt

ltinput name=ltportletAPIencodeNamespace value=cancelgt type=submit

value=ltportletAPItext key=cancel bundle=nlsTextgt class=portlet-form-buttongt

ltformgt

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 ldquodeleterdquo button for which an URL with the action ldquoremoveURIrdquo 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 ldquocancelrdquo button from the request

64 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

lt page import=javaxportlet javautil session=falsegt

lt taglib uri=httpjavasuncomportlet prefix=portletAPI gt

lt taglib prefix=fmt uri=httpjavasuncomjstlfmt gt

ltportletAPIdefineObjects gt

ltfmtsetBundle basename=nlsTextgt

lt

ResourceBundle myText = ResourceBundlegetBundle(nlsText requestgetLocale())

gt

lth4gtltfmtmessage key=available_bookmarksgtlth4gt

lt

PortletPreferences prefs = renderRequestgetPreferences()

Enumeration e = prefsgetNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltfmtmessage key=no_bookmarksgtltpgt

- 46 -

lt

else

gt

ltpgt

lt

while (ehasMoreElements())

String name = (String)enextElement()

String value = prefsgetValue(namelt+myTextgetString(undefined)+gt)

gt

lta href=lt=valuegt target=_blankgtlt=namegtltagtltbr gt

lt

gt

ltpgt

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 fmtmessage 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

lt page import=javaxportlet javautil session=false gt

lt taglib uri=httpjavasuncomportlet prefix=portletAPI gt

lt taglib prefix=fmt uri=httpjavasuncomjstlfmt gt

ltjspuseBean id=addUrl scope=request class=javalangString gt

ltjspuseBean id=cancelUrl scope=request class=javalangString gt

- 47 -

ltportletAPIdefineObjectsgt

lt

ResourceBundle myText = ResourceBundlegetBundle(nlsText requestgetLocale())

gt

ltfmtsetBundle basename=nlsTextgt

lth4gtltfmtmessage key=available_bookmarksgtlth4gt

lttable class=wpsTablegt

lttr class=wpsTableRowgt

ltth class=wpsTableHeadgtltfmtmessage key=namegtltthgt

ltth class=wpsTableHeadgtltfmtmessage key=urlgtltthgt

lttdgtlttdgt

lttrgt

lt

PortletPreferences prefs = renderRequestgetPreferences()

Enumeration e = prefsgetNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltfmtmessage key=no_bookmarksgtltpgt

lt

else

while (ehasMoreElements())

String name = (String)enextElement()

String value = prefsgetValue(namelt+myTextgetString(undefined)+gt)

gt

lttr class=wpsTableRowgt

lttdgt lt=namegt lttdgt

lttdgt lt=valuegt lttdgt

- 48 -

lttdgt ltportletAPIactionURL var=removeUrlgt

ltportletAPIparam name=remove value=lt=namegtgt

ltportletAPIactionURLgt

lta href=lt=removeUrltoString()gtgt(ltfmtmessage key=deletegt)ltagt

lttdgt

lttrgt

lt

gt

ltform action=lt=addUrlgt method=POSTgt

lttr class=wpsTableRowgt

lttdgtltinput name=name type=text class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=value type=text class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=add type=submit value=ltfmtmessage key=addgt

class=portlet-form-buttongtlttdgt

lttrgt

ltformgt

lttablegt

ltform action=lt=cancelUrlgt method=postgt

ltinput name=cancel type=submit value=ltfmtmessage key=cancelgt class=portlet-

form-buttongt

ltformgt

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 14 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 -

- 51 -

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 (eg eventing) the IBM Portlet API still needs to be used Trademarks bull IBM and WebSphere are trademarks or registered trademarks of IBM Corporation in

the United States other countries or both bull 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 bull Other company product and service names may be trademarks or service marks of

others IBM copyright and trademark information httpwwwibmcomlegalcopytradephtml

  • Introduction
  • JSR 168 and the Java Community Process
  • Comparing concepts
    • Basic concepts
      • Portal
      • Portal page
      • Portlet
      • Portlet Container
        • Concepts that are the same
          • Portlet mode
          • Window state
          • Portlet life cycle and request processing
          • URL encoding
          • Include servletsJSPs
          • Portlet application packaging
          • Expiration-based caching
            • Concepts that differ
              • Portlet application entity
              • Portlet entity
              • Action and Render Request Response objects
              • Window concept
              • Portlet API does not extend servlet API
              • TAG libraries
                • Concepts new in the JSR 168
                  • Render parameter
                  • Extension mechanisms
                    • Custom window states
                    • Custom portlet modes
                    • Custom user info
                    • Request Response properties
                      • Web application session scope
                      • Reuse of the HttpSession listeners
                      • J2EE role support
                      • Resource bundles
                      • Multiple response content types
                      • Redirect in action
                      • Preference validator
                      • Portal context
                      • Localization support
                        • Concepts missing in the JSR 168
                          • Eventing
                          • Additional lifecycle events
                          • Property broker
                          • Portlet Menus
                          • Portlet Services
                          • Invalidation-based caching
                            • Alignment with WSRP
                              • Outlook for the next version of the JSR 168
                              • Guidelines for programming IBM Portlet API portlets
                                • Similar Functionality
                                  • Basic programming model
                                  • Portlet private session
                                  • User profile information
                                  • Persistent data
                                  • Portlet modes and window states
                                  • Expiration-based caching
                                    • Slightly different functionality
                                      • Sharing of data between portlets
                                      • Session listeners
                                        • New JSR 168 functionality
                                          • Navigational state (render parameters)
                                            • Pitfalls
                                              • Request response objects for action and render phase
                                              • Include search path
                                              • Form parameter encoding
                                              • Title setting
                                                  • Examples
                                                    • IBM Portlet API Portlet Code
                                                    • JSR 168 Portlet Code
                                                    • IBM Portlet API JSPs
                                                    • JSR 168 JSPs
                                                      • Summary
Page 19: Difference Bw Jsr168 and Ibm

335 Portlet API does not extend servlet API

In the IBM Portlet API portlets extend servlets and all the major interfaces (Request Response Session hellip) 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

336 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

bull defineObjects tag ndash to define the basic portlet API objects RenderRequest RenderResponse and PortletConfig

bull actionURL tag ndash to create an action URL bull renderURL tag ndash to create a render URL bull namespace tag ndash 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 donrsquot need decoding

34 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 -

341 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 (eg 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

342 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

3421 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

3422 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 322) 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

3423 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

3424 Request Response properties

Properties can be used by the portalportlet container to send vendor specific information to the portlet andor the portlet can send vendor specific information to the portalportlet-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

343 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 (eg between portlets or between a portlet and a servlet)

344 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 23 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

345 J2EE role support

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

346 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 -

347 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 PortletRequestgetResponseContentTypes 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 (eg ldquotextrdquo or ldquordquo) 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

348 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 (eg an accounting servlet) in response to an action

349 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

3410 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 vendorrsquos 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)

3411 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 xmllang attribute like the

- 22 -

servlet 24 deployment descriptor Thus the same tag with descriptions in different languages can be used (eg 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

35 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)

351 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

bull ActionEventThe action event maps to the action phase call in the JSR 168

bull MessageEventMessage 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)

bull PortletApplicationSettingsAttributeEventPortletSettingsAttributeEventThese are events that get fired when attributes for the application or of the portlet settings change

bull WindowEventThe portlet will register for window events to get notified if the portlet window is changed via the window decorations

352 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 -

bull PortletPageListener The page listeners provides the portlet with events for the beginning of the page before any markup is written for this page (eg to write JavaScript at the beginning of the page) and the end of the page after all markup is written

bull 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 23 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

bull EventPhaseListener The event phase listener notifies the portlet of the beginning and end of the eventaction phase

353 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

354 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 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

Figure 4

- 24 -

Figure 4 Portlet menu example

355 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

356 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 -

36 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 indicates portlet in what mode to operate for a given request

View edit help + custom modes

view edit help + custom modes

full alignment

Window State the state of the window in which the portlet output will be displayed

minimized normal maximized solo +

custom window states

minimized normal maximized +

custom window states

full alignment (ldquosolordquo is missing in the JSR but can be implemented as a custom state)

URL encoding to allow re-writing URLs created by the portlet

defines how to create URLs to allow re-writing of the URLs either on consumer or producer side

encapsulates URL creation via a Java object

full alignment (the implementation of the Java object can implement the WSRP URL rewriting rules)

Namespace encoding to avoid that several portlets on a page conflicting with each other

defines namespace prefixes for consumer and producer side namespacing

provides a Java method to namespace a String

full alignment (the JSR namespace method can implement the WSRP namespace behavior)

User ndash portlet interaction operations

performBlockingInteraction blocking action processing

getMarkup render the markup

action blocking action processing

render render the makup

full alignment (action invocations carried through performBlockingInteraction render carried through getMarkup)

View state that allows the current portlet fragment to be correctly displayed in sub-sequent render calls

navigational state render parameter full alignment (WSRP navigational state maps to JSR render parameters)

Storing transient state across request

session state concept implemented via a sessionID

utilizes the Http web application session

full alignment (the WSRP sessionID can be used to reference the JSR session)

Storing persistent state to personalize the rendering of the portlet

allows to have properties of arbitrary types

provides String-based preferences

full alignment (JSR String preferences can be mapped to WSRP properties)

Information about the portal calling the portlet

RegistrationData provide information of the consumer to the producer

PortalContext provide a Java interface to access information about the portal calling the portlet

full alignment (all data represented through the PortalContext to the JSR portlet are available in the RegistrationData)

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

Aggregated HTML WML VoiceXML

over HTTPMark-Up Fragments

Transferred via WSRP

Portal

WSRP Service

WSRP Service

WSRP Service

WSRP Consumer WSRP Producer

Use of WSRP Services in Portals

Portal sharing Portlets as WSRP Services

ServerPortalPortals

Huge numberof users Publishing Portal

WSRPWrapperPortalsPortalsPortal

Portlet

Portlet

Portlet

WSRP Consumer WSRP Producer

ProxyPortlet

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

bull 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

bull 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

bull 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

bull 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 CCPP standard allowing a portlet to query the client capabilities and adopting its markup accordingly (eg screen size browser) This API is likely to be included in the next version of the portlet API Also J2EE 14 was finalized during this time period J2EE 14 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 14

bull caching The first version of the JSR 168 API is limited to expiration-based caching (see section 327) 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

bull 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

51 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

511 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

bull portlets are components Portlets are components that implement a specific function Different functions should be distributed to different portlets

bull 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

bull 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

512 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 HttpServletRequestgetSession() call in the JSPs called via the IBM Portlet API needs to be replaced when moving to JSR 168 portlets by the RenderRequestgetPortletSession() 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 HttpServletRequestgetSession() will get the HttpSession and therefore need to access the portlet session via the RenderRequest

513 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

514 Persistent data

Portlets can store customization and personalization data persistently Customization data are related to the portlet and are valid for all users (eg 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 (eg 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

515 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

516 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

52 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

521 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 351 353) 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

522 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

53 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 -

531 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

bull no support of the back button in the browser bull current state of the portlet is not bookmarkable bull 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 bull 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

54 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

541 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 -

542 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

543 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

544 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 wersquoll 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

Figure 7After clicking on the Edit mode button the portlet renders the Edit view shown in

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

Figure 8

After we press the ldquoAddrdquo 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

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

bull use JSPs for rendering the output bull customize the portlet output taking user specific data into account bull 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

61 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 comibmwpssampleswp5

import javaio

import javautil

import orgapachejetspeedportlet

import orgapachejetspeedportletevent

public class IbmBookmark extends PortletAdapter implements ActionListener

public void init(PortletConfig portletConfig) throws UnavailableException

superinit(portletConfig)

- 36 -

public void doView(PortletRequest request PortletResponse response)

throws PortletException IOException

String jspName = thisgetPortletConfig()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 = responsecreateReturnURI()

addURIaddAction(add)

requestsetAttribute(addURI addURItoString())

PortletURI cancelURI = responsecreateReturnURI()

requestsetAttribute(cancelURI cancelURItoString())

String jspName = thisgetPortletConfig()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 ldquocancelrdquo and ldquoaddrdquo URLs are created inside the portlet and attached to the request before including the Edit JSP Both URLs are from type ldquoReturnURIrdquo 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 = eventgetRequest()

String action = eventgetActionString()

PortletLog log = getPortletLog()

if ( action=null )

try

if (actionequals(removeURI))

String removeName = requestgetParameter(remove)

PortletData portData = requestgetData()

portDataremoveAttribute(removeName)

portDatastore()

if (actionequals(add))

PortletData portData = requestgetData()

String name = requestgetParameter(name)

String value = requestgetParameter(value)

portDatasetAttribute(name value)

portDatastore()

catch ( AccessDeniedException ade )

logerror(AccessDeniedException occured when adding or deleting a bookmark)

catch ( IOException ioe )

logerror(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 ldquoaddrdquo or ldquodeleterdquo 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 ldquoaddrdquo or ldquoremoveURIrdquo If the user has clicked on the ldquoremoverdquo button the corresponding link is removed from the portlet data whereas if ldquoaddrdquo was clicked the data entered by the user is added to the portlet data

62 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 comibmwpssamplesjsr

import javaio

import javaxportlet

public class Bookmark extends GenericPortlet

public void init(PortletConfig config) throws PortletException

superinit(config)

public void doView(RenderRequest request RenderResponse response)

throws PortletException IOException

responsesetContentType(texthtml)

String jspName = getPortletConfig()getInitParameter(jspView)

PortletRequestDispatcher rd = getPortletContext()getRequestDispatcher(jspName)

rdinclude(requestresponse)

- 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

responsesetContentType(texthtml)

PortletURL addUrl = responsecreateActionURL()

addUrlsetPortletMode(PortletModeVIEW)

addUrlsetParameter(addadd)

requestsetAttribute(addUrladdUrltoString())

PortletURL cancelUrl = responsecreateRenderURL()

cancelUrlsetPortletMode(PortletModeVIEW)

requestsetAttribute(cancelUrlcancelUrltoString())

String jspName = getPortletConfig()getInitParameter(jspEdit)

PortletRequestDispatcher rd = getPortletContext()getRequestDispatcher(jspName)

rdinclude(requestresponse)

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 ldquoaddrdquo button URL an action URL is created as we need to store the user input of the add form persistently For the ldquocancelrdquo 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 = requestgetParameter(remove)

if (removeName = null)

PortletPreferences prefs = requestgetPreferences()

prefsreset(removeName)

prefsstore()

String add = requestgetParameter(add)

if (add = null)

PortletPreferences prefs = requestgetPreferences()

String name = requestgetParameter(name)

String value = requestgetParameter(value)

prefssetValue(name value)

prefsstore()

catch ( IOException ioe )

getPortletContextlog(An IO error occured when trying to remove a bookmark)

catch ( PortletException pe )

getPortletContextlog(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

bull 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

bull 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

bull Persistent portlet data The JSR 168 persistent data PortletPreferences have an API similar to the JDK 14 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

bull 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

63 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

lt page contentType=texthtml import=javautil comibmwpssampleswp5

orgapachejetspeedportlet session=falsegt

lt taglib uri=WEB-INFtldportlettld prefix=portletAPI gt

- 42 -

ltportletAPIinitgt

ltp class=wpsPortletHeadgtltportletAPItext key=available_bookmarks

bundle=nlsTextgtAvailable BookmarksltportletAPItextgtltpgt

lt

PortletData prefs = portletRequestgetData()

Enumeration e = prefsgetAttributeNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltportletAPItext key=no_bookmarks bundle=nlsTextgtNo

bookmarksltportletAPItextgtltpgt

lt

else

gt

ltp class=wpsIndentMediumgt

lt

while (ehasMoreElements())

String name = (String)enextElement()

String value = (String)prefsgetAttribute(name)

gt

lta href=lt=valuegt target=_blankgtlt=namegtltagtltbr gt

lt

gt

ltpgt

The View JSP first call portletAPIinit 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

lt page contentType=texthtml import=javautil

comibmwpssampleswp5orgapachejetspeedportlet session=falsegt

lt taglib uri=WEB-INFtldportlettld prefix=portletAPI gt

ltjspuseBean id=addURI class=javalangString scope=request gt

ltjspuseBean id=cancelURI class=javalangString scope=request gt

ltportletAPIinitgt

lth4gtltportletAPItext key=available_bookmarks bundle=nlsTextgtAvailable

BookmarksltportletAPItextgtlth4gt

lttable class=wpsTablegt

lttr class=wpsTableRowgt

ltth class=portlet-table-headergtltportletAPItext key=name bundle=nlsTextgtltthgt

ltth class=portlet-table-headergtltportletAPItext key=url bundle=nlsTextgtltthgt

lttdgtlttdgt

lttrgt

lt

PortletData prefs = portletRequestgetData()

Enumeration e = prefsgetAttributeNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltportletAPItext key=no_bookmarks bundle=nlsTextgtNo

bookmarksltportletAPItextgtltpgt

lt

else

while (ehasMoreElements())

- 44 -

String name = (String)enextElement()

String value = (String)prefsgetAttribute(name)

gt

lttr class=wpsTableRowgt

lttdgt lt=namegt lttdgt

lttdgt lt=valuegt lttdgt

lttdgt lta href=ltportletAPIcreateURIgtltportletAPIURIAction

name=removeURIgtltportletAPIURIParameter name=remove

value=lt=namegtgtltportletAPIcreateURIgtgt

(ltportletAPItext key=delete bundle=nlsTextgt)ltagt

lttdgt

lttrgt

lt

gt

ltform action=lt=addURIgt method=POSTgt

lttr class=wpsTableRowgt

lttdgtltinput name=ltportletAPIencodeNamespace value=namegt type=text

class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=ltportletAPIencodeNamespace value=valuegt type=text

class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=ltportletAPIencodeNamespace value=addgt type=submit

value=ltportletAPItext key=add bundle=nlsTextgt class=portlet-form-buttongtlttdgt

lttrgt

ltformgt

lttablegt

- 45 -

ltform action=lt=cancelURIgt method=postgt

ltinput name=ltportletAPIencodeNamespace value=cancelgt type=submit

value=ltportletAPItext key=cancel bundle=nlsTextgt class=portlet-form-buttongt

ltformgt

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 ldquodeleterdquo button for which an URL with the action ldquoremoveURIrdquo 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 ldquocancelrdquo button from the request

64 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

lt page import=javaxportlet javautil session=falsegt

lt taglib uri=httpjavasuncomportlet prefix=portletAPI gt

lt taglib prefix=fmt uri=httpjavasuncomjstlfmt gt

ltportletAPIdefineObjects gt

ltfmtsetBundle basename=nlsTextgt

lt

ResourceBundle myText = ResourceBundlegetBundle(nlsText requestgetLocale())

gt

lth4gtltfmtmessage key=available_bookmarksgtlth4gt

lt

PortletPreferences prefs = renderRequestgetPreferences()

Enumeration e = prefsgetNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltfmtmessage key=no_bookmarksgtltpgt

- 46 -

lt

else

gt

ltpgt

lt

while (ehasMoreElements())

String name = (String)enextElement()

String value = prefsgetValue(namelt+myTextgetString(undefined)+gt)

gt

lta href=lt=valuegt target=_blankgtlt=namegtltagtltbr gt

lt

gt

ltpgt

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 fmtmessage 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

lt page import=javaxportlet javautil session=false gt

lt taglib uri=httpjavasuncomportlet prefix=portletAPI gt

lt taglib prefix=fmt uri=httpjavasuncomjstlfmt gt

ltjspuseBean id=addUrl scope=request class=javalangString gt

ltjspuseBean id=cancelUrl scope=request class=javalangString gt

- 47 -

ltportletAPIdefineObjectsgt

lt

ResourceBundle myText = ResourceBundlegetBundle(nlsText requestgetLocale())

gt

ltfmtsetBundle basename=nlsTextgt

lth4gtltfmtmessage key=available_bookmarksgtlth4gt

lttable class=wpsTablegt

lttr class=wpsTableRowgt

ltth class=wpsTableHeadgtltfmtmessage key=namegtltthgt

ltth class=wpsTableHeadgtltfmtmessage key=urlgtltthgt

lttdgtlttdgt

lttrgt

lt

PortletPreferences prefs = renderRequestgetPreferences()

Enumeration e = prefsgetNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltfmtmessage key=no_bookmarksgtltpgt

lt

else

while (ehasMoreElements())

String name = (String)enextElement()

String value = prefsgetValue(namelt+myTextgetString(undefined)+gt)

gt

lttr class=wpsTableRowgt

lttdgt lt=namegt lttdgt

lttdgt lt=valuegt lttdgt

- 48 -

lttdgt ltportletAPIactionURL var=removeUrlgt

ltportletAPIparam name=remove value=lt=namegtgt

ltportletAPIactionURLgt

lta href=lt=removeUrltoString()gtgt(ltfmtmessage key=deletegt)ltagt

lttdgt

lttrgt

lt

gt

ltform action=lt=addUrlgt method=POSTgt

lttr class=wpsTableRowgt

lttdgtltinput name=name type=text class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=value type=text class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=add type=submit value=ltfmtmessage key=addgt

class=portlet-form-buttongtlttdgt

lttrgt

ltformgt

lttablegt

ltform action=lt=cancelUrlgt method=postgt

ltinput name=cancel type=submit value=ltfmtmessage key=cancelgt class=portlet-

form-buttongt

ltformgt

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 14 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 -

- 51 -

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 (eg eventing) the IBM Portlet API still needs to be used Trademarks bull IBM and WebSphere are trademarks or registered trademarks of IBM Corporation in

the United States other countries or both bull 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 bull Other company product and service names may be trademarks or service marks of

others IBM copyright and trademark information httpwwwibmcomlegalcopytradephtml

  • Introduction
  • JSR 168 and the Java Community Process
  • Comparing concepts
    • Basic concepts
      • Portal
      • Portal page
      • Portlet
      • Portlet Container
        • Concepts that are the same
          • Portlet mode
          • Window state
          • Portlet life cycle and request processing
          • URL encoding
          • Include servletsJSPs
          • Portlet application packaging
          • Expiration-based caching
            • Concepts that differ
              • Portlet application entity
              • Portlet entity
              • Action and Render Request Response objects
              • Window concept
              • Portlet API does not extend servlet API
              • TAG libraries
                • Concepts new in the JSR 168
                  • Render parameter
                  • Extension mechanisms
                    • Custom window states
                    • Custom portlet modes
                    • Custom user info
                    • Request Response properties
                      • Web application session scope
                      • Reuse of the HttpSession listeners
                      • J2EE role support
                      • Resource bundles
                      • Multiple response content types
                      • Redirect in action
                      • Preference validator
                      • Portal context
                      • Localization support
                        • Concepts missing in the JSR 168
                          • Eventing
                          • Additional lifecycle events
                          • Property broker
                          • Portlet Menus
                          • Portlet Services
                          • Invalidation-based caching
                            • Alignment with WSRP
                              • Outlook for the next version of the JSR 168
                              • Guidelines for programming IBM Portlet API portlets
                                • Similar Functionality
                                  • Basic programming model
                                  • Portlet private session
                                  • User profile information
                                  • Persistent data
                                  • Portlet modes and window states
                                  • Expiration-based caching
                                    • Slightly different functionality
                                      • Sharing of data between portlets
                                      • Session listeners
                                        • New JSR 168 functionality
                                          • Navigational state (render parameters)
                                            • Pitfalls
                                              • Request response objects for action and render phase
                                              • Include search path
                                              • Form parameter encoding
                                              • Title setting
                                                  • Examples
                                                    • IBM Portlet API Portlet Code
                                                    • JSR 168 Portlet Code
                                                    • IBM Portlet API JSPs
                                                    • JSR 168 JSPs
                                                      • Summary
Page 20: Difference Bw Jsr168 and Ibm

341 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 (eg 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

342 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

3421 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

3422 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 322) 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

3423 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

3424 Request Response properties

Properties can be used by the portalportlet container to send vendor specific information to the portlet andor the portlet can send vendor specific information to the portalportlet-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

343 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 (eg between portlets or between a portlet and a servlet)

344 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 23 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

345 J2EE role support

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

346 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 -

347 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 PortletRequestgetResponseContentTypes 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 (eg ldquotextrdquo or ldquordquo) 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

348 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 (eg an accounting servlet) in response to an action

349 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

3410 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 vendorrsquos 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)

3411 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 xmllang attribute like the

- 22 -

servlet 24 deployment descriptor Thus the same tag with descriptions in different languages can be used (eg 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

35 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)

351 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

bull ActionEventThe action event maps to the action phase call in the JSR 168

bull MessageEventMessage 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)

bull PortletApplicationSettingsAttributeEventPortletSettingsAttributeEventThese are events that get fired when attributes for the application or of the portlet settings change

bull WindowEventThe portlet will register for window events to get notified if the portlet window is changed via the window decorations

352 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 -

bull PortletPageListener The page listeners provides the portlet with events for the beginning of the page before any markup is written for this page (eg to write JavaScript at the beginning of the page) and the end of the page after all markup is written

bull 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 23 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

bull EventPhaseListener The event phase listener notifies the portlet of the beginning and end of the eventaction phase

353 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

354 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 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

Figure 4

- 24 -

Figure 4 Portlet menu example

355 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

356 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 -

36 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 indicates portlet in what mode to operate for a given request

View edit help + custom modes

view edit help + custom modes

full alignment

Window State the state of the window in which the portlet output will be displayed

minimized normal maximized solo +

custom window states

minimized normal maximized +

custom window states

full alignment (ldquosolordquo is missing in the JSR but can be implemented as a custom state)

URL encoding to allow re-writing URLs created by the portlet

defines how to create URLs to allow re-writing of the URLs either on consumer or producer side

encapsulates URL creation via a Java object

full alignment (the implementation of the Java object can implement the WSRP URL rewriting rules)

Namespace encoding to avoid that several portlets on a page conflicting with each other

defines namespace prefixes for consumer and producer side namespacing

provides a Java method to namespace a String

full alignment (the JSR namespace method can implement the WSRP namespace behavior)

User ndash portlet interaction operations

performBlockingInteraction blocking action processing

getMarkup render the markup

action blocking action processing

render render the makup

full alignment (action invocations carried through performBlockingInteraction render carried through getMarkup)

View state that allows the current portlet fragment to be correctly displayed in sub-sequent render calls

navigational state render parameter full alignment (WSRP navigational state maps to JSR render parameters)

Storing transient state across request

session state concept implemented via a sessionID

utilizes the Http web application session

full alignment (the WSRP sessionID can be used to reference the JSR session)

Storing persistent state to personalize the rendering of the portlet

allows to have properties of arbitrary types

provides String-based preferences

full alignment (JSR String preferences can be mapped to WSRP properties)

Information about the portal calling the portlet

RegistrationData provide information of the consumer to the producer

PortalContext provide a Java interface to access information about the portal calling the portlet

full alignment (all data represented through the PortalContext to the JSR portlet are available in the RegistrationData)

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

Aggregated HTML WML VoiceXML

over HTTPMark-Up Fragments

Transferred via WSRP

Portal

WSRP Service

WSRP Service

WSRP Service

WSRP Consumer WSRP Producer

Use of WSRP Services in Portals

Portal sharing Portlets as WSRP Services

ServerPortalPortals

Huge numberof users Publishing Portal

WSRPWrapperPortalsPortalsPortal

Portlet

Portlet

Portlet

WSRP Consumer WSRP Producer

ProxyPortlet

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

bull 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

bull 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

bull 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

bull 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 CCPP standard allowing a portlet to query the client capabilities and adopting its markup accordingly (eg screen size browser) This API is likely to be included in the next version of the portlet API Also J2EE 14 was finalized during this time period J2EE 14 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 14

bull caching The first version of the JSR 168 API is limited to expiration-based caching (see section 327) 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

bull 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

51 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

511 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

bull portlets are components Portlets are components that implement a specific function Different functions should be distributed to different portlets

bull 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

bull 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

512 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 HttpServletRequestgetSession() call in the JSPs called via the IBM Portlet API needs to be replaced when moving to JSR 168 portlets by the RenderRequestgetPortletSession() 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 HttpServletRequestgetSession() will get the HttpSession and therefore need to access the portlet session via the RenderRequest

513 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

514 Persistent data

Portlets can store customization and personalization data persistently Customization data are related to the portlet and are valid for all users (eg 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 (eg 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

515 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

516 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

52 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

521 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 351 353) 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

522 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

53 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 -

531 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

bull no support of the back button in the browser bull current state of the portlet is not bookmarkable bull 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 bull 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

54 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

541 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 -

542 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

543 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

544 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 wersquoll 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

Figure 7After clicking on the Edit mode button the portlet renders the Edit view shown in

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

Figure 8

After we press the ldquoAddrdquo 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

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

bull use JSPs for rendering the output bull customize the portlet output taking user specific data into account bull 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

61 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 comibmwpssampleswp5

import javaio

import javautil

import orgapachejetspeedportlet

import orgapachejetspeedportletevent

public class IbmBookmark extends PortletAdapter implements ActionListener

public void init(PortletConfig portletConfig) throws UnavailableException

superinit(portletConfig)

- 36 -

public void doView(PortletRequest request PortletResponse response)

throws PortletException IOException

String jspName = thisgetPortletConfig()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 = responsecreateReturnURI()

addURIaddAction(add)

requestsetAttribute(addURI addURItoString())

PortletURI cancelURI = responsecreateReturnURI()

requestsetAttribute(cancelURI cancelURItoString())

String jspName = thisgetPortletConfig()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 ldquocancelrdquo and ldquoaddrdquo URLs are created inside the portlet and attached to the request before including the Edit JSP Both URLs are from type ldquoReturnURIrdquo 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 = eventgetRequest()

String action = eventgetActionString()

PortletLog log = getPortletLog()

if ( action=null )

try

if (actionequals(removeURI))

String removeName = requestgetParameter(remove)

PortletData portData = requestgetData()

portDataremoveAttribute(removeName)

portDatastore()

if (actionequals(add))

PortletData portData = requestgetData()

String name = requestgetParameter(name)

String value = requestgetParameter(value)

portDatasetAttribute(name value)

portDatastore()

catch ( AccessDeniedException ade )

logerror(AccessDeniedException occured when adding or deleting a bookmark)

catch ( IOException ioe )

logerror(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 ldquoaddrdquo or ldquodeleterdquo 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 ldquoaddrdquo or ldquoremoveURIrdquo If the user has clicked on the ldquoremoverdquo button the corresponding link is removed from the portlet data whereas if ldquoaddrdquo was clicked the data entered by the user is added to the portlet data

62 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 comibmwpssamplesjsr

import javaio

import javaxportlet

public class Bookmark extends GenericPortlet

public void init(PortletConfig config) throws PortletException

superinit(config)

public void doView(RenderRequest request RenderResponse response)

throws PortletException IOException

responsesetContentType(texthtml)

String jspName = getPortletConfig()getInitParameter(jspView)

PortletRequestDispatcher rd = getPortletContext()getRequestDispatcher(jspName)

rdinclude(requestresponse)

- 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

responsesetContentType(texthtml)

PortletURL addUrl = responsecreateActionURL()

addUrlsetPortletMode(PortletModeVIEW)

addUrlsetParameter(addadd)

requestsetAttribute(addUrladdUrltoString())

PortletURL cancelUrl = responsecreateRenderURL()

cancelUrlsetPortletMode(PortletModeVIEW)

requestsetAttribute(cancelUrlcancelUrltoString())

String jspName = getPortletConfig()getInitParameter(jspEdit)

PortletRequestDispatcher rd = getPortletContext()getRequestDispatcher(jspName)

rdinclude(requestresponse)

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 ldquoaddrdquo button URL an action URL is created as we need to store the user input of the add form persistently For the ldquocancelrdquo 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 = requestgetParameter(remove)

if (removeName = null)

PortletPreferences prefs = requestgetPreferences()

prefsreset(removeName)

prefsstore()

String add = requestgetParameter(add)

if (add = null)

PortletPreferences prefs = requestgetPreferences()

String name = requestgetParameter(name)

String value = requestgetParameter(value)

prefssetValue(name value)

prefsstore()

catch ( IOException ioe )

getPortletContextlog(An IO error occured when trying to remove a bookmark)

catch ( PortletException pe )

getPortletContextlog(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

bull 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

bull 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

bull Persistent portlet data The JSR 168 persistent data PortletPreferences have an API similar to the JDK 14 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

bull 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

63 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

lt page contentType=texthtml import=javautil comibmwpssampleswp5

orgapachejetspeedportlet session=falsegt

lt taglib uri=WEB-INFtldportlettld prefix=portletAPI gt

- 42 -

ltportletAPIinitgt

ltp class=wpsPortletHeadgtltportletAPItext key=available_bookmarks

bundle=nlsTextgtAvailable BookmarksltportletAPItextgtltpgt

lt

PortletData prefs = portletRequestgetData()

Enumeration e = prefsgetAttributeNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltportletAPItext key=no_bookmarks bundle=nlsTextgtNo

bookmarksltportletAPItextgtltpgt

lt

else

gt

ltp class=wpsIndentMediumgt

lt

while (ehasMoreElements())

String name = (String)enextElement()

String value = (String)prefsgetAttribute(name)

gt

lta href=lt=valuegt target=_blankgtlt=namegtltagtltbr gt

lt

gt

ltpgt

The View JSP first call portletAPIinit 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

lt page contentType=texthtml import=javautil

comibmwpssampleswp5orgapachejetspeedportlet session=falsegt

lt taglib uri=WEB-INFtldportlettld prefix=portletAPI gt

ltjspuseBean id=addURI class=javalangString scope=request gt

ltjspuseBean id=cancelURI class=javalangString scope=request gt

ltportletAPIinitgt

lth4gtltportletAPItext key=available_bookmarks bundle=nlsTextgtAvailable

BookmarksltportletAPItextgtlth4gt

lttable class=wpsTablegt

lttr class=wpsTableRowgt

ltth class=portlet-table-headergtltportletAPItext key=name bundle=nlsTextgtltthgt

ltth class=portlet-table-headergtltportletAPItext key=url bundle=nlsTextgtltthgt

lttdgtlttdgt

lttrgt

lt

PortletData prefs = portletRequestgetData()

Enumeration e = prefsgetAttributeNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltportletAPItext key=no_bookmarks bundle=nlsTextgtNo

bookmarksltportletAPItextgtltpgt

lt

else

while (ehasMoreElements())

- 44 -

String name = (String)enextElement()

String value = (String)prefsgetAttribute(name)

gt

lttr class=wpsTableRowgt

lttdgt lt=namegt lttdgt

lttdgt lt=valuegt lttdgt

lttdgt lta href=ltportletAPIcreateURIgtltportletAPIURIAction

name=removeURIgtltportletAPIURIParameter name=remove

value=lt=namegtgtltportletAPIcreateURIgtgt

(ltportletAPItext key=delete bundle=nlsTextgt)ltagt

lttdgt

lttrgt

lt

gt

ltform action=lt=addURIgt method=POSTgt

lttr class=wpsTableRowgt

lttdgtltinput name=ltportletAPIencodeNamespace value=namegt type=text

class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=ltportletAPIencodeNamespace value=valuegt type=text

class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=ltportletAPIencodeNamespace value=addgt type=submit

value=ltportletAPItext key=add bundle=nlsTextgt class=portlet-form-buttongtlttdgt

lttrgt

ltformgt

lttablegt

- 45 -

ltform action=lt=cancelURIgt method=postgt

ltinput name=ltportletAPIencodeNamespace value=cancelgt type=submit

value=ltportletAPItext key=cancel bundle=nlsTextgt class=portlet-form-buttongt

ltformgt

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 ldquodeleterdquo button for which an URL with the action ldquoremoveURIrdquo 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 ldquocancelrdquo button from the request

64 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

lt page import=javaxportlet javautil session=falsegt

lt taglib uri=httpjavasuncomportlet prefix=portletAPI gt

lt taglib prefix=fmt uri=httpjavasuncomjstlfmt gt

ltportletAPIdefineObjects gt

ltfmtsetBundle basename=nlsTextgt

lt

ResourceBundle myText = ResourceBundlegetBundle(nlsText requestgetLocale())

gt

lth4gtltfmtmessage key=available_bookmarksgtlth4gt

lt

PortletPreferences prefs = renderRequestgetPreferences()

Enumeration e = prefsgetNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltfmtmessage key=no_bookmarksgtltpgt

- 46 -

lt

else

gt

ltpgt

lt

while (ehasMoreElements())

String name = (String)enextElement()

String value = prefsgetValue(namelt+myTextgetString(undefined)+gt)

gt

lta href=lt=valuegt target=_blankgtlt=namegtltagtltbr gt

lt

gt

ltpgt

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 fmtmessage 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

lt page import=javaxportlet javautil session=false gt

lt taglib uri=httpjavasuncomportlet prefix=portletAPI gt

lt taglib prefix=fmt uri=httpjavasuncomjstlfmt gt

ltjspuseBean id=addUrl scope=request class=javalangString gt

ltjspuseBean id=cancelUrl scope=request class=javalangString gt

- 47 -

ltportletAPIdefineObjectsgt

lt

ResourceBundle myText = ResourceBundlegetBundle(nlsText requestgetLocale())

gt

ltfmtsetBundle basename=nlsTextgt

lth4gtltfmtmessage key=available_bookmarksgtlth4gt

lttable class=wpsTablegt

lttr class=wpsTableRowgt

ltth class=wpsTableHeadgtltfmtmessage key=namegtltthgt

ltth class=wpsTableHeadgtltfmtmessage key=urlgtltthgt

lttdgtlttdgt

lttrgt

lt

PortletPreferences prefs = renderRequestgetPreferences()

Enumeration e = prefsgetNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltfmtmessage key=no_bookmarksgtltpgt

lt

else

while (ehasMoreElements())

String name = (String)enextElement()

String value = prefsgetValue(namelt+myTextgetString(undefined)+gt)

gt

lttr class=wpsTableRowgt

lttdgt lt=namegt lttdgt

lttdgt lt=valuegt lttdgt

- 48 -

lttdgt ltportletAPIactionURL var=removeUrlgt

ltportletAPIparam name=remove value=lt=namegtgt

ltportletAPIactionURLgt

lta href=lt=removeUrltoString()gtgt(ltfmtmessage key=deletegt)ltagt

lttdgt

lttrgt

lt

gt

ltform action=lt=addUrlgt method=POSTgt

lttr class=wpsTableRowgt

lttdgtltinput name=name type=text class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=value type=text class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=add type=submit value=ltfmtmessage key=addgt

class=portlet-form-buttongtlttdgt

lttrgt

ltformgt

lttablegt

ltform action=lt=cancelUrlgt method=postgt

ltinput name=cancel type=submit value=ltfmtmessage key=cancelgt class=portlet-

form-buttongt

ltformgt

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 14 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 -

- 51 -

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 (eg eventing) the IBM Portlet API still needs to be used Trademarks bull IBM and WebSphere are trademarks or registered trademarks of IBM Corporation in

the United States other countries or both bull 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 bull Other company product and service names may be trademarks or service marks of

others IBM copyright and trademark information httpwwwibmcomlegalcopytradephtml

  • Introduction
  • JSR 168 and the Java Community Process
  • Comparing concepts
    • Basic concepts
      • Portal
      • Portal page
      • Portlet
      • Portlet Container
        • Concepts that are the same
          • Portlet mode
          • Window state
          • Portlet life cycle and request processing
          • URL encoding
          • Include servletsJSPs
          • Portlet application packaging
          • Expiration-based caching
            • Concepts that differ
              • Portlet application entity
              • Portlet entity
              • Action and Render Request Response objects
              • Window concept
              • Portlet API does not extend servlet API
              • TAG libraries
                • Concepts new in the JSR 168
                  • Render parameter
                  • Extension mechanisms
                    • Custom window states
                    • Custom portlet modes
                    • Custom user info
                    • Request Response properties
                      • Web application session scope
                      • Reuse of the HttpSession listeners
                      • J2EE role support
                      • Resource bundles
                      • Multiple response content types
                      • Redirect in action
                      • Preference validator
                      • Portal context
                      • Localization support
                        • Concepts missing in the JSR 168
                          • Eventing
                          • Additional lifecycle events
                          • Property broker
                          • Portlet Menus
                          • Portlet Services
                          • Invalidation-based caching
                            • Alignment with WSRP
                              • Outlook for the next version of the JSR 168
                              • Guidelines for programming IBM Portlet API portlets
                                • Similar Functionality
                                  • Basic programming model
                                  • Portlet private session
                                  • User profile information
                                  • Persistent data
                                  • Portlet modes and window states
                                  • Expiration-based caching
                                    • Slightly different functionality
                                      • Sharing of data between portlets
                                      • Session listeners
                                        • New JSR 168 functionality
                                          • Navigational state (render parameters)
                                            • Pitfalls
                                              • Request response objects for action and render phase
                                              • Include search path
                                              • Form parameter encoding
                                              • Title setting
                                                  • Examples
                                                    • IBM Portlet API Portlet Code
                                                    • JSR 168 Portlet Code
                                                    • IBM Portlet API JSPs
                                                    • JSR 168 JSPs
                                                      • Summary
Page 21: Difference Bw Jsr168 and Ibm

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

3424 Request Response properties

Properties can be used by the portalportlet container to send vendor specific information to the portlet andor the portlet can send vendor specific information to the portalportlet-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

343 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 (eg between portlets or between a portlet and a servlet)

344 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 23 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

345 J2EE role support

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

346 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 -

347 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 PortletRequestgetResponseContentTypes 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 (eg ldquotextrdquo or ldquordquo) 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

348 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 (eg an accounting servlet) in response to an action

349 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

3410 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 vendorrsquos 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)

3411 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 xmllang attribute like the

- 22 -

servlet 24 deployment descriptor Thus the same tag with descriptions in different languages can be used (eg 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

35 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)

351 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

bull ActionEventThe action event maps to the action phase call in the JSR 168

bull MessageEventMessage 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)

bull PortletApplicationSettingsAttributeEventPortletSettingsAttributeEventThese are events that get fired when attributes for the application or of the portlet settings change

bull WindowEventThe portlet will register for window events to get notified if the portlet window is changed via the window decorations

352 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 -

bull PortletPageListener The page listeners provides the portlet with events for the beginning of the page before any markup is written for this page (eg to write JavaScript at the beginning of the page) and the end of the page after all markup is written

bull 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 23 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

bull EventPhaseListener The event phase listener notifies the portlet of the beginning and end of the eventaction phase

353 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

354 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 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

Figure 4

- 24 -

Figure 4 Portlet menu example

355 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

356 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 -

36 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 indicates portlet in what mode to operate for a given request

View edit help + custom modes

view edit help + custom modes

full alignment

Window State the state of the window in which the portlet output will be displayed

minimized normal maximized solo +

custom window states

minimized normal maximized +

custom window states

full alignment (ldquosolordquo is missing in the JSR but can be implemented as a custom state)

URL encoding to allow re-writing URLs created by the portlet

defines how to create URLs to allow re-writing of the URLs either on consumer or producer side

encapsulates URL creation via a Java object

full alignment (the implementation of the Java object can implement the WSRP URL rewriting rules)

Namespace encoding to avoid that several portlets on a page conflicting with each other

defines namespace prefixes for consumer and producer side namespacing

provides a Java method to namespace a String

full alignment (the JSR namespace method can implement the WSRP namespace behavior)

User ndash portlet interaction operations

performBlockingInteraction blocking action processing

getMarkup render the markup

action blocking action processing

render render the makup

full alignment (action invocations carried through performBlockingInteraction render carried through getMarkup)

View state that allows the current portlet fragment to be correctly displayed in sub-sequent render calls

navigational state render parameter full alignment (WSRP navigational state maps to JSR render parameters)

Storing transient state across request

session state concept implemented via a sessionID

utilizes the Http web application session

full alignment (the WSRP sessionID can be used to reference the JSR session)

Storing persistent state to personalize the rendering of the portlet

allows to have properties of arbitrary types

provides String-based preferences

full alignment (JSR String preferences can be mapped to WSRP properties)

Information about the portal calling the portlet

RegistrationData provide information of the consumer to the producer

PortalContext provide a Java interface to access information about the portal calling the portlet

full alignment (all data represented through the PortalContext to the JSR portlet are available in the RegistrationData)

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

Aggregated HTML WML VoiceXML

over HTTPMark-Up Fragments

Transferred via WSRP

Portal

WSRP Service

WSRP Service

WSRP Service

WSRP Consumer WSRP Producer

Use of WSRP Services in Portals

Portal sharing Portlets as WSRP Services

ServerPortalPortals

Huge numberof users Publishing Portal

WSRPWrapperPortalsPortalsPortal

Portlet

Portlet

Portlet

WSRP Consumer WSRP Producer

ProxyPortlet

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

bull 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

bull 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

bull 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

bull 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 CCPP standard allowing a portlet to query the client capabilities and adopting its markup accordingly (eg screen size browser) This API is likely to be included in the next version of the portlet API Also J2EE 14 was finalized during this time period J2EE 14 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 14

bull caching The first version of the JSR 168 API is limited to expiration-based caching (see section 327) 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

bull 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

51 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

511 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

bull portlets are components Portlets are components that implement a specific function Different functions should be distributed to different portlets

bull 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

bull 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

512 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 HttpServletRequestgetSession() call in the JSPs called via the IBM Portlet API needs to be replaced when moving to JSR 168 portlets by the RenderRequestgetPortletSession() 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 HttpServletRequestgetSession() will get the HttpSession and therefore need to access the portlet session via the RenderRequest

513 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

514 Persistent data

Portlets can store customization and personalization data persistently Customization data are related to the portlet and are valid for all users (eg 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 (eg 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

515 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

516 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

52 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

521 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 351 353) 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

522 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

53 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 -

531 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

bull no support of the back button in the browser bull current state of the portlet is not bookmarkable bull 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 bull 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

54 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

541 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 -

542 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

543 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

544 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 wersquoll 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

Figure 7After clicking on the Edit mode button the portlet renders the Edit view shown in

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

Figure 8

After we press the ldquoAddrdquo 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

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

bull use JSPs for rendering the output bull customize the portlet output taking user specific data into account bull 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

61 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 comibmwpssampleswp5

import javaio

import javautil

import orgapachejetspeedportlet

import orgapachejetspeedportletevent

public class IbmBookmark extends PortletAdapter implements ActionListener

public void init(PortletConfig portletConfig) throws UnavailableException

superinit(portletConfig)

- 36 -

public void doView(PortletRequest request PortletResponse response)

throws PortletException IOException

String jspName = thisgetPortletConfig()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 = responsecreateReturnURI()

addURIaddAction(add)

requestsetAttribute(addURI addURItoString())

PortletURI cancelURI = responsecreateReturnURI()

requestsetAttribute(cancelURI cancelURItoString())

String jspName = thisgetPortletConfig()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 ldquocancelrdquo and ldquoaddrdquo URLs are created inside the portlet and attached to the request before including the Edit JSP Both URLs are from type ldquoReturnURIrdquo 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 = eventgetRequest()

String action = eventgetActionString()

PortletLog log = getPortletLog()

if ( action=null )

try

if (actionequals(removeURI))

String removeName = requestgetParameter(remove)

PortletData portData = requestgetData()

portDataremoveAttribute(removeName)

portDatastore()

if (actionequals(add))

PortletData portData = requestgetData()

String name = requestgetParameter(name)

String value = requestgetParameter(value)

portDatasetAttribute(name value)

portDatastore()

catch ( AccessDeniedException ade )

logerror(AccessDeniedException occured when adding or deleting a bookmark)

catch ( IOException ioe )

logerror(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 ldquoaddrdquo or ldquodeleterdquo 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 ldquoaddrdquo or ldquoremoveURIrdquo If the user has clicked on the ldquoremoverdquo button the corresponding link is removed from the portlet data whereas if ldquoaddrdquo was clicked the data entered by the user is added to the portlet data

62 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 comibmwpssamplesjsr

import javaio

import javaxportlet

public class Bookmark extends GenericPortlet

public void init(PortletConfig config) throws PortletException

superinit(config)

public void doView(RenderRequest request RenderResponse response)

throws PortletException IOException

responsesetContentType(texthtml)

String jspName = getPortletConfig()getInitParameter(jspView)

PortletRequestDispatcher rd = getPortletContext()getRequestDispatcher(jspName)

rdinclude(requestresponse)

- 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

responsesetContentType(texthtml)

PortletURL addUrl = responsecreateActionURL()

addUrlsetPortletMode(PortletModeVIEW)

addUrlsetParameter(addadd)

requestsetAttribute(addUrladdUrltoString())

PortletURL cancelUrl = responsecreateRenderURL()

cancelUrlsetPortletMode(PortletModeVIEW)

requestsetAttribute(cancelUrlcancelUrltoString())

String jspName = getPortletConfig()getInitParameter(jspEdit)

PortletRequestDispatcher rd = getPortletContext()getRequestDispatcher(jspName)

rdinclude(requestresponse)

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 ldquoaddrdquo button URL an action URL is created as we need to store the user input of the add form persistently For the ldquocancelrdquo 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 = requestgetParameter(remove)

if (removeName = null)

PortletPreferences prefs = requestgetPreferences()

prefsreset(removeName)

prefsstore()

String add = requestgetParameter(add)

if (add = null)

PortletPreferences prefs = requestgetPreferences()

String name = requestgetParameter(name)

String value = requestgetParameter(value)

prefssetValue(name value)

prefsstore()

catch ( IOException ioe )

getPortletContextlog(An IO error occured when trying to remove a bookmark)

catch ( PortletException pe )

getPortletContextlog(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

bull 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

bull 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

bull Persistent portlet data The JSR 168 persistent data PortletPreferences have an API similar to the JDK 14 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

bull 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

63 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

lt page contentType=texthtml import=javautil comibmwpssampleswp5

orgapachejetspeedportlet session=falsegt

lt taglib uri=WEB-INFtldportlettld prefix=portletAPI gt

- 42 -

ltportletAPIinitgt

ltp class=wpsPortletHeadgtltportletAPItext key=available_bookmarks

bundle=nlsTextgtAvailable BookmarksltportletAPItextgtltpgt

lt

PortletData prefs = portletRequestgetData()

Enumeration e = prefsgetAttributeNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltportletAPItext key=no_bookmarks bundle=nlsTextgtNo

bookmarksltportletAPItextgtltpgt

lt

else

gt

ltp class=wpsIndentMediumgt

lt

while (ehasMoreElements())

String name = (String)enextElement()

String value = (String)prefsgetAttribute(name)

gt

lta href=lt=valuegt target=_blankgtlt=namegtltagtltbr gt

lt

gt

ltpgt

The View JSP first call portletAPIinit 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

lt page contentType=texthtml import=javautil

comibmwpssampleswp5orgapachejetspeedportlet session=falsegt

lt taglib uri=WEB-INFtldportlettld prefix=portletAPI gt

ltjspuseBean id=addURI class=javalangString scope=request gt

ltjspuseBean id=cancelURI class=javalangString scope=request gt

ltportletAPIinitgt

lth4gtltportletAPItext key=available_bookmarks bundle=nlsTextgtAvailable

BookmarksltportletAPItextgtlth4gt

lttable class=wpsTablegt

lttr class=wpsTableRowgt

ltth class=portlet-table-headergtltportletAPItext key=name bundle=nlsTextgtltthgt

ltth class=portlet-table-headergtltportletAPItext key=url bundle=nlsTextgtltthgt

lttdgtlttdgt

lttrgt

lt

PortletData prefs = portletRequestgetData()

Enumeration e = prefsgetAttributeNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltportletAPItext key=no_bookmarks bundle=nlsTextgtNo

bookmarksltportletAPItextgtltpgt

lt

else

while (ehasMoreElements())

- 44 -

String name = (String)enextElement()

String value = (String)prefsgetAttribute(name)

gt

lttr class=wpsTableRowgt

lttdgt lt=namegt lttdgt

lttdgt lt=valuegt lttdgt

lttdgt lta href=ltportletAPIcreateURIgtltportletAPIURIAction

name=removeURIgtltportletAPIURIParameter name=remove

value=lt=namegtgtltportletAPIcreateURIgtgt

(ltportletAPItext key=delete bundle=nlsTextgt)ltagt

lttdgt

lttrgt

lt

gt

ltform action=lt=addURIgt method=POSTgt

lttr class=wpsTableRowgt

lttdgtltinput name=ltportletAPIencodeNamespace value=namegt type=text

class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=ltportletAPIencodeNamespace value=valuegt type=text

class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=ltportletAPIencodeNamespace value=addgt type=submit

value=ltportletAPItext key=add bundle=nlsTextgt class=portlet-form-buttongtlttdgt

lttrgt

ltformgt

lttablegt

- 45 -

ltform action=lt=cancelURIgt method=postgt

ltinput name=ltportletAPIencodeNamespace value=cancelgt type=submit

value=ltportletAPItext key=cancel bundle=nlsTextgt class=portlet-form-buttongt

ltformgt

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 ldquodeleterdquo button for which an URL with the action ldquoremoveURIrdquo 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 ldquocancelrdquo button from the request

64 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

lt page import=javaxportlet javautil session=falsegt

lt taglib uri=httpjavasuncomportlet prefix=portletAPI gt

lt taglib prefix=fmt uri=httpjavasuncomjstlfmt gt

ltportletAPIdefineObjects gt

ltfmtsetBundle basename=nlsTextgt

lt

ResourceBundle myText = ResourceBundlegetBundle(nlsText requestgetLocale())

gt

lth4gtltfmtmessage key=available_bookmarksgtlth4gt

lt

PortletPreferences prefs = renderRequestgetPreferences()

Enumeration e = prefsgetNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltfmtmessage key=no_bookmarksgtltpgt

- 46 -

lt

else

gt

ltpgt

lt

while (ehasMoreElements())

String name = (String)enextElement()

String value = prefsgetValue(namelt+myTextgetString(undefined)+gt)

gt

lta href=lt=valuegt target=_blankgtlt=namegtltagtltbr gt

lt

gt

ltpgt

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 fmtmessage 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

lt page import=javaxportlet javautil session=false gt

lt taglib uri=httpjavasuncomportlet prefix=portletAPI gt

lt taglib prefix=fmt uri=httpjavasuncomjstlfmt gt

ltjspuseBean id=addUrl scope=request class=javalangString gt

ltjspuseBean id=cancelUrl scope=request class=javalangString gt

- 47 -

ltportletAPIdefineObjectsgt

lt

ResourceBundle myText = ResourceBundlegetBundle(nlsText requestgetLocale())

gt

ltfmtsetBundle basename=nlsTextgt

lth4gtltfmtmessage key=available_bookmarksgtlth4gt

lttable class=wpsTablegt

lttr class=wpsTableRowgt

ltth class=wpsTableHeadgtltfmtmessage key=namegtltthgt

ltth class=wpsTableHeadgtltfmtmessage key=urlgtltthgt

lttdgtlttdgt

lttrgt

lt

PortletPreferences prefs = renderRequestgetPreferences()

Enumeration e = prefsgetNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltfmtmessage key=no_bookmarksgtltpgt

lt

else

while (ehasMoreElements())

String name = (String)enextElement()

String value = prefsgetValue(namelt+myTextgetString(undefined)+gt)

gt

lttr class=wpsTableRowgt

lttdgt lt=namegt lttdgt

lttdgt lt=valuegt lttdgt

- 48 -

lttdgt ltportletAPIactionURL var=removeUrlgt

ltportletAPIparam name=remove value=lt=namegtgt

ltportletAPIactionURLgt

lta href=lt=removeUrltoString()gtgt(ltfmtmessage key=deletegt)ltagt

lttdgt

lttrgt

lt

gt

ltform action=lt=addUrlgt method=POSTgt

lttr class=wpsTableRowgt

lttdgtltinput name=name type=text class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=value type=text class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=add type=submit value=ltfmtmessage key=addgt

class=portlet-form-buttongtlttdgt

lttrgt

ltformgt

lttablegt

ltform action=lt=cancelUrlgt method=postgt

ltinput name=cancel type=submit value=ltfmtmessage key=cancelgt class=portlet-

form-buttongt

ltformgt

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 14 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 -

- 51 -

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 (eg eventing) the IBM Portlet API still needs to be used Trademarks bull IBM and WebSphere are trademarks or registered trademarks of IBM Corporation in

the United States other countries or both bull 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 bull Other company product and service names may be trademarks or service marks of

others IBM copyright and trademark information httpwwwibmcomlegalcopytradephtml

  • Introduction
  • JSR 168 and the Java Community Process
  • Comparing concepts
    • Basic concepts
      • Portal
      • Portal page
      • Portlet
      • Portlet Container
        • Concepts that are the same
          • Portlet mode
          • Window state
          • Portlet life cycle and request processing
          • URL encoding
          • Include servletsJSPs
          • Portlet application packaging
          • Expiration-based caching
            • Concepts that differ
              • Portlet application entity
              • Portlet entity
              • Action and Render Request Response objects
              • Window concept
              • Portlet API does not extend servlet API
              • TAG libraries
                • Concepts new in the JSR 168
                  • Render parameter
                  • Extension mechanisms
                    • Custom window states
                    • Custom portlet modes
                    • Custom user info
                    • Request Response properties
                      • Web application session scope
                      • Reuse of the HttpSession listeners
                      • J2EE role support
                      • Resource bundles
                      • Multiple response content types
                      • Redirect in action
                      • Preference validator
                      • Portal context
                      • Localization support
                        • Concepts missing in the JSR 168
                          • Eventing
                          • Additional lifecycle events
                          • Property broker
                          • Portlet Menus
                          • Portlet Services
                          • Invalidation-based caching
                            • Alignment with WSRP
                              • Outlook for the next version of the JSR 168
                              • Guidelines for programming IBM Portlet API portlets
                                • Similar Functionality
                                  • Basic programming model
                                  • Portlet private session
                                  • User profile information
                                  • Persistent data
                                  • Portlet modes and window states
                                  • Expiration-based caching
                                    • Slightly different functionality
                                      • Sharing of data between portlets
                                      • Session listeners
                                        • New JSR 168 functionality
                                          • Navigational state (render parameters)
                                            • Pitfalls
                                              • Request response objects for action and render phase
                                              • Include search path
                                              • Form parameter encoding
                                              • Title setting
                                                  • Examples
                                                    • IBM Portlet API Portlet Code
                                                    • JSR 168 Portlet Code
                                                    • IBM Portlet API JSPs
                                                    • JSR 168 JSPs
                                                      • Summary
Page 22: Difference Bw Jsr168 and Ibm

347 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 PortletRequestgetResponseContentTypes 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 (eg ldquotextrdquo or ldquordquo) 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

348 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 (eg an accounting servlet) in response to an action

349 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

3410 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 vendorrsquos 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)

3411 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 xmllang attribute like the

- 22 -

servlet 24 deployment descriptor Thus the same tag with descriptions in different languages can be used (eg 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

35 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)

351 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

bull ActionEventThe action event maps to the action phase call in the JSR 168

bull MessageEventMessage 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)

bull PortletApplicationSettingsAttributeEventPortletSettingsAttributeEventThese are events that get fired when attributes for the application or of the portlet settings change

bull WindowEventThe portlet will register for window events to get notified if the portlet window is changed via the window decorations

352 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 -

bull PortletPageListener The page listeners provides the portlet with events for the beginning of the page before any markup is written for this page (eg to write JavaScript at the beginning of the page) and the end of the page after all markup is written

bull 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 23 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

bull EventPhaseListener The event phase listener notifies the portlet of the beginning and end of the eventaction phase

353 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

354 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 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

Figure 4

- 24 -

Figure 4 Portlet menu example

355 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

356 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 -

36 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 indicates portlet in what mode to operate for a given request

View edit help + custom modes

view edit help + custom modes

full alignment

Window State the state of the window in which the portlet output will be displayed

minimized normal maximized solo +

custom window states

minimized normal maximized +

custom window states

full alignment (ldquosolordquo is missing in the JSR but can be implemented as a custom state)

URL encoding to allow re-writing URLs created by the portlet

defines how to create URLs to allow re-writing of the URLs either on consumer or producer side

encapsulates URL creation via a Java object

full alignment (the implementation of the Java object can implement the WSRP URL rewriting rules)

Namespace encoding to avoid that several portlets on a page conflicting with each other

defines namespace prefixes for consumer and producer side namespacing

provides a Java method to namespace a String

full alignment (the JSR namespace method can implement the WSRP namespace behavior)

User ndash portlet interaction operations

performBlockingInteraction blocking action processing

getMarkup render the markup

action blocking action processing

render render the makup

full alignment (action invocations carried through performBlockingInteraction render carried through getMarkup)

View state that allows the current portlet fragment to be correctly displayed in sub-sequent render calls

navigational state render parameter full alignment (WSRP navigational state maps to JSR render parameters)

Storing transient state across request

session state concept implemented via a sessionID

utilizes the Http web application session

full alignment (the WSRP sessionID can be used to reference the JSR session)

Storing persistent state to personalize the rendering of the portlet

allows to have properties of arbitrary types

provides String-based preferences

full alignment (JSR String preferences can be mapped to WSRP properties)

Information about the portal calling the portlet

RegistrationData provide information of the consumer to the producer

PortalContext provide a Java interface to access information about the portal calling the portlet

full alignment (all data represented through the PortalContext to the JSR portlet are available in the RegistrationData)

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

Aggregated HTML WML VoiceXML

over HTTPMark-Up Fragments

Transferred via WSRP

Portal

WSRP Service

WSRP Service

WSRP Service

WSRP Consumer WSRP Producer

Use of WSRP Services in Portals

Portal sharing Portlets as WSRP Services

ServerPortalPortals

Huge numberof users Publishing Portal

WSRPWrapperPortalsPortalsPortal

Portlet

Portlet

Portlet

WSRP Consumer WSRP Producer

ProxyPortlet

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

bull 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

bull 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

bull 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

bull 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 CCPP standard allowing a portlet to query the client capabilities and adopting its markup accordingly (eg screen size browser) This API is likely to be included in the next version of the portlet API Also J2EE 14 was finalized during this time period J2EE 14 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 14

bull caching The first version of the JSR 168 API is limited to expiration-based caching (see section 327) 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

bull 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

51 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

511 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

bull portlets are components Portlets are components that implement a specific function Different functions should be distributed to different portlets

bull 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

bull 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

512 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 HttpServletRequestgetSession() call in the JSPs called via the IBM Portlet API needs to be replaced when moving to JSR 168 portlets by the RenderRequestgetPortletSession() 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 HttpServletRequestgetSession() will get the HttpSession and therefore need to access the portlet session via the RenderRequest

513 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

514 Persistent data

Portlets can store customization and personalization data persistently Customization data are related to the portlet and are valid for all users (eg 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 (eg 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

515 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

516 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

52 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

521 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 351 353) 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

522 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

53 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 -

531 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

bull no support of the back button in the browser bull current state of the portlet is not bookmarkable bull 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 bull 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

54 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

541 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 -

542 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

543 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

544 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 wersquoll 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

Figure 7After clicking on the Edit mode button the portlet renders the Edit view shown in

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

Figure 8

After we press the ldquoAddrdquo 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

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

bull use JSPs for rendering the output bull customize the portlet output taking user specific data into account bull 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

61 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 comibmwpssampleswp5

import javaio

import javautil

import orgapachejetspeedportlet

import orgapachejetspeedportletevent

public class IbmBookmark extends PortletAdapter implements ActionListener

public void init(PortletConfig portletConfig) throws UnavailableException

superinit(portletConfig)

- 36 -

public void doView(PortletRequest request PortletResponse response)

throws PortletException IOException

String jspName = thisgetPortletConfig()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 = responsecreateReturnURI()

addURIaddAction(add)

requestsetAttribute(addURI addURItoString())

PortletURI cancelURI = responsecreateReturnURI()

requestsetAttribute(cancelURI cancelURItoString())

String jspName = thisgetPortletConfig()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 ldquocancelrdquo and ldquoaddrdquo URLs are created inside the portlet and attached to the request before including the Edit JSP Both URLs are from type ldquoReturnURIrdquo 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 = eventgetRequest()

String action = eventgetActionString()

PortletLog log = getPortletLog()

if ( action=null )

try

if (actionequals(removeURI))

String removeName = requestgetParameter(remove)

PortletData portData = requestgetData()

portDataremoveAttribute(removeName)

portDatastore()

if (actionequals(add))

PortletData portData = requestgetData()

String name = requestgetParameter(name)

String value = requestgetParameter(value)

portDatasetAttribute(name value)

portDatastore()

catch ( AccessDeniedException ade )

logerror(AccessDeniedException occured when adding or deleting a bookmark)

catch ( IOException ioe )

logerror(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 ldquoaddrdquo or ldquodeleterdquo 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 ldquoaddrdquo or ldquoremoveURIrdquo If the user has clicked on the ldquoremoverdquo button the corresponding link is removed from the portlet data whereas if ldquoaddrdquo was clicked the data entered by the user is added to the portlet data

62 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 comibmwpssamplesjsr

import javaio

import javaxportlet

public class Bookmark extends GenericPortlet

public void init(PortletConfig config) throws PortletException

superinit(config)

public void doView(RenderRequest request RenderResponse response)

throws PortletException IOException

responsesetContentType(texthtml)

String jspName = getPortletConfig()getInitParameter(jspView)

PortletRequestDispatcher rd = getPortletContext()getRequestDispatcher(jspName)

rdinclude(requestresponse)

- 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

responsesetContentType(texthtml)

PortletURL addUrl = responsecreateActionURL()

addUrlsetPortletMode(PortletModeVIEW)

addUrlsetParameter(addadd)

requestsetAttribute(addUrladdUrltoString())

PortletURL cancelUrl = responsecreateRenderURL()

cancelUrlsetPortletMode(PortletModeVIEW)

requestsetAttribute(cancelUrlcancelUrltoString())

String jspName = getPortletConfig()getInitParameter(jspEdit)

PortletRequestDispatcher rd = getPortletContext()getRequestDispatcher(jspName)

rdinclude(requestresponse)

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 ldquoaddrdquo button URL an action URL is created as we need to store the user input of the add form persistently For the ldquocancelrdquo 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 = requestgetParameter(remove)

if (removeName = null)

PortletPreferences prefs = requestgetPreferences()

prefsreset(removeName)

prefsstore()

String add = requestgetParameter(add)

if (add = null)

PortletPreferences prefs = requestgetPreferences()

String name = requestgetParameter(name)

String value = requestgetParameter(value)

prefssetValue(name value)

prefsstore()

catch ( IOException ioe )

getPortletContextlog(An IO error occured when trying to remove a bookmark)

catch ( PortletException pe )

getPortletContextlog(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

bull 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

bull 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

bull Persistent portlet data The JSR 168 persistent data PortletPreferences have an API similar to the JDK 14 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

bull 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

63 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

lt page contentType=texthtml import=javautil comibmwpssampleswp5

orgapachejetspeedportlet session=falsegt

lt taglib uri=WEB-INFtldportlettld prefix=portletAPI gt

- 42 -

ltportletAPIinitgt

ltp class=wpsPortletHeadgtltportletAPItext key=available_bookmarks

bundle=nlsTextgtAvailable BookmarksltportletAPItextgtltpgt

lt

PortletData prefs = portletRequestgetData()

Enumeration e = prefsgetAttributeNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltportletAPItext key=no_bookmarks bundle=nlsTextgtNo

bookmarksltportletAPItextgtltpgt

lt

else

gt

ltp class=wpsIndentMediumgt

lt

while (ehasMoreElements())

String name = (String)enextElement()

String value = (String)prefsgetAttribute(name)

gt

lta href=lt=valuegt target=_blankgtlt=namegtltagtltbr gt

lt

gt

ltpgt

The View JSP first call portletAPIinit 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

lt page contentType=texthtml import=javautil

comibmwpssampleswp5orgapachejetspeedportlet session=falsegt

lt taglib uri=WEB-INFtldportlettld prefix=portletAPI gt

ltjspuseBean id=addURI class=javalangString scope=request gt

ltjspuseBean id=cancelURI class=javalangString scope=request gt

ltportletAPIinitgt

lth4gtltportletAPItext key=available_bookmarks bundle=nlsTextgtAvailable

BookmarksltportletAPItextgtlth4gt

lttable class=wpsTablegt

lttr class=wpsTableRowgt

ltth class=portlet-table-headergtltportletAPItext key=name bundle=nlsTextgtltthgt

ltth class=portlet-table-headergtltportletAPItext key=url bundle=nlsTextgtltthgt

lttdgtlttdgt

lttrgt

lt

PortletData prefs = portletRequestgetData()

Enumeration e = prefsgetAttributeNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltportletAPItext key=no_bookmarks bundle=nlsTextgtNo

bookmarksltportletAPItextgtltpgt

lt

else

while (ehasMoreElements())

- 44 -

String name = (String)enextElement()

String value = (String)prefsgetAttribute(name)

gt

lttr class=wpsTableRowgt

lttdgt lt=namegt lttdgt

lttdgt lt=valuegt lttdgt

lttdgt lta href=ltportletAPIcreateURIgtltportletAPIURIAction

name=removeURIgtltportletAPIURIParameter name=remove

value=lt=namegtgtltportletAPIcreateURIgtgt

(ltportletAPItext key=delete bundle=nlsTextgt)ltagt

lttdgt

lttrgt

lt

gt

ltform action=lt=addURIgt method=POSTgt

lttr class=wpsTableRowgt

lttdgtltinput name=ltportletAPIencodeNamespace value=namegt type=text

class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=ltportletAPIencodeNamespace value=valuegt type=text

class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=ltportletAPIencodeNamespace value=addgt type=submit

value=ltportletAPItext key=add bundle=nlsTextgt class=portlet-form-buttongtlttdgt

lttrgt

ltformgt

lttablegt

- 45 -

ltform action=lt=cancelURIgt method=postgt

ltinput name=ltportletAPIencodeNamespace value=cancelgt type=submit

value=ltportletAPItext key=cancel bundle=nlsTextgt class=portlet-form-buttongt

ltformgt

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 ldquodeleterdquo button for which an URL with the action ldquoremoveURIrdquo 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 ldquocancelrdquo button from the request

64 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

lt page import=javaxportlet javautil session=falsegt

lt taglib uri=httpjavasuncomportlet prefix=portletAPI gt

lt taglib prefix=fmt uri=httpjavasuncomjstlfmt gt

ltportletAPIdefineObjects gt

ltfmtsetBundle basename=nlsTextgt

lt

ResourceBundle myText = ResourceBundlegetBundle(nlsText requestgetLocale())

gt

lth4gtltfmtmessage key=available_bookmarksgtlth4gt

lt

PortletPreferences prefs = renderRequestgetPreferences()

Enumeration e = prefsgetNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltfmtmessage key=no_bookmarksgtltpgt

- 46 -

lt

else

gt

ltpgt

lt

while (ehasMoreElements())

String name = (String)enextElement()

String value = prefsgetValue(namelt+myTextgetString(undefined)+gt)

gt

lta href=lt=valuegt target=_blankgtlt=namegtltagtltbr gt

lt

gt

ltpgt

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 fmtmessage 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

lt page import=javaxportlet javautil session=false gt

lt taglib uri=httpjavasuncomportlet prefix=portletAPI gt

lt taglib prefix=fmt uri=httpjavasuncomjstlfmt gt

ltjspuseBean id=addUrl scope=request class=javalangString gt

ltjspuseBean id=cancelUrl scope=request class=javalangString gt

- 47 -

ltportletAPIdefineObjectsgt

lt

ResourceBundle myText = ResourceBundlegetBundle(nlsText requestgetLocale())

gt

ltfmtsetBundle basename=nlsTextgt

lth4gtltfmtmessage key=available_bookmarksgtlth4gt

lttable class=wpsTablegt

lttr class=wpsTableRowgt

ltth class=wpsTableHeadgtltfmtmessage key=namegtltthgt

ltth class=wpsTableHeadgtltfmtmessage key=urlgtltthgt

lttdgtlttdgt

lttrgt

lt

PortletPreferences prefs = renderRequestgetPreferences()

Enumeration e = prefsgetNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltfmtmessage key=no_bookmarksgtltpgt

lt

else

while (ehasMoreElements())

String name = (String)enextElement()

String value = prefsgetValue(namelt+myTextgetString(undefined)+gt)

gt

lttr class=wpsTableRowgt

lttdgt lt=namegt lttdgt

lttdgt lt=valuegt lttdgt

- 48 -

lttdgt ltportletAPIactionURL var=removeUrlgt

ltportletAPIparam name=remove value=lt=namegtgt

ltportletAPIactionURLgt

lta href=lt=removeUrltoString()gtgt(ltfmtmessage key=deletegt)ltagt

lttdgt

lttrgt

lt

gt

ltform action=lt=addUrlgt method=POSTgt

lttr class=wpsTableRowgt

lttdgtltinput name=name type=text class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=value type=text class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=add type=submit value=ltfmtmessage key=addgt

class=portlet-form-buttongtlttdgt

lttrgt

ltformgt

lttablegt

ltform action=lt=cancelUrlgt method=postgt

ltinput name=cancel type=submit value=ltfmtmessage key=cancelgt class=portlet-

form-buttongt

ltformgt

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 14 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 -

- 51 -

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 (eg eventing) the IBM Portlet API still needs to be used Trademarks bull IBM and WebSphere are trademarks or registered trademarks of IBM Corporation in

the United States other countries or both bull 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 bull Other company product and service names may be trademarks or service marks of

others IBM copyright and trademark information httpwwwibmcomlegalcopytradephtml

  • Introduction
  • JSR 168 and the Java Community Process
  • Comparing concepts
    • Basic concepts
      • Portal
      • Portal page
      • Portlet
      • Portlet Container
        • Concepts that are the same
          • Portlet mode
          • Window state
          • Portlet life cycle and request processing
          • URL encoding
          • Include servletsJSPs
          • Portlet application packaging
          • Expiration-based caching
            • Concepts that differ
              • Portlet application entity
              • Portlet entity
              • Action and Render Request Response objects
              • Window concept
              • Portlet API does not extend servlet API
              • TAG libraries
                • Concepts new in the JSR 168
                  • Render parameter
                  • Extension mechanisms
                    • Custom window states
                    • Custom portlet modes
                    • Custom user info
                    • Request Response properties
                      • Web application session scope
                      • Reuse of the HttpSession listeners
                      • J2EE role support
                      • Resource bundles
                      • Multiple response content types
                      • Redirect in action
                      • Preference validator
                      • Portal context
                      • Localization support
                        • Concepts missing in the JSR 168
                          • Eventing
                          • Additional lifecycle events
                          • Property broker
                          • Portlet Menus
                          • Portlet Services
                          • Invalidation-based caching
                            • Alignment with WSRP
                              • Outlook for the next version of the JSR 168
                              • Guidelines for programming IBM Portlet API portlets
                                • Similar Functionality
                                  • Basic programming model
                                  • Portlet private session
                                  • User profile information
                                  • Persistent data
                                  • Portlet modes and window states
                                  • Expiration-based caching
                                    • Slightly different functionality
                                      • Sharing of data between portlets
                                      • Session listeners
                                        • New JSR 168 functionality
                                          • Navigational state (render parameters)
                                            • Pitfalls
                                              • Request response objects for action and render phase
                                              • Include search path
                                              • Form parameter encoding
                                              • Title setting
                                                  • Examples
                                                    • IBM Portlet API Portlet Code
                                                    • JSR 168 Portlet Code
                                                    • IBM Portlet API JSPs
                                                    • JSR 168 JSPs
                                                      • Summary
Page 23: Difference Bw Jsr168 and Ibm

servlet 24 deployment descriptor Thus the same tag with descriptions in different languages can be used (eg 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

35 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)

351 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

bull ActionEventThe action event maps to the action phase call in the JSR 168

bull MessageEventMessage 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)

bull PortletApplicationSettingsAttributeEventPortletSettingsAttributeEventThese are events that get fired when attributes for the application or of the portlet settings change

bull WindowEventThe portlet will register for window events to get notified if the portlet window is changed via the window decorations

352 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 -

bull PortletPageListener The page listeners provides the portlet with events for the beginning of the page before any markup is written for this page (eg to write JavaScript at the beginning of the page) and the end of the page after all markup is written

bull 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 23 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

bull EventPhaseListener The event phase listener notifies the portlet of the beginning and end of the eventaction phase

353 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

354 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 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

Figure 4

- 24 -

Figure 4 Portlet menu example

355 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

356 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 -

36 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 indicates portlet in what mode to operate for a given request

View edit help + custom modes

view edit help + custom modes

full alignment

Window State the state of the window in which the portlet output will be displayed

minimized normal maximized solo +

custom window states

minimized normal maximized +

custom window states

full alignment (ldquosolordquo is missing in the JSR but can be implemented as a custom state)

URL encoding to allow re-writing URLs created by the portlet

defines how to create URLs to allow re-writing of the URLs either on consumer or producer side

encapsulates URL creation via a Java object

full alignment (the implementation of the Java object can implement the WSRP URL rewriting rules)

Namespace encoding to avoid that several portlets on a page conflicting with each other

defines namespace prefixes for consumer and producer side namespacing

provides a Java method to namespace a String

full alignment (the JSR namespace method can implement the WSRP namespace behavior)

User ndash portlet interaction operations

performBlockingInteraction blocking action processing

getMarkup render the markup

action blocking action processing

render render the makup

full alignment (action invocations carried through performBlockingInteraction render carried through getMarkup)

View state that allows the current portlet fragment to be correctly displayed in sub-sequent render calls

navigational state render parameter full alignment (WSRP navigational state maps to JSR render parameters)

Storing transient state across request

session state concept implemented via a sessionID

utilizes the Http web application session

full alignment (the WSRP sessionID can be used to reference the JSR session)

Storing persistent state to personalize the rendering of the portlet

allows to have properties of arbitrary types

provides String-based preferences

full alignment (JSR String preferences can be mapped to WSRP properties)

Information about the portal calling the portlet

RegistrationData provide information of the consumer to the producer

PortalContext provide a Java interface to access information about the portal calling the portlet

full alignment (all data represented through the PortalContext to the JSR portlet are available in the RegistrationData)

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

Aggregated HTML WML VoiceXML

over HTTPMark-Up Fragments

Transferred via WSRP

Portal

WSRP Service

WSRP Service

WSRP Service

WSRP Consumer WSRP Producer

Use of WSRP Services in Portals

Portal sharing Portlets as WSRP Services

ServerPortalPortals

Huge numberof users Publishing Portal

WSRPWrapperPortalsPortalsPortal

Portlet

Portlet

Portlet

WSRP Consumer WSRP Producer

ProxyPortlet

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

bull 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

bull 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

bull 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

bull 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 CCPP standard allowing a portlet to query the client capabilities and adopting its markup accordingly (eg screen size browser) This API is likely to be included in the next version of the portlet API Also J2EE 14 was finalized during this time period J2EE 14 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 14

bull caching The first version of the JSR 168 API is limited to expiration-based caching (see section 327) 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

bull 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

51 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

511 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

bull portlets are components Portlets are components that implement a specific function Different functions should be distributed to different portlets

bull 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

bull 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

512 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 HttpServletRequestgetSession() call in the JSPs called via the IBM Portlet API needs to be replaced when moving to JSR 168 portlets by the RenderRequestgetPortletSession() 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 HttpServletRequestgetSession() will get the HttpSession and therefore need to access the portlet session via the RenderRequest

513 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

514 Persistent data

Portlets can store customization and personalization data persistently Customization data are related to the portlet and are valid for all users (eg 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 (eg 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

515 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

516 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

52 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

521 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 351 353) 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

522 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

53 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 -

531 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

bull no support of the back button in the browser bull current state of the portlet is not bookmarkable bull 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 bull 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

54 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

541 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 -

542 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

543 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

544 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 wersquoll 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

Figure 7After clicking on the Edit mode button the portlet renders the Edit view shown in

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

Figure 8

After we press the ldquoAddrdquo 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

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

bull use JSPs for rendering the output bull customize the portlet output taking user specific data into account bull 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

61 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 comibmwpssampleswp5

import javaio

import javautil

import orgapachejetspeedportlet

import orgapachejetspeedportletevent

public class IbmBookmark extends PortletAdapter implements ActionListener

public void init(PortletConfig portletConfig) throws UnavailableException

superinit(portletConfig)

- 36 -

public void doView(PortletRequest request PortletResponse response)

throws PortletException IOException

String jspName = thisgetPortletConfig()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 = responsecreateReturnURI()

addURIaddAction(add)

requestsetAttribute(addURI addURItoString())

PortletURI cancelURI = responsecreateReturnURI()

requestsetAttribute(cancelURI cancelURItoString())

String jspName = thisgetPortletConfig()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 ldquocancelrdquo and ldquoaddrdquo URLs are created inside the portlet and attached to the request before including the Edit JSP Both URLs are from type ldquoReturnURIrdquo 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 = eventgetRequest()

String action = eventgetActionString()

PortletLog log = getPortletLog()

if ( action=null )

try

if (actionequals(removeURI))

String removeName = requestgetParameter(remove)

PortletData portData = requestgetData()

portDataremoveAttribute(removeName)

portDatastore()

if (actionequals(add))

PortletData portData = requestgetData()

String name = requestgetParameter(name)

String value = requestgetParameter(value)

portDatasetAttribute(name value)

portDatastore()

catch ( AccessDeniedException ade )

logerror(AccessDeniedException occured when adding or deleting a bookmark)

catch ( IOException ioe )

logerror(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 ldquoaddrdquo or ldquodeleterdquo 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 ldquoaddrdquo or ldquoremoveURIrdquo If the user has clicked on the ldquoremoverdquo button the corresponding link is removed from the portlet data whereas if ldquoaddrdquo was clicked the data entered by the user is added to the portlet data

62 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 comibmwpssamplesjsr

import javaio

import javaxportlet

public class Bookmark extends GenericPortlet

public void init(PortletConfig config) throws PortletException

superinit(config)

public void doView(RenderRequest request RenderResponse response)

throws PortletException IOException

responsesetContentType(texthtml)

String jspName = getPortletConfig()getInitParameter(jspView)

PortletRequestDispatcher rd = getPortletContext()getRequestDispatcher(jspName)

rdinclude(requestresponse)

- 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

responsesetContentType(texthtml)

PortletURL addUrl = responsecreateActionURL()

addUrlsetPortletMode(PortletModeVIEW)

addUrlsetParameter(addadd)

requestsetAttribute(addUrladdUrltoString())

PortletURL cancelUrl = responsecreateRenderURL()

cancelUrlsetPortletMode(PortletModeVIEW)

requestsetAttribute(cancelUrlcancelUrltoString())

String jspName = getPortletConfig()getInitParameter(jspEdit)

PortletRequestDispatcher rd = getPortletContext()getRequestDispatcher(jspName)

rdinclude(requestresponse)

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 ldquoaddrdquo button URL an action URL is created as we need to store the user input of the add form persistently For the ldquocancelrdquo 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 = requestgetParameter(remove)

if (removeName = null)

PortletPreferences prefs = requestgetPreferences()

prefsreset(removeName)

prefsstore()

String add = requestgetParameter(add)

if (add = null)

PortletPreferences prefs = requestgetPreferences()

String name = requestgetParameter(name)

String value = requestgetParameter(value)

prefssetValue(name value)

prefsstore()

catch ( IOException ioe )

getPortletContextlog(An IO error occured when trying to remove a bookmark)

catch ( PortletException pe )

getPortletContextlog(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

bull 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

bull 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

bull Persistent portlet data The JSR 168 persistent data PortletPreferences have an API similar to the JDK 14 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

bull 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

63 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

lt page contentType=texthtml import=javautil comibmwpssampleswp5

orgapachejetspeedportlet session=falsegt

lt taglib uri=WEB-INFtldportlettld prefix=portletAPI gt

- 42 -

ltportletAPIinitgt

ltp class=wpsPortletHeadgtltportletAPItext key=available_bookmarks

bundle=nlsTextgtAvailable BookmarksltportletAPItextgtltpgt

lt

PortletData prefs = portletRequestgetData()

Enumeration e = prefsgetAttributeNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltportletAPItext key=no_bookmarks bundle=nlsTextgtNo

bookmarksltportletAPItextgtltpgt

lt

else

gt

ltp class=wpsIndentMediumgt

lt

while (ehasMoreElements())

String name = (String)enextElement()

String value = (String)prefsgetAttribute(name)

gt

lta href=lt=valuegt target=_blankgtlt=namegtltagtltbr gt

lt

gt

ltpgt

The View JSP first call portletAPIinit 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

lt page contentType=texthtml import=javautil

comibmwpssampleswp5orgapachejetspeedportlet session=falsegt

lt taglib uri=WEB-INFtldportlettld prefix=portletAPI gt

ltjspuseBean id=addURI class=javalangString scope=request gt

ltjspuseBean id=cancelURI class=javalangString scope=request gt

ltportletAPIinitgt

lth4gtltportletAPItext key=available_bookmarks bundle=nlsTextgtAvailable

BookmarksltportletAPItextgtlth4gt

lttable class=wpsTablegt

lttr class=wpsTableRowgt

ltth class=portlet-table-headergtltportletAPItext key=name bundle=nlsTextgtltthgt

ltth class=portlet-table-headergtltportletAPItext key=url bundle=nlsTextgtltthgt

lttdgtlttdgt

lttrgt

lt

PortletData prefs = portletRequestgetData()

Enumeration e = prefsgetAttributeNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltportletAPItext key=no_bookmarks bundle=nlsTextgtNo

bookmarksltportletAPItextgtltpgt

lt

else

while (ehasMoreElements())

- 44 -

String name = (String)enextElement()

String value = (String)prefsgetAttribute(name)

gt

lttr class=wpsTableRowgt

lttdgt lt=namegt lttdgt

lttdgt lt=valuegt lttdgt

lttdgt lta href=ltportletAPIcreateURIgtltportletAPIURIAction

name=removeURIgtltportletAPIURIParameter name=remove

value=lt=namegtgtltportletAPIcreateURIgtgt

(ltportletAPItext key=delete bundle=nlsTextgt)ltagt

lttdgt

lttrgt

lt

gt

ltform action=lt=addURIgt method=POSTgt

lttr class=wpsTableRowgt

lttdgtltinput name=ltportletAPIencodeNamespace value=namegt type=text

class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=ltportletAPIencodeNamespace value=valuegt type=text

class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=ltportletAPIencodeNamespace value=addgt type=submit

value=ltportletAPItext key=add bundle=nlsTextgt class=portlet-form-buttongtlttdgt

lttrgt

ltformgt

lttablegt

- 45 -

ltform action=lt=cancelURIgt method=postgt

ltinput name=ltportletAPIencodeNamespace value=cancelgt type=submit

value=ltportletAPItext key=cancel bundle=nlsTextgt class=portlet-form-buttongt

ltformgt

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 ldquodeleterdquo button for which an URL with the action ldquoremoveURIrdquo 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 ldquocancelrdquo button from the request

64 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

lt page import=javaxportlet javautil session=falsegt

lt taglib uri=httpjavasuncomportlet prefix=portletAPI gt

lt taglib prefix=fmt uri=httpjavasuncomjstlfmt gt

ltportletAPIdefineObjects gt

ltfmtsetBundle basename=nlsTextgt

lt

ResourceBundle myText = ResourceBundlegetBundle(nlsText requestgetLocale())

gt

lth4gtltfmtmessage key=available_bookmarksgtlth4gt

lt

PortletPreferences prefs = renderRequestgetPreferences()

Enumeration e = prefsgetNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltfmtmessage key=no_bookmarksgtltpgt

- 46 -

lt

else

gt

ltpgt

lt

while (ehasMoreElements())

String name = (String)enextElement()

String value = prefsgetValue(namelt+myTextgetString(undefined)+gt)

gt

lta href=lt=valuegt target=_blankgtlt=namegtltagtltbr gt

lt

gt

ltpgt

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 fmtmessage 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

lt page import=javaxportlet javautil session=false gt

lt taglib uri=httpjavasuncomportlet prefix=portletAPI gt

lt taglib prefix=fmt uri=httpjavasuncomjstlfmt gt

ltjspuseBean id=addUrl scope=request class=javalangString gt

ltjspuseBean id=cancelUrl scope=request class=javalangString gt

- 47 -

ltportletAPIdefineObjectsgt

lt

ResourceBundle myText = ResourceBundlegetBundle(nlsText requestgetLocale())

gt

ltfmtsetBundle basename=nlsTextgt

lth4gtltfmtmessage key=available_bookmarksgtlth4gt

lttable class=wpsTablegt

lttr class=wpsTableRowgt

ltth class=wpsTableHeadgtltfmtmessage key=namegtltthgt

ltth class=wpsTableHeadgtltfmtmessage key=urlgtltthgt

lttdgtlttdgt

lttrgt

lt

PortletPreferences prefs = renderRequestgetPreferences()

Enumeration e = prefsgetNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltfmtmessage key=no_bookmarksgtltpgt

lt

else

while (ehasMoreElements())

String name = (String)enextElement()

String value = prefsgetValue(namelt+myTextgetString(undefined)+gt)

gt

lttr class=wpsTableRowgt

lttdgt lt=namegt lttdgt

lttdgt lt=valuegt lttdgt

- 48 -

lttdgt ltportletAPIactionURL var=removeUrlgt

ltportletAPIparam name=remove value=lt=namegtgt

ltportletAPIactionURLgt

lta href=lt=removeUrltoString()gtgt(ltfmtmessage key=deletegt)ltagt

lttdgt

lttrgt

lt

gt

ltform action=lt=addUrlgt method=POSTgt

lttr class=wpsTableRowgt

lttdgtltinput name=name type=text class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=value type=text class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=add type=submit value=ltfmtmessage key=addgt

class=portlet-form-buttongtlttdgt

lttrgt

ltformgt

lttablegt

ltform action=lt=cancelUrlgt method=postgt

ltinput name=cancel type=submit value=ltfmtmessage key=cancelgt class=portlet-

form-buttongt

ltformgt

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 14 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 -

- 51 -

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 (eg eventing) the IBM Portlet API still needs to be used Trademarks bull IBM and WebSphere are trademarks or registered trademarks of IBM Corporation in

the United States other countries or both bull 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 bull Other company product and service names may be trademarks or service marks of

others IBM copyright and trademark information httpwwwibmcomlegalcopytradephtml

  • Introduction
  • JSR 168 and the Java Community Process
  • Comparing concepts
    • Basic concepts
      • Portal
      • Portal page
      • Portlet
      • Portlet Container
        • Concepts that are the same
          • Portlet mode
          • Window state
          • Portlet life cycle and request processing
          • URL encoding
          • Include servletsJSPs
          • Portlet application packaging
          • Expiration-based caching
            • Concepts that differ
              • Portlet application entity
              • Portlet entity
              • Action and Render Request Response objects
              • Window concept
              • Portlet API does not extend servlet API
              • TAG libraries
                • Concepts new in the JSR 168
                  • Render parameter
                  • Extension mechanisms
                    • Custom window states
                    • Custom portlet modes
                    • Custom user info
                    • Request Response properties
                      • Web application session scope
                      • Reuse of the HttpSession listeners
                      • J2EE role support
                      • Resource bundles
                      • Multiple response content types
                      • Redirect in action
                      • Preference validator
                      • Portal context
                      • Localization support
                        • Concepts missing in the JSR 168
                          • Eventing
                          • Additional lifecycle events
                          • Property broker
                          • Portlet Menus
                          • Portlet Services
                          • Invalidation-based caching
                            • Alignment with WSRP
                              • Outlook for the next version of the JSR 168
                              • Guidelines for programming IBM Portlet API portlets
                                • Similar Functionality
                                  • Basic programming model
                                  • Portlet private session
                                  • User profile information
                                  • Persistent data
                                  • Portlet modes and window states
                                  • Expiration-based caching
                                    • Slightly different functionality
                                      • Sharing of data between portlets
                                      • Session listeners
                                        • New JSR 168 functionality
                                          • Navigational state (render parameters)
                                            • Pitfalls
                                              • Request response objects for action and render phase
                                              • Include search path
                                              • Form parameter encoding
                                              • Title setting
                                                  • Examples
                                                    • IBM Portlet API Portlet Code
                                                    • JSR 168 Portlet Code
                                                    • IBM Portlet API JSPs
                                                    • JSR 168 JSPs
                                                      • Summary
Page 24: Difference Bw Jsr168 and Ibm

bull PortletPageListener The page listeners provides the portlet with events for the beginning of the page before any markup is written for this page (eg to write JavaScript at the beginning of the page) and the end of the page after all markup is written

bull 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 23 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

bull EventPhaseListener The event phase listener notifies the portlet of the beginning and end of the eventaction phase

353 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

354 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 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

Figure 4

- 24 -

Figure 4 Portlet menu example

355 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

356 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 -

36 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 indicates portlet in what mode to operate for a given request

View edit help + custom modes

view edit help + custom modes

full alignment

Window State the state of the window in which the portlet output will be displayed

minimized normal maximized solo +

custom window states

minimized normal maximized +

custom window states

full alignment (ldquosolordquo is missing in the JSR but can be implemented as a custom state)

URL encoding to allow re-writing URLs created by the portlet

defines how to create URLs to allow re-writing of the URLs either on consumer or producer side

encapsulates URL creation via a Java object

full alignment (the implementation of the Java object can implement the WSRP URL rewriting rules)

Namespace encoding to avoid that several portlets on a page conflicting with each other

defines namespace prefixes for consumer and producer side namespacing

provides a Java method to namespace a String

full alignment (the JSR namespace method can implement the WSRP namespace behavior)

User ndash portlet interaction operations

performBlockingInteraction blocking action processing

getMarkup render the markup

action blocking action processing

render render the makup

full alignment (action invocations carried through performBlockingInteraction render carried through getMarkup)

View state that allows the current portlet fragment to be correctly displayed in sub-sequent render calls

navigational state render parameter full alignment (WSRP navigational state maps to JSR render parameters)

Storing transient state across request

session state concept implemented via a sessionID

utilizes the Http web application session

full alignment (the WSRP sessionID can be used to reference the JSR session)

Storing persistent state to personalize the rendering of the portlet

allows to have properties of arbitrary types

provides String-based preferences

full alignment (JSR String preferences can be mapped to WSRP properties)

Information about the portal calling the portlet

RegistrationData provide information of the consumer to the producer

PortalContext provide a Java interface to access information about the portal calling the portlet

full alignment (all data represented through the PortalContext to the JSR portlet are available in the RegistrationData)

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

Aggregated HTML WML VoiceXML

over HTTPMark-Up Fragments

Transferred via WSRP

Portal

WSRP Service

WSRP Service

WSRP Service

WSRP Consumer WSRP Producer

Use of WSRP Services in Portals

Portal sharing Portlets as WSRP Services

ServerPortalPortals

Huge numberof users Publishing Portal

WSRPWrapperPortalsPortalsPortal

Portlet

Portlet

Portlet

WSRP Consumer WSRP Producer

ProxyPortlet

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

bull 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

bull 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

bull 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

bull 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 CCPP standard allowing a portlet to query the client capabilities and adopting its markup accordingly (eg screen size browser) This API is likely to be included in the next version of the portlet API Also J2EE 14 was finalized during this time period J2EE 14 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 14

bull caching The first version of the JSR 168 API is limited to expiration-based caching (see section 327) 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

bull 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

51 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

511 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

bull portlets are components Portlets are components that implement a specific function Different functions should be distributed to different portlets

bull 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

bull 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

512 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 HttpServletRequestgetSession() call in the JSPs called via the IBM Portlet API needs to be replaced when moving to JSR 168 portlets by the RenderRequestgetPortletSession() 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 HttpServletRequestgetSession() will get the HttpSession and therefore need to access the portlet session via the RenderRequest

513 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

514 Persistent data

Portlets can store customization and personalization data persistently Customization data are related to the portlet and are valid for all users (eg 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 (eg 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

515 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

516 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

52 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

521 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 351 353) 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

522 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

53 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 -

531 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

bull no support of the back button in the browser bull current state of the portlet is not bookmarkable bull 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 bull 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

54 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

541 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 -

542 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

543 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

544 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 wersquoll 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

Figure 7After clicking on the Edit mode button the portlet renders the Edit view shown in

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

Figure 8

After we press the ldquoAddrdquo 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

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

bull use JSPs for rendering the output bull customize the portlet output taking user specific data into account bull 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

61 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 comibmwpssampleswp5

import javaio

import javautil

import orgapachejetspeedportlet

import orgapachejetspeedportletevent

public class IbmBookmark extends PortletAdapter implements ActionListener

public void init(PortletConfig portletConfig) throws UnavailableException

superinit(portletConfig)

- 36 -

public void doView(PortletRequest request PortletResponse response)

throws PortletException IOException

String jspName = thisgetPortletConfig()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 = responsecreateReturnURI()

addURIaddAction(add)

requestsetAttribute(addURI addURItoString())

PortletURI cancelURI = responsecreateReturnURI()

requestsetAttribute(cancelURI cancelURItoString())

String jspName = thisgetPortletConfig()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 ldquocancelrdquo and ldquoaddrdquo URLs are created inside the portlet and attached to the request before including the Edit JSP Both URLs are from type ldquoReturnURIrdquo 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 = eventgetRequest()

String action = eventgetActionString()

PortletLog log = getPortletLog()

if ( action=null )

try

if (actionequals(removeURI))

String removeName = requestgetParameter(remove)

PortletData portData = requestgetData()

portDataremoveAttribute(removeName)

portDatastore()

if (actionequals(add))

PortletData portData = requestgetData()

String name = requestgetParameter(name)

String value = requestgetParameter(value)

portDatasetAttribute(name value)

portDatastore()

catch ( AccessDeniedException ade )

logerror(AccessDeniedException occured when adding or deleting a bookmark)

catch ( IOException ioe )

logerror(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 ldquoaddrdquo or ldquodeleterdquo 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 ldquoaddrdquo or ldquoremoveURIrdquo If the user has clicked on the ldquoremoverdquo button the corresponding link is removed from the portlet data whereas if ldquoaddrdquo was clicked the data entered by the user is added to the portlet data

62 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 comibmwpssamplesjsr

import javaio

import javaxportlet

public class Bookmark extends GenericPortlet

public void init(PortletConfig config) throws PortletException

superinit(config)

public void doView(RenderRequest request RenderResponse response)

throws PortletException IOException

responsesetContentType(texthtml)

String jspName = getPortletConfig()getInitParameter(jspView)

PortletRequestDispatcher rd = getPortletContext()getRequestDispatcher(jspName)

rdinclude(requestresponse)

- 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

responsesetContentType(texthtml)

PortletURL addUrl = responsecreateActionURL()

addUrlsetPortletMode(PortletModeVIEW)

addUrlsetParameter(addadd)

requestsetAttribute(addUrladdUrltoString())

PortletURL cancelUrl = responsecreateRenderURL()

cancelUrlsetPortletMode(PortletModeVIEW)

requestsetAttribute(cancelUrlcancelUrltoString())

String jspName = getPortletConfig()getInitParameter(jspEdit)

PortletRequestDispatcher rd = getPortletContext()getRequestDispatcher(jspName)

rdinclude(requestresponse)

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 ldquoaddrdquo button URL an action URL is created as we need to store the user input of the add form persistently For the ldquocancelrdquo 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 = requestgetParameter(remove)

if (removeName = null)

PortletPreferences prefs = requestgetPreferences()

prefsreset(removeName)

prefsstore()

String add = requestgetParameter(add)

if (add = null)

PortletPreferences prefs = requestgetPreferences()

String name = requestgetParameter(name)

String value = requestgetParameter(value)

prefssetValue(name value)

prefsstore()

catch ( IOException ioe )

getPortletContextlog(An IO error occured when trying to remove a bookmark)

catch ( PortletException pe )

getPortletContextlog(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

bull 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

bull 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

bull Persistent portlet data The JSR 168 persistent data PortletPreferences have an API similar to the JDK 14 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

bull 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

63 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

lt page contentType=texthtml import=javautil comibmwpssampleswp5

orgapachejetspeedportlet session=falsegt

lt taglib uri=WEB-INFtldportlettld prefix=portletAPI gt

- 42 -

ltportletAPIinitgt

ltp class=wpsPortletHeadgtltportletAPItext key=available_bookmarks

bundle=nlsTextgtAvailable BookmarksltportletAPItextgtltpgt

lt

PortletData prefs = portletRequestgetData()

Enumeration e = prefsgetAttributeNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltportletAPItext key=no_bookmarks bundle=nlsTextgtNo

bookmarksltportletAPItextgtltpgt

lt

else

gt

ltp class=wpsIndentMediumgt

lt

while (ehasMoreElements())

String name = (String)enextElement()

String value = (String)prefsgetAttribute(name)

gt

lta href=lt=valuegt target=_blankgtlt=namegtltagtltbr gt

lt

gt

ltpgt

The View JSP first call portletAPIinit 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

lt page contentType=texthtml import=javautil

comibmwpssampleswp5orgapachejetspeedportlet session=falsegt

lt taglib uri=WEB-INFtldportlettld prefix=portletAPI gt

ltjspuseBean id=addURI class=javalangString scope=request gt

ltjspuseBean id=cancelURI class=javalangString scope=request gt

ltportletAPIinitgt

lth4gtltportletAPItext key=available_bookmarks bundle=nlsTextgtAvailable

BookmarksltportletAPItextgtlth4gt

lttable class=wpsTablegt

lttr class=wpsTableRowgt

ltth class=portlet-table-headergtltportletAPItext key=name bundle=nlsTextgtltthgt

ltth class=portlet-table-headergtltportletAPItext key=url bundle=nlsTextgtltthgt

lttdgtlttdgt

lttrgt

lt

PortletData prefs = portletRequestgetData()

Enumeration e = prefsgetAttributeNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltportletAPItext key=no_bookmarks bundle=nlsTextgtNo

bookmarksltportletAPItextgtltpgt

lt

else

while (ehasMoreElements())

- 44 -

String name = (String)enextElement()

String value = (String)prefsgetAttribute(name)

gt

lttr class=wpsTableRowgt

lttdgt lt=namegt lttdgt

lttdgt lt=valuegt lttdgt

lttdgt lta href=ltportletAPIcreateURIgtltportletAPIURIAction

name=removeURIgtltportletAPIURIParameter name=remove

value=lt=namegtgtltportletAPIcreateURIgtgt

(ltportletAPItext key=delete bundle=nlsTextgt)ltagt

lttdgt

lttrgt

lt

gt

ltform action=lt=addURIgt method=POSTgt

lttr class=wpsTableRowgt

lttdgtltinput name=ltportletAPIencodeNamespace value=namegt type=text

class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=ltportletAPIencodeNamespace value=valuegt type=text

class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=ltportletAPIencodeNamespace value=addgt type=submit

value=ltportletAPItext key=add bundle=nlsTextgt class=portlet-form-buttongtlttdgt

lttrgt

ltformgt

lttablegt

- 45 -

ltform action=lt=cancelURIgt method=postgt

ltinput name=ltportletAPIencodeNamespace value=cancelgt type=submit

value=ltportletAPItext key=cancel bundle=nlsTextgt class=portlet-form-buttongt

ltformgt

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 ldquodeleterdquo button for which an URL with the action ldquoremoveURIrdquo 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 ldquocancelrdquo button from the request

64 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

lt page import=javaxportlet javautil session=falsegt

lt taglib uri=httpjavasuncomportlet prefix=portletAPI gt

lt taglib prefix=fmt uri=httpjavasuncomjstlfmt gt

ltportletAPIdefineObjects gt

ltfmtsetBundle basename=nlsTextgt

lt

ResourceBundle myText = ResourceBundlegetBundle(nlsText requestgetLocale())

gt

lth4gtltfmtmessage key=available_bookmarksgtlth4gt

lt

PortletPreferences prefs = renderRequestgetPreferences()

Enumeration e = prefsgetNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltfmtmessage key=no_bookmarksgtltpgt

- 46 -

lt

else

gt

ltpgt

lt

while (ehasMoreElements())

String name = (String)enextElement()

String value = prefsgetValue(namelt+myTextgetString(undefined)+gt)

gt

lta href=lt=valuegt target=_blankgtlt=namegtltagtltbr gt

lt

gt

ltpgt

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 fmtmessage 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

lt page import=javaxportlet javautil session=false gt

lt taglib uri=httpjavasuncomportlet prefix=portletAPI gt

lt taglib prefix=fmt uri=httpjavasuncomjstlfmt gt

ltjspuseBean id=addUrl scope=request class=javalangString gt

ltjspuseBean id=cancelUrl scope=request class=javalangString gt

- 47 -

ltportletAPIdefineObjectsgt

lt

ResourceBundle myText = ResourceBundlegetBundle(nlsText requestgetLocale())

gt

ltfmtsetBundle basename=nlsTextgt

lth4gtltfmtmessage key=available_bookmarksgtlth4gt

lttable class=wpsTablegt

lttr class=wpsTableRowgt

ltth class=wpsTableHeadgtltfmtmessage key=namegtltthgt

ltth class=wpsTableHeadgtltfmtmessage key=urlgtltthgt

lttdgtlttdgt

lttrgt

lt

PortletPreferences prefs = renderRequestgetPreferences()

Enumeration e = prefsgetNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltfmtmessage key=no_bookmarksgtltpgt

lt

else

while (ehasMoreElements())

String name = (String)enextElement()

String value = prefsgetValue(namelt+myTextgetString(undefined)+gt)

gt

lttr class=wpsTableRowgt

lttdgt lt=namegt lttdgt

lttdgt lt=valuegt lttdgt

- 48 -

lttdgt ltportletAPIactionURL var=removeUrlgt

ltportletAPIparam name=remove value=lt=namegtgt

ltportletAPIactionURLgt

lta href=lt=removeUrltoString()gtgt(ltfmtmessage key=deletegt)ltagt

lttdgt

lttrgt

lt

gt

ltform action=lt=addUrlgt method=POSTgt

lttr class=wpsTableRowgt

lttdgtltinput name=name type=text class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=value type=text class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=add type=submit value=ltfmtmessage key=addgt

class=portlet-form-buttongtlttdgt

lttrgt

ltformgt

lttablegt

ltform action=lt=cancelUrlgt method=postgt

ltinput name=cancel type=submit value=ltfmtmessage key=cancelgt class=portlet-

form-buttongt

ltformgt

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 14 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 -

- 51 -

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 (eg eventing) the IBM Portlet API still needs to be used Trademarks bull IBM and WebSphere are trademarks or registered trademarks of IBM Corporation in

the United States other countries or both bull 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 bull Other company product and service names may be trademarks or service marks of

others IBM copyright and trademark information httpwwwibmcomlegalcopytradephtml

  • Introduction
  • JSR 168 and the Java Community Process
  • Comparing concepts
    • Basic concepts
      • Portal
      • Portal page
      • Portlet
      • Portlet Container
        • Concepts that are the same
          • Portlet mode
          • Window state
          • Portlet life cycle and request processing
          • URL encoding
          • Include servletsJSPs
          • Portlet application packaging
          • Expiration-based caching
            • Concepts that differ
              • Portlet application entity
              • Portlet entity
              • Action and Render Request Response objects
              • Window concept
              • Portlet API does not extend servlet API
              • TAG libraries
                • Concepts new in the JSR 168
                  • Render parameter
                  • Extension mechanisms
                    • Custom window states
                    • Custom portlet modes
                    • Custom user info
                    • Request Response properties
                      • Web application session scope
                      • Reuse of the HttpSession listeners
                      • J2EE role support
                      • Resource bundles
                      • Multiple response content types
                      • Redirect in action
                      • Preference validator
                      • Portal context
                      • Localization support
                        • Concepts missing in the JSR 168
                          • Eventing
                          • Additional lifecycle events
                          • Property broker
                          • Portlet Menus
                          • Portlet Services
                          • Invalidation-based caching
                            • Alignment with WSRP
                              • Outlook for the next version of the JSR 168
                              • Guidelines for programming IBM Portlet API portlets
                                • Similar Functionality
                                  • Basic programming model
                                  • Portlet private session
                                  • User profile information
                                  • Persistent data
                                  • Portlet modes and window states
                                  • Expiration-based caching
                                    • Slightly different functionality
                                      • Sharing of data between portlets
                                      • Session listeners
                                        • New JSR 168 functionality
                                          • Navigational state (render parameters)
                                            • Pitfalls
                                              • Request response objects for action and render phase
                                              • Include search path
                                              • Form parameter encoding
                                              • Title setting
                                                  • Examples
                                                    • IBM Portlet API Portlet Code
                                                    • JSR 168 Portlet Code
                                                    • IBM Portlet API JSPs
                                                    • JSR 168 JSPs
                                                      • Summary
Page 25: Difference Bw Jsr168 and Ibm

Figure 4 Portlet menu example

355 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

356 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 -

36 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 indicates portlet in what mode to operate for a given request

View edit help + custom modes

view edit help + custom modes

full alignment

Window State the state of the window in which the portlet output will be displayed

minimized normal maximized solo +

custom window states

minimized normal maximized +

custom window states

full alignment (ldquosolordquo is missing in the JSR but can be implemented as a custom state)

URL encoding to allow re-writing URLs created by the portlet

defines how to create URLs to allow re-writing of the URLs either on consumer or producer side

encapsulates URL creation via a Java object

full alignment (the implementation of the Java object can implement the WSRP URL rewriting rules)

Namespace encoding to avoid that several portlets on a page conflicting with each other

defines namespace prefixes for consumer and producer side namespacing

provides a Java method to namespace a String

full alignment (the JSR namespace method can implement the WSRP namespace behavior)

User ndash portlet interaction operations

performBlockingInteraction blocking action processing

getMarkup render the markup

action blocking action processing

render render the makup

full alignment (action invocations carried through performBlockingInteraction render carried through getMarkup)

View state that allows the current portlet fragment to be correctly displayed in sub-sequent render calls

navigational state render parameter full alignment (WSRP navigational state maps to JSR render parameters)

Storing transient state across request

session state concept implemented via a sessionID

utilizes the Http web application session

full alignment (the WSRP sessionID can be used to reference the JSR session)

Storing persistent state to personalize the rendering of the portlet

allows to have properties of arbitrary types

provides String-based preferences

full alignment (JSR String preferences can be mapped to WSRP properties)

Information about the portal calling the portlet

RegistrationData provide information of the consumer to the producer

PortalContext provide a Java interface to access information about the portal calling the portlet

full alignment (all data represented through the PortalContext to the JSR portlet are available in the RegistrationData)

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

Aggregated HTML WML VoiceXML

over HTTPMark-Up Fragments

Transferred via WSRP

Portal

WSRP Service

WSRP Service

WSRP Service

WSRP Consumer WSRP Producer

Use of WSRP Services in Portals

Portal sharing Portlets as WSRP Services

ServerPortalPortals

Huge numberof users Publishing Portal

WSRPWrapperPortalsPortalsPortal

Portlet

Portlet

Portlet

WSRP Consumer WSRP Producer

ProxyPortlet

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

bull 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

bull 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

bull 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

bull 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 CCPP standard allowing a portlet to query the client capabilities and adopting its markup accordingly (eg screen size browser) This API is likely to be included in the next version of the portlet API Also J2EE 14 was finalized during this time period J2EE 14 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 14

bull caching The first version of the JSR 168 API is limited to expiration-based caching (see section 327) 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

bull 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

51 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

511 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

bull portlets are components Portlets are components that implement a specific function Different functions should be distributed to different portlets

bull 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

bull 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

512 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 HttpServletRequestgetSession() call in the JSPs called via the IBM Portlet API needs to be replaced when moving to JSR 168 portlets by the RenderRequestgetPortletSession() 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 HttpServletRequestgetSession() will get the HttpSession and therefore need to access the portlet session via the RenderRequest

513 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

514 Persistent data

Portlets can store customization and personalization data persistently Customization data are related to the portlet and are valid for all users (eg 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 (eg 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

515 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

516 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

52 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

521 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 351 353) 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

522 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

53 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 -

531 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

bull no support of the back button in the browser bull current state of the portlet is not bookmarkable bull 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 bull 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

54 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

541 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 -

542 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

543 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

544 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 wersquoll 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

Figure 7After clicking on the Edit mode button the portlet renders the Edit view shown in

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

Figure 8

After we press the ldquoAddrdquo 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

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

bull use JSPs for rendering the output bull customize the portlet output taking user specific data into account bull 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

61 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 comibmwpssampleswp5

import javaio

import javautil

import orgapachejetspeedportlet

import orgapachejetspeedportletevent

public class IbmBookmark extends PortletAdapter implements ActionListener

public void init(PortletConfig portletConfig) throws UnavailableException

superinit(portletConfig)

- 36 -

public void doView(PortletRequest request PortletResponse response)

throws PortletException IOException

String jspName = thisgetPortletConfig()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 = responsecreateReturnURI()

addURIaddAction(add)

requestsetAttribute(addURI addURItoString())

PortletURI cancelURI = responsecreateReturnURI()

requestsetAttribute(cancelURI cancelURItoString())

String jspName = thisgetPortletConfig()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 ldquocancelrdquo and ldquoaddrdquo URLs are created inside the portlet and attached to the request before including the Edit JSP Both URLs are from type ldquoReturnURIrdquo 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 = eventgetRequest()

String action = eventgetActionString()

PortletLog log = getPortletLog()

if ( action=null )

try

if (actionequals(removeURI))

String removeName = requestgetParameter(remove)

PortletData portData = requestgetData()

portDataremoveAttribute(removeName)

portDatastore()

if (actionequals(add))

PortletData portData = requestgetData()

String name = requestgetParameter(name)

String value = requestgetParameter(value)

portDatasetAttribute(name value)

portDatastore()

catch ( AccessDeniedException ade )

logerror(AccessDeniedException occured when adding or deleting a bookmark)

catch ( IOException ioe )

logerror(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 ldquoaddrdquo or ldquodeleterdquo 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 ldquoaddrdquo or ldquoremoveURIrdquo If the user has clicked on the ldquoremoverdquo button the corresponding link is removed from the portlet data whereas if ldquoaddrdquo was clicked the data entered by the user is added to the portlet data

62 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 comibmwpssamplesjsr

import javaio

import javaxportlet

public class Bookmark extends GenericPortlet

public void init(PortletConfig config) throws PortletException

superinit(config)

public void doView(RenderRequest request RenderResponse response)

throws PortletException IOException

responsesetContentType(texthtml)

String jspName = getPortletConfig()getInitParameter(jspView)

PortletRequestDispatcher rd = getPortletContext()getRequestDispatcher(jspName)

rdinclude(requestresponse)

- 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

responsesetContentType(texthtml)

PortletURL addUrl = responsecreateActionURL()

addUrlsetPortletMode(PortletModeVIEW)

addUrlsetParameter(addadd)

requestsetAttribute(addUrladdUrltoString())

PortletURL cancelUrl = responsecreateRenderURL()

cancelUrlsetPortletMode(PortletModeVIEW)

requestsetAttribute(cancelUrlcancelUrltoString())

String jspName = getPortletConfig()getInitParameter(jspEdit)

PortletRequestDispatcher rd = getPortletContext()getRequestDispatcher(jspName)

rdinclude(requestresponse)

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 ldquoaddrdquo button URL an action URL is created as we need to store the user input of the add form persistently For the ldquocancelrdquo 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 = requestgetParameter(remove)

if (removeName = null)

PortletPreferences prefs = requestgetPreferences()

prefsreset(removeName)

prefsstore()

String add = requestgetParameter(add)

if (add = null)

PortletPreferences prefs = requestgetPreferences()

String name = requestgetParameter(name)

String value = requestgetParameter(value)

prefssetValue(name value)

prefsstore()

catch ( IOException ioe )

getPortletContextlog(An IO error occured when trying to remove a bookmark)

catch ( PortletException pe )

getPortletContextlog(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

bull 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

bull 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

bull Persistent portlet data The JSR 168 persistent data PortletPreferences have an API similar to the JDK 14 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

bull 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

63 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

lt page contentType=texthtml import=javautil comibmwpssampleswp5

orgapachejetspeedportlet session=falsegt

lt taglib uri=WEB-INFtldportlettld prefix=portletAPI gt

- 42 -

ltportletAPIinitgt

ltp class=wpsPortletHeadgtltportletAPItext key=available_bookmarks

bundle=nlsTextgtAvailable BookmarksltportletAPItextgtltpgt

lt

PortletData prefs = portletRequestgetData()

Enumeration e = prefsgetAttributeNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltportletAPItext key=no_bookmarks bundle=nlsTextgtNo

bookmarksltportletAPItextgtltpgt

lt

else

gt

ltp class=wpsIndentMediumgt

lt

while (ehasMoreElements())

String name = (String)enextElement()

String value = (String)prefsgetAttribute(name)

gt

lta href=lt=valuegt target=_blankgtlt=namegtltagtltbr gt

lt

gt

ltpgt

The View JSP first call portletAPIinit 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

lt page contentType=texthtml import=javautil

comibmwpssampleswp5orgapachejetspeedportlet session=falsegt

lt taglib uri=WEB-INFtldportlettld prefix=portletAPI gt

ltjspuseBean id=addURI class=javalangString scope=request gt

ltjspuseBean id=cancelURI class=javalangString scope=request gt

ltportletAPIinitgt

lth4gtltportletAPItext key=available_bookmarks bundle=nlsTextgtAvailable

BookmarksltportletAPItextgtlth4gt

lttable class=wpsTablegt

lttr class=wpsTableRowgt

ltth class=portlet-table-headergtltportletAPItext key=name bundle=nlsTextgtltthgt

ltth class=portlet-table-headergtltportletAPItext key=url bundle=nlsTextgtltthgt

lttdgtlttdgt

lttrgt

lt

PortletData prefs = portletRequestgetData()

Enumeration e = prefsgetAttributeNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltportletAPItext key=no_bookmarks bundle=nlsTextgtNo

bookmarksltportletAPItextgtltpgt

lt

else

while (ehasMoreElements())

- 44 -

String name = (String)enextElement()

String value = (String)prefsgetAttribute(name)

gt

lttr class=wpsTableRowgt

lttdgt lt=namegt lttdgt

lttdgt lt=valuegt lttdgt

lttdgt lta href=ltportletAPIcreateURIgtltportletAPIURIAction

name=removeURIgtltportletAPIURIParameter name=remove

value=lt=namegtgtltportletAPIcreateURIgtgt

(ltportletAPItext key=delete bundle=nlsTextgt)ltagt

lttdgt

lttrgt

lt

gt

ltform action=lt=addURIgt method=POSTgt

lttr class=wpsTableRowgt

lttdgtltinput name=ltportletAPIencodeNamespace value=namegt type=text

class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=ltportletAPIencodeNamespace value=valuegt type=text

class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=ltportletAPIencodeNamespace value=addgt type=submit

value=ltportletAPItext key=add bundle=nlsTextgt class=portlet-form-buttongtlttdgt

lttrgt

ltformgt

lttablegt

- 45 -

ltform action=lt=cancelURIgt method=postgt

ltinput name=ltportletAPIencodeNamespace value=cancelgt type=submit

value=ltportletAPItext key=cancel bundle=nlsTextgt class=portlet-form-buttongt

ltformgt

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 ldquodeleterdquo button for which an URL with the action ldquoremoveURIrdquo 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 ldquocancelrdquo button from the request

64 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

lt page import=javaxportlet javautil session=falsegt

lt taglib uri=httpjavasuncomportlet prefix=portletAPI gt

lt taglib prefix=fmt uri=httpjavasuncomjstlfmt gt

ltportletAPIdefineObjects gt

ltfmtsetBundle basename=nlsTextgt

lt

ResourceBundle myText = ResourceBundlegetBundle(nlsText requestgetLocale())

gt

lth4gtltfmtmessage key=available_bookmarksgtlth4gt

lt

PortletPreferences prefs = renderRequestgetPreferences()

Enumeration e = prefsgetNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltfmtmessage key=no_bookmarksgtltpgt

- 46 -

lt

else

gt

ltpgt

lt

while (ehasMoreElements())

String name = (String)enextElement()

String value = prefsgetValue(namelt+myTextgetString(undefined)+gt)

gt

lta href=lt=valuegt target=_blankgtlt=namegtltagtltbr gt

lt

gt

ltpgt

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 fmtmessage 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

lt page import=javaxportlet javautil session=false gt

lt taglib uri=httpjavasuncomportlet prefix=portletAPI gt

lt taglib prefix=fmt uri=httpjavasuncomjstlfmt gt

ltjspuseBean id=addUrl scope=request class=javalangString gt

ltjspuseBean id=cancelUrl scope=request class=javalangString gt

- 47 -

ltportletAPIdefineObjectsgt

lt

ResourceBundle myText = ResourceBundlegetBundle(nlsText requestgetLocale())

gt

ltfmtsetBundle basename=nlsTextgt

lth4gtltfmtmessage key=available_bookmarksgtlth4gt

lttable class=wpsTablegt

lttr class=wpsTableRowgt

ltth class=wpsTableHeadgtltfmtmessage key=namegtltthgt

ltth class=wpsTableHeadgtltfmtmessage key=urlgtltthgt

lttdgtlttdgt

lttrgt

lt

PortletPreferences prefs = renderRequestgetPreferences()

Enumeration e = prefsgetNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltfmtmessage key=no_bookmarksgtltpgt

lt

else

while (ehasMoreElements())

String name = (String)enextElement()

String value = prefsgetValue(namelt+myTextgetString(undefined)+gt)

gt

lttr class=wpsTableRowgt

lttdgt lt=namegt lttdgt

lttdgt lt=valuegt lttdgt

- 48 -

lttdgt ltportletAPIactionURL var=removeUrlgt

ltportletAPIparam name=remove value=lt=namegtgt

ltportletAPIactionURLgt

lta href=lt=removeUrltoString()gtgt(ltfmtmessage key=deletegt)ltagt

lttdgt

lttrgt

lt

gt

ltform action=lt=addUrlgt method=POSTgt

lttr class=wpsTableRowgt

lttdgtltinput name=name type=text class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=value type=text class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=add type=submit value=ltfmtmessage key=addgt

class=portlet-form-buttongtlttdgt

lttrgt

ltformgt

lttablegt

ltform action=lt=cancelUrlgt method=postgt

ltinput name=cancel type=submit value=ltfmtmessage key=cancelgt class=portlet-

form-buttongt

ltformgt

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 14 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 -

- 51 -

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 (eg eventing) the IBM Portlet API still needs to be used Trademarks bull IBM and WebSphere are trademarks or registered trademarks of IBM Corporation in

the United States other countries or both bull 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 bull Other company product and service names may be trademarks or service marks of

others IBM copyright and trademark information httpwwwibmcomlegalcopytradephtml

  • Introduction
  • JSR 168 and the Java Community Process
  • Comparing concepts
    • Basic concepts
      • Portal
      • Portal page
      • Portlet
      • Portlet Container
        • Concepts that are the same
          • Portlet mode
          • Window state
          • Portlet life cycle and request processing
          • URL encoding
          • Include servletsJSPs
          • Portlet application packaging
          • Expiration-based caching
            • Concepts that differ
              • Portlet application entity
              • Portlet entity
              • Action and Render Request Response objects
              • Window concept
              • Portlet API does not extend servlet API
              • TAG libraries
                • Concepts new in the JSR 168
                  • Render parameter
                  • Extension mechanisms
                    • Custom window states
                    • Custom portlet modes
                    • Custom user info
                    • Request Response properties
                      • Web application session scope
                      • Reuse of the HttpSession listeners
                      • J2EE role support
                      • Resource bundles
                      • Multiple response content types
                      • Redirect in action
                      • Preference validator
                      • Portal context
                      • Localization support
                        • Concepts missing in the JSR 168
                          • Eventing
                          • Additional lifecycle events
                          • Property broker
                          • Portlet Menus
                          • Portlet Services
                          • Invalidation-based caching
                            • Alignment with WSRP
                              • Outlook for the next version of the JSR 168
                              • Guidelines for programming IBM Portlet API portlets
                                • Similar Functionality
                                  • Basic programming model
                                  • Portlet private session
                                  • User profile information
                                  • Persistent data
                                  • Portlet modes and window states
                                  • Expiration-based caching
                                    • Slightly different functionality
                                      • Sharing of data between portlets
                                      • Session listeners
                                        • New JSR 168 functionality
                                          • Navigational state (render parameters)
                                            • Pitfalls
                                              • Request response objects for action and render phase
                                              • Include search path
                                              • Form parameter encoding
                                              • Title setting
                                                  • Examples
                                                    • IBM Portlet API Portlet Code
                                                    • JSR 168 Portlet Code
                                                    • IBM Portlet API JSPs
                                                    • JSR 168 JSPs
                                                      • Summary
Page 26: Difference Bw Jsr168 and Ibm

36 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 indicates portlet in what mode to operate for a given request

View edit help + custom modes

view edit help + custom modes

full alignment

Window State the state of the window in which the portlet output will be displayed

minimized normal maximized solo +

custom window states

minimized normal maximized +

custom window states

full alignment (ldquosolordquo is missing in the JSR but can be implemented as a custom state)

URL encoding to allow re-writing URLs created by the portlet

defines how to create URLs to allow re-writing of the URLs either on consumer or producer side

encapsulates URL creation via a Java object

full alignment (the implementation of the Java object can implement the WSRP URL rewriting rules)

Namespace encoding to avoid that several portlets on a page conflicting with each other

defines namespace prefixes for consumer and producer side namespacing

provides a Java method to namespace a String

full alignment (the JSR namespace method can implement the WSRP namespace behavior)

User ndash portlet interaction operations

performBlockingInteraction blocking action processing

getMarkup render the markup

action blocking action processing

render render the makup

full alignment (action invocations carried through performBlockingInteraction render carried through getMarkup)

View state that allows the current portlet fragment to be correctly displayed in sub-sequent render calls

navigational state render parameter full alignment (WSRP navigational state maps to JSR render parameters)

Storing transient state across request

session state concept implemented via a sessionID

utilizes the Http web application session

full alignment (the WSRP sessionID can be used to reference the JSR session)

Storing persistent state to personalize the rendering of the portlet

allows to have properties of arbitrary types

provides String-based preferences

full alignment (JSR String preferences can be mapped to WSRP properties)

Information about the portal calling the portlet

RegistrationData provide information of the consumer to the producer

PortalContext provide a Java interface to access information about the portal calling the portlet

full alignment (all data represented through the PortalContext to the JSR portlet are available in the RegistrationData)

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

Aggregated HTML WML VoiceXML

over HTTPMark-Up Fragments

Transferred via WSRP

Portal

WSRP Service

WSRP Service

WSRP Service

WSRP Consumer WSRP Producer

Use of WSRP Services in Portals

Portal sharing Portlets as WSRP Services

ServerPortalPortals

Huge numberof users Publishing Portal

WSRPWrapperPortalsPortalsPortal

Portlet

Portlet

Portlet

WSRP Consumer WSRP Producer

ProxyPortlet

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

bull 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

bull 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

bull 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

bull 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 CCPP standard allowing a portlet to query the client capabilities and adopting its markup accordingly (eg screen size browser) This API is likely to be included in the next version of the portlet API Also J2EE 14 was finalized during this time period J2EE 14 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 14

bull caching The first version of the JSR 168 API is limited to expiration-based caching (see section 327) 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

bull 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

51 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

511 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

bull portlets are components Portlets are components that implement a specific function Different functions should be distributed to different portlets

bull 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

bull 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

512 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 HttpServletRequestgetSession() call in the JSPs called via the IBM Portlet API needs to be replaced when moving to JSR 168 portlets by the RenderRequestgetPortletSession() 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 HttpServletRequestgetSession() will get the HttpSession and therefore need to access the portlet session via the RenderRequest

513 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

514 Persistent data

Portlets can store customization and personalization data persistently Customization data are related to the portlet and are valid for all users (eg 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 (eg 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

515 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

516 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

52 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

521 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 351 353) 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

522 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

53 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 -

531 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

bull no support of the back button in the browser bull current state of the portlet is not bookmarkable bull 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 bull 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

54 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

541 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 -

542 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

543 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

544 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 wersquoll 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

Figure 7After clicking on the Edit mode button the portlet renders the Edit view shown in

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

Figure 8

After we press the ldquoAddrdquo 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

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

bull use JSPs for rendering the output bull customize the portlet output taking user specific data into account bull 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

61 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 comibmwpssampleswp5

import javaio

import javautil

import orgapachejetspeedportlet

import orgapachejetspeedportletevent

public class IbmBookmark extends PortletAdapter implements ActionListener

public void init(PortletConfig portletConfig) throws UnavailableException

superinit(portletConfig)

- 36 -

public void doView(PortletRequest request PortletResponse response)

throws PortletException IOException

String jspName = thisgetPortletConfig()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 = responsecreateReturnURI()

addURIaddAction(add)

requestsetAttribute(addURI addURItoString())

PortletURI cancelURI = responsecreateReturnURI()

requestsetAttribute(cancelURI cancelURItoString())

String jspName = thisgetPortletConfig()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 ldquocancelrdquo and ldquoaddrdquo URLs are created inside the portlet and attached to the request before including the Edit JSP Both URLs are from type ldquoReturnURIrdquo 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 = eventgetRequest()

String action = eventgetActionString()

PortletLog log = getPortletLog()

if ( action=null )

try

if (actionequals(removeURI))

String removeName = requestgetParameter(remove)

PortletData portData = requestgetData()

portDataremoveAttribute(removeName)

portDatastore()

if (actionequals(add))

PortletData portData = requestgetData()

String name = requestgetParameter(name)

String value = requestgetParameter(value)

portDatasetAttribute(name value)

portDatastore()

catch ( AccessDeniedException ade )

logerror(AccessDeniedException occured when adding or deleting a bookmark)

catch ( IOException ioe )

logerror(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 ldquoaddrdquo or ldquodeleterdquo 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 ldquoaddrdquo or ldquoremoveURIrdquo If the user has clicked on the ldquoremoverdquo button the corresponding link is removed from the portlet data whereas if ldquoaddrdquo was clicked the data entered by the user is added to the portlet data

62 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 comibmwpssamplesjsr

import javaio

import javaxportlet

public class Bookmark extends GenericPortlet

public void init(PortletConfig config) throws PortletException

superinit(config)

public void doView(RenderRequest request RenderResponse response)

throws PortletException IOException

responsesetContentType(texthtml)

String jspName = getPortletConfig()getInitParameter(jspView)

PortletRequestDispatcher rd = getPortletContext()getRequestDispatcher(jspName)

rdinclude(requestresponse)

- 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

responsesetContentType(texthtml)

PortletURL addUrl = responsecreateActionURL()

addUrlsetPortletMode(PortletModeVIEW)

addUrlsetParameter(addadd)

requestsetAttribute(addUrladdUrltoString())

PortletURL cancelUrl = responsecreateRenderURL()

cancelUrlsetPortletMode(PortletModeVIEW)

requestsetAttribute(cancelUrlcancelUrltoString())

String jspName = getPortletConfig()getInitParameter(jspEdit)

PortletRequestDispatcher rd = getPortletContext()getRequestDispatcher(jspName)

rdinclude(requestresponse)

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 ldquoaddrdquo button URL an action URL is created as we need to store the user input of the add form persistently For the ldquocancelrdquo 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 = requestgetParameter(remove)

if (removeName = null)

PortletPreferences prefs = requestgetPreferences()

prefsreset(removeName)

prefsstore()

String add = requestgetParameter(add)

if (add = null)

PortletPreferences prefs = requestgetPreferences()

String name = requestgetParameter(name)

String value = requestgetParameter(value)

prefssetValue(name value)

prefsstore()

catch ( IOException ioe )

getPortletContextlog(An IO error occured when trying to remove a bookmark)

catch ( PortletException pe )

getPortletContextlog(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

bull 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

bull 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

bull Persistent portlet data The JSR 168 persistent data PortletPreferences have an API similar to the JDK 14 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

bull 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

63 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

lt page contentType=texthtml import=javautil comibmwpssampleswp5

orgapachejetspeedportlet session=falsegt

lt taglib uri=WEB-INFtldportlettld prefix=portletAPI gt

- 42 -

ltportletAPIinitgt

ltp class=wpsPortletHeadgtltportletAPItext key=available_bookmarks

bundle=nlsTextgtAvailable BookmarksltportletAPItextgtltpgt

lt

PortletData prefs = portletRequestgetData()

Enumeration e = prefsgetAttributeNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltportletAPItext key=no_bookmarks bundle=nlsTextgtNo

bookmarksltportletAPItextgtltpgt

lt

else

gt

ltp class=wpsIndentMediumgt

lt

while (ehasMoreElements())

String name = (String)enextElement()

String value = (String)prefsgetAttribute(name)

gt

lta href=lt=valuegt target=_blankgtlt=namegtltagtltbr gt

lt

gt

ltpgt

The View JSP first call portletAPIinit 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

lt page contentType=texthtml import=javautil

comibmwpssampleswp5orgapachejetspeedportlet session=falsegt

lt taglib uri=WEB-INFtldportlettld prefix=portletAPI gt

ltjspuseBean id=addURI class=javalangString scope=request gt

ltjspuseBean id=cancelURI class=javalangString scope=request gt

ltportletAPIinitgt

lth4gtltportletAPItext key=available_bookmarks bundle=nlsTextgtAvailable

BookmarksltportletAPItextgtlth4gt

lttable class=wpsTablegt

lttr class=wpsTableRowgt

ltth class=portlet-table-headergtltportletAPItext key=name bundle=nlsTextgtltthgt

ltth class=portlet-table-headergtltportletAPItext key=url bundle=nlsTextgtltthgt

lttdgtlttdgt

lttrgt

lt

PortletData prefs = portletRequestgetData()

Enumeration e = prefsgetAttributeNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltportletAPItext key=no_bookmarks bundle=nlsTextgtNo

bookmarksltportletAPItextgtltpgt

lt

else

while (ehasMoreElements())

- 44 -

String name = (String)enextElement()

String value = (String)prefsgetAttribute(name)

gt

lttr class=wpsTableRowgt

lttdgt lt=namegt lttdgt

lttdgt lt=valuegt lttdgt

lttdgt lta href=ltportletAPIcreateURIgtltportletAPIURIAction

name=removeURIgtltportletAPIURIParameter name=remove

value=lt=namegtgtltportletAPIcreateURIgtgt

(ltportletAPItext key=delete bundle=nlsTextgt)ltagt

lttdgt

lttrgt

lt

gt

ltform action=lt=addURIgt method=POSTgt

lttr class=wpsTableRowgt

lttdgtltinput name=ltportletAPIencodeNamespace value=namegt type=text

class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=ltportletAPIencodeNamespace value=valuegt type=text

class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=ltportletAPIencodeNamespace value=addgt type=submit

value=ltportletAPItext key=add bundle=nlsTextgt class=portlet-form-buttongtlttdgt

lttrgt

ltformgt

lttablegt

- 45 -

ltform action=lt=cancelURIgt method=postgt

ltinput name=ltportletAPIencodeNamespace value=cancelgt type=submit

value=ltportletAPItext key=cancel bundle=nlsTextgt class=portlet-form-buttongt

ltformgt

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 ldquodeleterdquo button for which an URL with the action ldquoremoveURIrdquo 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 ldquocancelrdquo button from the request

64 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

lt page import=javaxportlet javautil session=falsegt

lt taglib uri=httpjavasuncomportlet prefix=portletAPI gt

lt taglib prefix=fmt uri=httpjavasuncomjstlfmt gt

ltportletAPIdefineObjects gt

ltfmtsetBundle basename=nlsTextgt

lt

ResourceBundle myText = ResourceBundlegetBundle(nlsText requestgetLocale())

gt

lth4gtltfmtmessage key=available_bookmarksgtlth4gt

lt

PortletPreferences prefs = renderRequestgetPreferences()

Enumeration e = prefsgetNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltfmtmessage key=no_bookmarksgtltpgt

- 46 -

lt

else

gt

ltpgt

lt

while (ehasMoreElements())

String name = (String)enextElement()

String value = prefsgetValue(namelt+myTextgetString(undefined)+gt)

gt

lta href=lt=valuegt target=_blankgtlt=namegtltagtltbr gt

lt

gt

ltpgt

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 fmtmessage 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

lt page import=javaxportlet javautil session=false gt

lt taglib uri=httpjavasuncomportlet prefix=portletAPI gt

lt taglib prefix=fmt uri=httpjavasuncomjstlfmt gt

ltjspuseBean id=addUrl scope=request class=javalangString gt

ltjspuseBean id=cancelUrl scope=request class=javalangString gt

- 47 -

ltportletAPIdefineObjectsgt

lt

ResourceBundle myText = ResourceBundlegetBundle(nlsText requestgetLocale())

gt

ltfmtsetBundle basename=nlsTextgt

lth4gtltfmtmessage key=available_bookmarksgtlth4gt

lttable class=wpsTablegt

lttr class=wpsTableRowgt

ltth class=wpsTableHeadgtltfmtmessage key=namegtltthgt

ltth class=wpsTableHeadgtltfmtmessage key=urlgtltthgt

lttdgtlttdgt

lttrgt

lt

PortletPreferences prefs = renderRequestgetPreferences()

Enumeration e = prefsgetNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltfmtmessage key=no_bookmarksgtltpgt

lt

else

while (ehasMoreElements())

String name = (String)enextElement()

String value = prefsgetValue(namelt+myTextgetString(undefined)+gt)

gt

lttr class=wpsTableRowgt

lttdgt lt=namegt lttdgt

lttdgt lt=valuegt lttdgt

- 48 -

lttdgt ltportletAPIactionURL var=removeUrlgt

ltportletAPIparam name=remove value=lt=namegtgt

ltportletAPIactionURLgt

lta href=lt=removeUrltoString()gtgt(ltfmtmessage key=deletegt)ltagt

lttdgt

lttrgt

lt

gt

ltform action=lt=addUrlgt method=POSTgt

lttr class=wpsTableRowgt

lttdgtltinput name=name type=text class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=value type=text class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=add type=submit value=ltfmtmessage key=addgt

class=portlet-form-buttongtlttdgt

lttrgt

ltformgt

lttablegt

ltform action=lt=cancelUrlgt method=postgt

ltinput name=cancel type=submit value=ltfmtmessage key=cancelgt class=portlet-

form-buttongt

ltformgt

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 14 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 -

- 51 -

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 (eg eventing) the IBM Portlet API still needs to be used Trademarks bull IBM and WebSphere are trademarks or registered trademarks of IBM Corporation in

the United States other countries or both bull 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 bull Other company product and service names may be trademarks or service marks of

others IBM copyright and trademark information httpwwwibmcomlegalcopytradephtml

  • Introduction
  • JSR 168 and the Java Community Process
  • Comparing concepts
    • Basic concepts
      • Portal
      • Portal page
      • Portlet
      • Portlet Container
        • Concepts that are the same
          • Portlet mode
          • Window state
          • Portlet life cycle and request processing
          • URL encoding
          • Include servletsJSPs
          • Portlet application packaging
          • Expiration-based caching
            • Concepts that differ
              • Portlet application entity
              • Portlet entity
              • Action and Render Request Response objects
              • Window concept
              • Portlet API does not extend servlet API
              • TAG libraries
                • Concepts new in the JSR 168
                  • Render parameter
                  • Extension mechanisms
                    • Custom window states
                    • Custom portlet modes
                    • Custom user info
                    • Request Response properties
                      • Web application session scope
                      • Reuse of the HttpSession listeners
                      • J2EE role support
                      • Resource bundles
                      • Multiple response content types
                      • Redirect in action
                      • Preference validator
                      • Portal context
                      • Localization support
                        • Concepts missing in the JSR 168
                          • Eventing
                          • Additional lifecycle events
                          • Property broker
                          • Portlet Menus
                          • Portlet Services
                          • Invalidation-based caching
                            • Alignment with WSRP
                              • Outlook for the next version of the JSR 168
                              • Guidelines for programming IBM Portlet API portlets
                                • Similar Functionality
                                  • Basic programming model
                                  • Portlet private session
                                  • User profile information
                                  • Persistent data
                                  • Portlet modes and window states
                                  • Expiration-based caching
                                    • Slightly different functionality
                                      • Sharing of data between portlets
                                      • Session listeners
                                        • New JSR 168 functionality
                                          • Navigational state (render parameters)
                                            • Pitfalls
                                              • Request response objects for action and render phase
                                              • Include search path
                                              • Form parameter encoding
                                              • Title setting
                                                  • Examples
                                                    • IBM Portlet API Portlet Code
                                                    • JSR 168 Portlet Code
                                                    • IBM Portlet API JSPs
                                                    • JSR 168 JSPs
                                                      • Summary
Page 27: Difference Bw Jsr168 and Ibm

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

Aggregated HTML WML VoiceXML

over HTTPMark-Up Fragments

Transferred via WSRP

Portal

WSRP Service

WSRP Service

WSRP Service

WSRP Consumer WSRP Producer

Use of WSRP Services in Portals

Portal sharing Portlets as WSRP Services

ServerPortalPortals

Huge numberof users Publishing Portal

WSRPWrapperPortalsPortalsPortal

Portlet

Portlet

Portlet

WSRP Consumer WSRP Producer

ProxyPortlet

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

bull 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

bull 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

bull 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

bull 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 CCPP standard allowing a portlet to query the client capabilities and adopting its markup accordingly (eg screen size browser) This API is likely to be included in the next version of the portlet API Also J2EE 14 was finalized during this time period J2EE 14 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 14

bull caching The first version of the JSR 168 API is limited to expiration-based caching (see section 327) 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

bull 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

51 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

511 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

bull portlets are components Portlets are components that implement a specific function Different functions should be distributed to different portlets

bull 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

bull 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

512 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 HttpServletRequestgetSession() call in the JSPs called via the IBM Portlet API needs to be replaced when moving to JSR 168 portlets by the RenderRequestgetPortletSession() 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 HttpServletRequestgetSession() will get the HttpSession and therefore need to access the portlet session via the RenderRequest

513 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

514 Persistent data

Portlets can store customization and personalization data persistently Customization data are related to the portlet and are valid for all users (eg 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 (eg 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

515 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

516 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

52 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

521 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 351 353) 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

522 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

53 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 -

531 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

bull no support of the back button in the browser bull current state of the portlet is not bookmarkable bull 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 bull 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

54 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

541 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 -

542 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

543 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

544 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 wersquoll 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

Figure 7After clicking on the Edit mode button the portlet renders the Edit view shown in

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

Figure 8

After we press the ldquoAddrdquo 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

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

bull use JSPs for rendering the output bull customize the portlet output taking user specific data into account bull 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

61 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 comibmwpssampleswp5

import javaio

import javautil

import orgapachejetspeedportlet

import orgapachejetspeedportletevent

public class IbmBookmark extends PortletAdapter implements ActionListener

public void init(PortletConfig portletConfig) throws UnavailableException

superinit(portletConfig)

- 36 -

public void doView(PortletRequest request PortletResponse response)

throws PortletException IOException

String jspName = thisgetPortletConfig()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 = responsecreateReturnURI()

addURIaddAction(add)

requestsetAttribute(addURI addURItoString())

PortletURI cancelURI = responsecreateReturnURI()

requestsetAttribute(cancelURI cancelURItoString())

String jspName = thisgetPortletConfig()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 ldquocancelrdquo and ldquoaddrdquo URLs are created inside the portlet and attached to the request before including the Edit JSP Both URLs are from type ldquoReturnURIrdquo 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 = eventgetRequest()

String action = eventgetActionString()

PortletLog log = getPortletLog()

if ( action=null )

try

if (actionequals(removeURI))

String removeName = requestgetParameter(remove)

PortletData portData = requestgetData()

portDataremoveAttribute(removeName)

portDatastore()

if (actionequals(add))

PortletData portData = requestgetData()

String name = requestgetParameter(name)

String value = requestgetParameter(value)

portDatasetAttribute(name value)

portDatastore()

catch ( AccessDeniedException ade )

logerror(AccessDeniedException occured when adding or deleting a bookmark)

catch ( IOException ioe )

logerror(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 ldquoaddrdquo or ldquodeleterdquo 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 ldquoaddrdquo or ldquoremoveURIrdquo If the user has clicked on the ldquoremoverdquo button the corresponding link is removed from the portlet data whereas if ldquoaddrdquo was clicked the data entered by the user is added to the portlet data

62 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 comibmwpssamplesjsr

import javaio

import javaxportlet

public class Bookmark extends GenericPortlet

public void init(PortletConfig config) throws PortletException

superinit(config)

public void doView(RenderRequest request RenderResponse response)

throws PortletException IOException

responsesetContentType(texthtml)

String jspName = getPortletConfig()getInitParameter(jspView)

PortletRequestDispatcher rd = getPortletContext()getRequestDispatcher(jspName)

rdinclude(requestresponse)

- 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

responsesetContentType(texthtml)

PortletURL addUrl = responsecreateActionURL()

addUrlsetPortletMode(PortletModeVIEW)

addUrlsetParameter(addadd)

requestsetAttribute(addUrladdUrltoString())

PortletURL cancelUrl = responsecreateRenderURL()

cancelUrlsetPortletMode(PortletModeVIEW)

requestsetAttribute(cancelUrlcancelUrltoString())

String jspName = getPortletConfig()getInitParameter(jspEdit)

PortletRequestDispatcher rd = getPortletContext()getRequestDispatcher(jspName)

rdinclude(requestresponse)

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 ldquoaddrdquo button URL an action URL is created as we need to store the user input of the add form persistently For the ldquocancelrdquo 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 = requestgetParameter(remove)

if (removeName = null)

PortletPreferences prefs = requestgetPreferences()

prefsreset(removeName)

prefsstore()

String add = requestgetParameter(add)

if (add = null)

PortletPreferences prefs = requestgetPreferences()

String name = requestgetParameter(name)

String value = requestgetParameter(value)

prefssetValue(name value)

prefsstore()

catch ( IOException ioe )

getPortletContextlog(An IO error occured when trying to remove a bookmark)

catch ( PortletException pe )

getPortletContextlog(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

bull 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

bull 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

bull Persistent portlet data The JSR 168 persistent data PortletPreferences have an API similar to the JDK 14 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

bull 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

63 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

lt page contentType=texthtml import=javautil comibmwpssampleswp5

orgapachejetspeedportlet session=falsegt

lt taglib uri=WEB-INFtldportlettld prefix=portletAPI gt

- 42 -

ltportletAPIinitgt

ltp class=wpsPortletHeadgtltportletAPItext key=available_bookmarks

bundle=nlsTextgtAvailable BookmarksltportletAPItextgtltpgt

lt

PortletData prefs = portletRequestgetData()

Enumeration e = prefsgetAttributeNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltportletAPItext key=no_bookmarks bundle=nlsTextgtNo

bookmarksltportletAPItextgtltpgt

lt

else

gt

ltp class=wpsIndentMediumgt

lt

while (ehasMoreElements())

String name = (String)enextElement()

String value = (String)prefsgetAttribute(name)

gt

lta href=lt=valuegt target=_blankgtlt=namegtltagtltbr gt

lt

gt

ltpgt

The View JSP first call portletAPIinit 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

lt page contentType=texthtml import=javautil

comibmwpssampleswp5orgapachejetspeedportlet session=falsegt

lt taglib uri=WEB-INFtldportlettld prefix=portletAPI gt

ltjspuseBean id=addURI class=javalangString scope=request gt

ltjspuseBean id=cancelURI class=javalangString scope=request gt

ltportletAPIinitgt

lth4gtltportletAPItext key=available_bookmarks bundle=nlsTextgtAvailable

BookmarksltportletAPItextgtlth4gt

lttable class=wpsTablegt

lttr class=wpsTableRowgt

ltth class=portlet-table-headergtltportletAPItext key=name bundle=nlsTextgtltthgt

ltth class=portlet-table-headergtltportletAPItext key=url bundle=nlsTextgtltthgt

lttdgtlttdgt

lttrgt

lt

PortletData prefs = portletRequestgetData()

Enumeration e = prefsgetAttributeNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltportletAPItext key=no_bookmarks bundle=nlsTextgtNo

bookmarksltportletAPItextgtltpgt

lt

else

while (ehasMoreElements())

- 44 -

String name = (String)enextElement()

String value = (String)prefsgetAttribute(name)

gt

lttr class=wpsTableRowgt

lttdgt lt=namegt lttdgt

lttdgt lt=valuegt lttdgt

lttdgt lta href=ltportletAPIcreateURIgtltportletAPIURIAction

name=removeURIgtltportletAPIURIParameter name=remove

value=lt=namegtgtltportletAPIcreateURIgtgt

(ltportletAPItext key=delete bundle=nlsTextgt)ltagt

lttdgt

lttrgt

lt

gt

ltform action=lt=addURIgt method=POSTgt

lttr class=wpsTableRowgt

lttdgtltinput name=ltportletAPIencodeNamespace value=namegt type=text

class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=ltportletAPIencodeNamespace value=valuegt type=text

class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=ltportletAPIencodeNamespace value=addgt type=submit

value=ltportletAPItext key=add bundle=nlsTextgt class=portlet-form-buttongtlttdgt

lttrgt

ltformgt

lttablegt

- 45 -

ltform action=lt=cancelURIgt method=postgt

ltinput name=ltportletAPIencodeNamespace value=cancelgt type=submit

value=ltportletAPItext key=cancel bundle=nlsTextgt class=portlet-form-buttongt

ltformgt

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 ldquodeleterdquo button for which an URL with the action ldquoremoveURIrdquo 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 ldquocancelrdquo button from the request

64 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

lt page import=javaxportlet javautil session=falsegt

lt taglib uri=httpjavasuncomportlet prefix=portletAPI gt

lt taglib prefix=fmt uri=httpjavasuncomjstlfmt gt

ltportletAPIdefineObjects gt

ltfmtsetBundle basename=nlsTextgt

lt

ResourceBundle myText = ResourceBundlegetBundle(nlsText requestgetLocale())

gt

lth4gtltfmtmessage key=available_bookmarksgtlth4gt

lt

PortletPreferences prefs = renderRequestgetPreferences()

Enumeration e = prefsgetNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltfmtmessage key=no_bookmarksgtltpgt

- 46 -

lt

else

gt

ltpgt

lt

while (ehasMoreElements())

String name = (String)enextElement()

String value = prefsgetValue(namelt+myTextgetString(undefined)+gt)

gt

lta href=lt=valuegt target=_blankgtlt=namegtltagtltbr gt

lt

gt

ltpgt

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 fmtmessage 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

lt page import=javaxportlet javautil session=false gt

lt taglib uri=httpjavasuncomportlet prefix=portletAPI gt

lt taglib prefix=fmt uri=httpjavasuncomjstlfmt gt

ltjspuseBean id=addUrl scope=request class=javalangString gt

ltjspuseBean id=cancelUrl scope=request class=javalangString gt

- 47 -

ltportletAPIdefineObjectsgt

lt

ResourceBundle myText = ResourceBundlegetBundle(nlsText requestgetLocale())

gt

ltfmtsetBundle basename=nlsTextgt

lth4gtltfmtmessage key=available_bookmarksgtlth4gt

lttable class=wpsTablegt

lttr class=wpsTableRowgt

ltth class=wpsTableHeadgtltfmtmessage key=namegtltthgt

ltth class=wpsTableHeadgtltfmtmessage key=urlgtltthgt

lttdgtlttdgt

lttrgt

lt

PortletPreferences prefs = renderRequestgetPreferences()

Enumeration e = prefsgetNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltfmtmessage key=no_bookmarksgtltpgt

lt

else

while (ehasMoreElements())

String name = (String)enextElement()

String value = prefsgetValue(namelt+myTextgetString(undefined)+gt)

gt

lttr class=wpsTableRowgt

lttdgt lt=namegt lttdgt

lttdgt lt=valuegt lttdgt

- 48 -

lttdgt ltportletAPIactionURL var=removeUrlgt

ltportletAPIparam name=remove value=lt=namegtgt

ltportletAPIactionURLgt

lta href=lt=removeUrltoString()gtgt(ltfmtmessage key=deletegt)ltagt

lttdgt

lttrgt

lt

gt

ltform action=lt=addUrlgt method=POSTgt

lttr class=wpsTableRowgt

lttdgtltinput name=name type=text class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=value type=text class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=add type=submit value=ltfmtmessage key=addgt

class=portlet-form-buttongtlttdgt

lttrgt

ltformgt

lttablegt

ltform action=lt=cancelUrlgt method=postgt

ltinput name=cancel type=submit value=ltfmtmessage key=cancelgt class=portlet-

form-buttongt

ltformgt

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 14 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 -

- 51 -

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 (eg eventing) the IBM Portlet API still needs to be used Trademarks bull IBM and WebSphere are trademarks or registered trademarks of IBM Corporation in

the United States other countries or both bull 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 bull Other company product and service names may be trademarks or service marks of

others IBM copyright and trademark information httpwwwibmcomlegalcopytradephtml

  • Introduction
  • JSR 168 and the Java Community Process
  • Comparing concepts
    • Basic concepts
      • Portal
      • Portal page
      • Portlet
      • Portlet Container
        • Concepts that are the same
          • Portlet mode
          • Window state
          • Portlet life cycle and request processing
          • URL encoding
          • Include servletsJSPs
          • Portlet application packaging
          • Expiration-based caching
            • Concepts that differ
              • Portlet application entity
              • Portlet entity
              • Action and Render Request Response objects
              • Window concept
              • Portlet API does not extend servlet API
              • TAG libraries
                • Concepts new in the JSR 168
                  • Render parameter
                  • Extension mechanisms
                    • Custom window states
                    • Custom portlet modes
                    • Custom user info
                    • Request Response properties
                      • Web application session scope
                      • Reuse of the HttpSession listeners
                      • J2EE role support
                      • Resource bundles
                      • Multiple response content types
                      • Redirect in action
                      • Preference validator
                      • Portal context
                      • Localization support
                        • Concepts missing in the JSR 168
                          • Eventing
                          • Additional lifecycle events
                          • Property broker
                          • Portlet Menus
                          • Portlet Services
                          • Invalidation-based caching
                            • Alignment with WSRP
                              • Outlook for the next version of the JSR 168
                              • Guidelines for programming IBM Portlet API portlets
                                • Similar Functionality
                                  • Basic programming model
                                  • Portlet private session
                                  • User profile information
                                  • Persistent data
                                  • Portlet modes and window states
                                  • Expiration-based caching
                                    • Slightly different functionality
                                      • Sharing of data between portlets
                                      • Session listeners
                                        • New JSR 168 functionality
                                          • Navigational state (render parameters)
                                            • Pitfalls
                                              • Request response objects for action and render phase
                                              • Include search path
                                              • Form parameter encoding
                                              • Title setting
                                                  • Examples
                                                    • IBM Portlet API Portlet Code
                                                    • JSR 168 Portlet Code
                                                    • IBM Portlet API JSPs
                                                    • JSR 168 JSPs
                                                      • Summary
Page 28: Difference Bw Jsr168 and Ibm

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

bull 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

bull 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

bull 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

bull 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 CCPP standard allowing a portlet to query the client capabilities and adopting its markup accordingly (eg screen size browser) This API is likely to be included in the next version of the portlet API Also J2EE 14 was finalized during this time period J2EE 14 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 14

bull caching The first version of the JSR 168 API is limited to expiration-based caching (see section 327) 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

bull 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

51 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

511 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

bull portlets are components Portlets are components that implement a specific function Different functions should be distributed to different portlets

bull 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

bull 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

512 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 HttpServletRequestgetSession() call in the JSPs called via the IBM Portlet API needs to be replaced when moving to JSR 168 portlets by the RenderRequestgetPortletSession() 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 HttpServletRequestgetSession() will get the HttpSession and therefore need to access the portlet session via the RenderRequest

513 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

514 Persistent data

Portlets can store customization and personalization data persistently Customization data are related to the portlet and are valid for all users (eg 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 (eg 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

515 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

516 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

52 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

521 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 351 353) 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

522 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

53 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 -

531 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

bull no support of the back button in the browser bull current state of the portlet is not bookmarkable bull 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 bull 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

54 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

541 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 -

542 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

543 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

544 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 wersquoll 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

Figure 7After clicking on the Edit mode button the portlet renders the Edit view shown in

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

Figure 8

After we press the ldquoAddrdquo 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

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

bull use JSPs for rendering the output bull customize the portlet output taking user specific data into account bull 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

61 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 comibmwpssampleswp5

import javaio

import javautil

import orgapachejetspeedportlet

import orgapachejetspeedportletevent

public class IbmBookmark extends PortletAdapter implements ActionListener

public void init(PortletConfig portletConfig) throws UnavailableException

superinit(portletConfig)

- 36 -

public void doView(PortletRequest request PortletResponse response)

throws PortletException IOException

String jspName = thisgetPortletConfig()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 = responsecreateReturnURI()

addURIaddAction(add)

requestsetAttribute(addURI addURItoString())

PortletURI cancelURI = responsecreateReturnURI()

requestsetAttribute(cancelURI cancelURItoString())

String jspName = thisgetPortletConfig()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 ldquocancelrdquo and ldquoaddrdquo URLs are created inside the portlet and attached to the request before including the Edit JSP Both URLs are from type ldquoReturnURIrdquo 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 = eventgetRequest()

String action = eventgetActionString()

PortletLog log = getPortletLog()

if ( action=null )

try

if (actionequals(removeURI))

String removeName = requestgetParameter(remove)

PortletData portData = requestgetData()

portDataremoveAttribute(removeName)

portDatastore()

if (actionequals(add))

PortletData portData = requestgetData()

String name = requestgetParameter(name)

String value = requestgetParameter(value)

portDatasetAttribute(name value)

portDatastore()

catch ( AccessDeniedException ade )

logerror(AccessDeniedException occured when adding or deleting a bookmark)

catch ( IOException ioe )

logerror(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 ldquoaddrdquo or ldquodeleterdquo 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 ldquoaddrdquo or ldquoremoveURIrdquo If the user has clicked on the ldquoremoverdquo button the corresponding link is removed from the portlet data whereas if ldquoaddrdquo was clicked the data entered by the user is added to the portlet data

62 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 comibmwpssamplesjsr

import javaio

import javaxportlet

public class Bookmark extends GenericPortlet

public void init(PortletConfig config) throws PortletException

superinit(config)

public void doView(RenderRequest request RenderResponse response)

throws PortletException IOException

responsesetContentType(texthtml)

String jspName = getPortletConfig()getInitParameter(jspView)

PortletRequestDispatcher rd = getPortletContext()getRequestDispatcher(jspName)

rdinclude(requestresponse)

- 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

responsesetContentType(texthtml)

PortletURL addUrl = responsecreateActionURL()

addUrlsetPortletMode(PortletModeVIEW)

addUrlsetParameter(addadd)

requestsetAttribute(addUrladdUrltoString())

PortletURL cancelUrl = responsecreateRenderURL()

cancelUrlsetPortletMode(PortletModeVIEW)

requestsetAttribute(cancelUrlcancelUrltoString())

String jspName = getPortletConfig()getInitParameter(jspEdit)

PortletRequestDispatcher rd = getPortletContext()getRequestDispatcher(jspName)

rdinclude(requestresponse)

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 ldquoaddrdquo button URL an action URL is created as we need to store the user input of the add form persistently For the ldquocancelrdquo 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 = requestgetParameter(remove)

if (removeName = null)

PortletPreferences prefs = requestgetPreferences()

prefsreset(removeName)

prefsstore()

String add = requestgetParameter(add)

if (add = null)

PortletPreferences prefs = requestgetPreferences()

String name = requestgetParameter(name)

String value = requestgetParameter(value)

prefssetValue(name value)

prefsstore()

catch ( IOException ioe )

getPortletContextlog(An IO error occured when trying to remove a bookmark)

catch ( PortletException pe )

getPortletContextlog(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

bull 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

bull 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

bull Persistent portlet data The JSR 168 persistent data PortletPreferences have an API similar to the JDK 14 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

bull 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

63 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

lt page contentType=texthtml import=javautil comibmwpssampleswp5

orgapachejetspeedportlet session=falsegt

lt taglib uri=WEB-INFtldportlettld prefix=portletAPI gt

- 42 -

ltportletAPIinitgt

ltp class=wpsPortletHeadgtltportletAPItext key=available_bookmarks

bundle=nlsTextgtAvailable BookmarksltportletAPItextgtltpgt

lt

PortletData prefs = portletRequestgetData()

Enumeration e = prefsgetAttributeNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltportletAPItext key=no_bookmarks bundle=nlsTextgtNo

bookmarksltportletAPItextgtltpgt

lt

else

gt

ltp class=wpsIndentMediumgt

lt

while (ehasMoreElements())

String name = (String)enextElement()

String value = (String)prefsgetAttribute(name)

gt

lta href=lt=valuegt target=_blankgtlt=namegtltagtltbr gt

lt

gt

ltpgt

The View JSP first call portletAPIinit 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

lt page contentType=texthtml import=javautil

comibmwpssampleswp5orgapachejetspeedportlet session=falsegt

lt taglib uri=WEB-INFtldportlettld prefix=portletAPI gt

ltjspuseBean id=addURI class=javalangString scope=request gt

ltjspuseBean id=cancelURI class=javalangString scope=request gt

ltportletAPIinitgt

lth4gtltportletAPItext key=available_bookmarks bundle=nlsTextgtAvailable

BookmarksltportletAPItextgtlth4gt

lttable class=wpsTablegt

lttr class=wpsTableRowgt

ltth class=portlet-table-headergtltportletAPItext key=name bundle=nlsTextgtltthgt

ltth class=portlet-table-headergtltportletAPItext key=url bundle=nlsTextgtltthgt

lttdgtlttdgt

lttrgt

lt

PortletData prefs = portletRequestgetData()

Enumeration e = prefsgetAttributeNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltportletAPItext key=no_bookmarks bundle=nlsTextgtNo

bookmarksltportletAPItextgtltpgt

lt

else

while (ehasMoreElements())

- 44 -

String name = (String)enextElement()

String value = (String)prefsgetAttribute(name)

gt

lttr class=wpsTableRowgt

lttdgt lt=namegt lttdgt

lttdgt lt=valuegt lttdgt

lttdgt lta href=ltportletAPIcreateURIgtltportletAPIURIAction

name=removeURIgtltportletAPIURIParameter name=remove

value=lt=namegtgtltportletAPIcreateURIgtgt

(ltportletAPItext key=delete bundle=nlsTextgt)ltagt

lttdgt

lttrgt

lt

gt

ltform action=lt=addURIgt method=POSTgt

lttr class=wpsTableRowgt

lttdgtltinput name=ltportletAPIencodeNamespace value=namegt type=text

class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=ltportletAPIencodeNamespace value=valuegt type=text

class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=ltportletAPIencodeNamespace value=addgt type=submit

value=ltportletAPItext key=add bundle=nlsTextgt class=portlet-form-buttongtlttdgt

lttrgt

ltformgt

lttablegt

- 45 -

ltform action=lt=cancelURIgt method=postgt

ltinput name=ltportletAPIencodeNamespace value=cancelgt type=submit

value=ltportletAPItext key=cancel bundle=nlsTextgt class=portlet-form-buttongt

ltformgt

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 ldquodeleterdquo button for which an URL with the action ldquoremoveURIrdquo 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 ldquocancelrdquo button from the request

64 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

lt page import=javaxportlet javautil session=falsegt

lt taglib uri=httpjavasuncomportlet prefix=portletAPI gt

lt taglib prefix=fmt uri=httpjavasuncomjstlfmt gt

ltportletAPIdefineObjects gt

ltfmtsetBundle basename=nlsTextgt

lt

ResourceBundle myText = ResourceBundlegetBundle(nlsText requestgetLocale())

gt

lth4gtltfmtmessage key=available_bookmarksgtlth4gt

lt

PortletPreferences prefs = renderRequestgetPreferences()

Enumeration e = prefsgetNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltfmtmessage key=no_bookmarksgtltpgt

- 46 -

lt

else

gt

ltpgt

lt

while (ehasMoreElements())

String name = (String)enextElement()

String value = prefsgetValue(namelt+myTextgetString(undefined)+gt)

gt

lta href=lt=valuegt target=_blankgtlt=namegtltagtltbr gt

lt

gt

ltpgt

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 fmtmessage 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

lt page import=javaxportlet javautil session=false gt

lt taglib uri=httpjavasuncomportlet prefix=portletAPI gt

lt taglib prefix=fmt uri=httpjavasuncomjstlfmt gt

ltjspuseBean id=addUrl scope=request class=javalangString gt

ltjspuseBean id=cancelUrl scope=request class=javalangString gt

- 47 -

ltportletAPIdefineObjectsgt

lt

ResourceBundle myText = ResourceBundlegetBundle(nlsText requestgetLocale())

gt

ltfmtsetBundle basename=nlsTextgt

lth4gtltfmtmessage key=available_bookmarksgtlth4gt

lttable class=wpsTablegt

lttr class=wpsTableRowgt

ltth class=wpsTableHeadgtltfmtmessage key=namegtltthgt

ltth class=wpsTableHeadgtltfmtmessage key=urlgtltthgt

lttdgtlttdgt

lttrgt

lt

PortletPreferences prefs = renderRequestgetPreferences()

Enumeration e = prefsgetNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltfmtmessage key=no_bookmarksgtltpgt

lt

else

while (ehasMoreElements())

String name = (String)enextElement()

String value = prefsgetValue(namelt+myTextgetString(undefined)+gt)

gt

lttr class=wpsTableRowgt

lttdgt lt=namegt lttdgt

lttdgt lt=valuegt lttdgt

- 48 -

lttdgt ltportletAPIactionURL var=removeUrlgt

ltportletAPIparam name=remove value=lt=namegtgt

ltportletAPIactionURLgt

lta href=lt=removeUrltoString()gtgt(ltfmtmessage key=deletegt)ltagt

lttdgt

lttrgt

lt

gt

ltform action=lt=addUrlgt method=POSTgt

lttr class=wpsTableRowgt

lttdgtltinput name=name type=text class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=value type=text class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=add type=submit value=ltfmtmessage key=addgt

class=portlet-form-buttongtlttdgt

lttrgt

ltformgt

lttablegt

ltform action=lt=cancelUrlgt method=postgt

ltinput name=cancel type=submit value=ltfmtmessage key=cancelgt class=portlet-

form-buttongt

ltformgt

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 14 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 -

- 51 -

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 (eg eventing) the IBM Portlet API still needs to be used Trademarks bull IBM and WebSphere are trademarks or registered trademarks of IBM Corporation in

the United States other countries or both bull 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 bull Other company product and service names may be trademarks or service marks of

others IBM copyright and trademark information httpwwwibmcomlegalcopytradephtml

  • Introduction
  • JSR 168 and the Java Community Process
  • Comparing concepts
    • Basic concepts
      • Portal
      • Portal page
      • Portlet
      • Portlet Container
        • Concepts that are the same
          • Portlet mode
          • Window state
          • Portlet life cycle and request processing
          • URL encoding
          • Include servletsJSPs
          • Portlet application packaging
          • Expiration-based caching
            • Concepts that differ
              • Portlet application entity
              • Portlet entity
              • Action and Render Request Response objects
              • Window concept
              • Portlet API does not extend servlet API
              • TAG libraries
                • Concepts new in the JSR 168
                  • Render parameter
                  • Extension mechanisms
                    • Custom window states
                    • Custom portlet modes
                    • Custom user info
                    • Request Response properties
                      • Web application session scope
                      • Reuse of the HttpSession listeners
                      • J2EE role support
                      • Resource bundles
                      • Multiple response content types
                      • Redirect in action
                      • Preference validator
                      • Portal context
                      • Localization support
                        • Concepts missing in the JSR 168
                          • Eventing
                          • Additional lifecycle events
                          • Property broker
                          • Portlet Menus
                          • Portlet Services
                          • Invalidation-based caching
                            • Alignment with WSRP
                              • Outlook for the next version of the JSR 168
                              • Guidelines for programming IBM Portlet API portlets
                                • Similar Functionality
                                  • Basic programming model
                                  • Portlet private session
                                  • User profile information
                                  • Persistent data
                                  • Portlet modes and window states
                                  • Expiration-based caching
                                    • Slightly different functionality
                                      • Sharing of data between portlets
                                      • Session listeners
                                        • New JSR 168 functionality
                                          • Navigational state (render parameters)
                                            • Pitfalls
                                              • Request response objects for action and render phase
                                              • Include search path
                                              • Form parameter encoding
                                              • Title setting
                                                  • Examples
                                                    • IBM Portlet API Portlet Code
                                                    • JSR 168 Portlet Code
                                                    • IBM Portlet API JSPs
                                                    • JSR 168 JSPs
                                                      • Summary
Page 29: Difference Bw Jsr168 and Ibm

functionality to support validation-based caching to be completely aligned with WSRP and invalidation-based caching Portlets then actively invalidate cached content

bull 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

51 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

511 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

bull portlets are components Portlets are components that implement a specific function Different functions should be distributed to different portlets

bull 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

bull 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

512 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 HttpServletRequestgetSession() call in the JSPs called via the IBM Portlet API needs to be replaced when moving to JSR 168 portlets by the RenderRequestgetPortletSession() 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 HttpServletRequestgetSession() will get the HttpSession and therefore need to access the portlet session via the RenderRequest

513 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

514 Persistent data

Portlets can store customization and personalization data persistently Customization data are related to the portlet and are valid for all users (eg 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 (eg 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

515 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

516 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

52 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

521 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 351 353) 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

522 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

53 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 -

531 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

bull no support of the back button in the browser bull current state of the portlet is not bookmarkable bull 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 bull 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

54 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

541 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 -

542 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

543 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

544 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 wersquoll 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

Figure 7After clicking on the Edit mode button the portlet renders the Edit view shown in

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

Figure 8

After we press the ldquoAddrdquo 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

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

bull use JSPs for rendering the output bull customize the portlet output taking user specific data into account bull 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

61 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 comibmwpssampleswp5

import javaio

import javautil

import orgapachejetspeedportlet

import orgapachejetspeedportletevent

public class IbmBookmark extends PortletAdapter implements ActionListener

public void init(PortletConfig portletConfig) throws UnavailableException

superinit(portletConfig)

- 36 -

public void doView(PortletRequest request PortletResponse response)

throws PortletException IOException

String jspName = thisgetPortletConfig()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 = responsecreateReturnURI()

addURIaddAction(add)

requestsetAttribute(addURI addURItoString())

PortletURI cancelURI = responsecreateReturnURI()

requestsetAttribute(cancelURI cancelURItoString())

String jspName = thisgetPortletConfig()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 ldquocancelrdquo and ldquoaddrdquo URLs are created inside the portlet and attached to the request before including the Edit JSP Both URLs are from type ldquoReturnURIrdquo 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 = eventgetRequest()

String action = eventgetActionString()

PortletLog log = getPortletLog()

if ( action=null )

try

if (actionequals(removeURI))

String removeName = requestgetParameter(remove)

PortletData portData = requestgetData()

portDataremoveAttribute(removeName)

portDatastore()

if (actionequals(add))

PortletData portData = requestgetData()

String name = requestgetParameter(name)

String value = requestgetParameter(value)

portDatasetAttribute(name value)

portDatastore()

catch ( AccessDeniedException ade )

logerror(AccessDeniedException occured when adding or deleting a bookmark)

catch ( IOException ioe )

logerror(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 ldquoaddrdquo or ldquodeleterdquo 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 ldquoaddrdquo or ldquoremoveURIrdquo If the user has clicked on the ldquoremoverdquo button the corresponding link is removed from the portlet data whereas if ldquoaddrdquo was clicked the data entered by the user is added to the portlet data

62 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 comibmwpssamplesjsr

import javaio

import javaxportlet

public class Bookmark extends GenericPortlet

public void init(PortletConfig config) throws PortletException

superinit(config)

public void doView(RenderRequest request RenderResponse response)

throws PortletException IOException

responsesetContentType(texthtml)

String jspName = getPortletConfig()getInitParameter(jspView)

PortletRequestDispatcher rd = getPortletContext()getRequestDispatcher(jspName)

rdinclude(requestresponse)

- 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

responsesetContentType(texthtml)

PortletURL addUrl = responsecreateActionURL()

addUrlsetPortletMode(PortletModeVIEW)

addUrlsetParameter(addadd)

requestsetAttribute(addUrladdUrltoString())

PortletURL cancelUrl = responsecreateRenderURL()

cancelUrlsetPortletMode(PortletModeVIEW)

requestsetAttribute(cancelUrlcancelUrltoString())

String jspName = getPortletConfig()getInitParameter(jspEdit)

PortletRequestDispatcher rd = getPortletContext()getRequestDispatcher(jspName)

rdinclude(requestresponse)

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 ldquoaddrdquo button URL an action URL is created as we need to store the user input of the add form persistently For the ldquocancelrdquo 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 = requestgetParameter(remove)

if (removeName = null)

PortletPreferences prefs = requestgetPreferences()

prefsreset(removeName)

prefsstore()

String add = requestgetParameter(add)

if (add = null)

PortletPreferences prefs = requestgetPreferences()

String name = requestgetParameter(name)

String value = requestgetParameter(value)

prefssetValue(name value)

prefsstore()

catch ( IOException ioe )

getPortletContextlog(An IO error occured when trying to remove a bookmark)

catch ( PortletException pe )

getPortletContextlog(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

bull 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

bull 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

bull Persistent portlet data The JSR 168 persistent data PortletPreferences have an API similar to the JDK 14 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

bull 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

63 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

lt page contentType=texthtml import=javautil comibmwpssampleswp5

orgapachejetspeedportlet session=falsegt

lt taglib uri=WEB-INFtldportlettld prefix=portletAPI gt

- 42 -

ltportletAPIinitgt

ltp class=wpsPortletHeadgtltportletAPItext key=available_bookmarks

bundle=nlsTextgtAvailable BookmarksltportletAPItextgtltpgt

lt

PortletData prefs = portletRequestgetData()

Enumeration e = prefsgetAttributeNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltportletAPItext key=no_bookmarks bundle=nlsTextgtNo

bookmarksltportletAPItextgtltpgt

lt

else

gt

ltp class=wpsIndentMediumgt

lt

while (ehasMoreElements())

String name = (String)enextElement()

String value = (String)prefsgetAttribute(name)

gt

lta href=lt=valuegt target=_blankgtlt=namegtltagtltbr gt

lt

gt

ltpgt

The View JSP first call portletAPIinit 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

lt page contentType=texthtml import=javautil

comibmwpssampleswp5orgapachejetspeedportlet session=falsegt

lt taglib uri=WEB-INFtldportlettld prefix=portletAPI gt

ltjspuseBean id=addURI class=javalangString scope=request gt

ltjspuseBean id=cancelURI class=javalangString scope=request gt

ltportletAPIinitgt

lth4gtltportletAPItext key=available_bookmarks bundle=nlsTextgtAvailable

BookmarksltportletAPItextgtlth4gt

lttable class=wpsTablegt

lttr class=wpsTableRowgt

ltth class=portlet-table-headergtltportletAPItext key=name bundle=nlsTextgtltthgt

ltth class=portlet-table-headergtltportletAPItext key=url bundle=nlsTextgtltthgt

lttdgtlttdgt

lttrgt

lt

PortletData prefs = portletRequestgetData()

Enumeration e = prefsgetAttributeNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltportletAPItext key=no_bookmarks bundle=nlsTextgtNo

bookmarksltportletAPItextgtltpgt

lt

else

while (ehasMoreElements())

- 44 -

String name = (String)enextElement()

String value = (String)prefsgetAttribute(name)

gt

lttr class=wpsTableRowgt

lttdgt lt=namegt lttdgt

lttdgt lt=valuegt lttdgt

lttdgt lta href=ltportletAPIcreateURIgtltportletAPIURIAction

name=removeURIgtltportletAPIURIParameter name=remove

value=lt=namegtgtltportletAPIcreateURIgtgt

(ltportletAPItext key=delete bundle=nlsTextgt)ltagt

lttdgt

lttrgt

lt

gt

ltform action=lt=addURIgt method=POSTgt

lttr class=wpsTableRowgt

lttdgtltinput name=ltportletAPIencodeNamespace value=namegt type=text

class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=ltportletAPIencodeNamespace value=valuegt type=text

class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=ltportletAPIencodeNamespace value=addgt type=submit

value=ltportletAPItext key=add bundle=nlsTextgt class=portlet-form-buttongtlttdgt

lttrgt

ltformgt

lttablegt

- 45 -

ltform action=lt=cancelURIgt method=postgt

ltinput name=ltportletAPIencodeNamespace value=cancelgt type=submit

value=ltportletAPItext key=cancel bundle=nlsTextgt class=portlet-form-buttongt

ltformgt

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 ldquodeleterdquo button for which an URL with the action ldquoremoveURIrdquo 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 ldquocancelrdquo button from the request

64 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

lt page import=javaxportlet javautil session=falsegt

lt taglib uri=httpjavasuncomportlet prefix=portletAPI gt

lt taglib prefix=fmt uri=httpjavasuncomjstlfmt gt

ltportletAPIdefineObjects gt

ltfmtsetBundle basename=nlsTextgt

lt

ResourceBundle myText = ResourceBundlegetBundle(nlsText requestgetLocale())

gt

lth4gtltfmtmessage key=available_bookmarksgtlth4gt

lt

PortletPreferences prefs = renderRequestgetPreferences()

Enumeration e = prefsgetNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltfmtmessage key=no_bookmarksgtltpgt

- 46 -

lt

else

gt

ltpgt

lt

while (ehasMoreElements())

String name = (String)enextElement()

String value = prefsgetValue(namelt+myTextgetString(undefined)+gt)

gt

lta href=lt=valuegt target=_blankgtlt=namegtltagtltbr gt

lt

gt

ltpgt

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 fmtmessage 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

lt page import=javaxportlet javautil session=false gt

lt taglib uri=httpjavasuncomportlet prefix=portletAPI gt

lt taglib prefix=fmt uri=httpjavasuncomjstlfmt gt

ltjspuseBean id=addUrl scope=request class=javalangString gt

ltjspuseBean id=cancelUrl scope=request class=javalangString gt

- 47 -

ltportletAPIdefineObjectsgt

lt

ResourceBundle myText = ResourceBundlegetBundle(nlsText requestgetLocale())

gt

ltfmtsetBundle basename=nlsTextgt

lth4gtltfmtmessage key=available_bookmarksgtlth4gt

lttable class=wpsTablegt

lttr class=wpsTableRowgt

ltth class=wpsTableHeadgtltfmtmessage key=namegtltthgt

ltth class=wpsTableHeadgtltfmtmessage key=urlgtltthgt

lttdgtlttdgt

lttrgt

lt

PortletPreferences prefs = renderRequestgetPreferences()

Enumeration e = prefsgetNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltfmtmessage key=no_bookmarksgtltpgt

lt

else

while (ehasMoreElements())

String name = (String)enextElement()

String value = prefsgetValue(namelt+myTextgetString(undefined)+gt)

gt

lttr class=wpsTableRowgt

lttdgt lt=namegt lttdgt

lttdgt lt=valuegt lttdgt

- 48 -

lttdgt ltportletAPIactionURL var=removeUrlgt

ltportletAPIparam name=remove value=lt=namegtgt

ltportletAPIactionURLgt

lta href=lt=removeUrltoString()gtgt(ltfmtmessage key=deletegt)ltagt

lttdgt

lttrgt

lt

gt

ltform action=lt=addUrlgt method=POSTgt

lttr class=wpsTableRowgt

lttdgtltinput name=name type=text class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=value type=text class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=add type=submit value=ltfmtmessage key=addgt

class=portlet-form-buttongtlttdgt

lttrgt

ltformgt

lttablegt

ltform action=lt=cancelUrlgt method=postgt

ltinput name=cancel type=submit value=ltfmtmessage key=cancelgt class=portlet-

form-buttongt

ltformgt

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 14 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 -

- 51 -

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 (eg eventing) the IBM Portlet API still needs to be used Trademarks bull IBM and WebSphere are trademarks or registered trademarks of IBM Corporation in

the United States other countries or both bull 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 bull Other company product and service names may be trademarks or service marks of

others IBM copyright and trademark information httpwwwibmcomlegalcopytradephtml

  • Introduction
  • JSR 168 and the Java Community Process
  • Comparing concepts
    • Basic concepts
      • Portal
      • Portal page
      • Portlet
      • Portlet Container
        • Concepts that are the same
          • Portlet mode
          • Window state
          • Portlet life cycle and request processing
          • URL encoding
          • Include servletsJSPs
          • Portlet application packaging
          • Expiration-based caching
            • Concepts that differ
              • Portlet application entity
              • Portlet entity
              • Action and Render Request Response objects
              • Window concept
              • Portlet API does not extend servlet API
              • TAG libraries
                • Concepts new in the JSR 168
                  • Render parameter
                  • Extension mechanisms
                    • Custom window states
                    • Custom portlet modes
                    • Custom user info
                    • Request Response properties
                      • Web application session scope
                      • Reuse of the HttpSession listeners
                      • J2EE role support
                      • Resource bundles
                      • Multiple response content types
                      • Redirect in action
                      • Preference validator
                      • Portal context
                      • Localization support
                        • Concepts missing in the JSR 168
                          • Eventing
                          • Additional lifecycle events
                          • Property broker
                          • Portlet Menus
                          • Portlet Services
                          • Invalidation-based caching
                            • Alignment with WSRP
                              • Outlook for the next version of the JSR 168
                              • Guidelines for programming IBM Portlet API portlets
                                • Similar Functionality
                                  • Basic programming model
                                  • Portlet private session
                                  • User profile information
                                  • Persistent data
                                  • Portlet modes and window states
                                  • Expiration-based caching
                                    • Slightly different functionality
                                      • Sharing of data between portlets
                                      • Session listeners
                                        • New JSR 168 functionality
                                          • Navigational state (render parameters)
                                            • Pitfalls
                                              • Request response objects for action and render phase
                                              • Include search path
                                              • Form parameter encoding
                                              • Title setting
                                                  • Examples
                                                    • IBM Portlet API Portlet Code
                                                    • JSR 168 Portlet Code
                                                    • IBM Portlet API JSPs
                                                    • JSR 168 JSPs
                                                      • Summary
Page 30: Difference Bw Jsr168 and Ibm

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

51 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

511 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

bull portlets are components Portlets are components that implement a specific function Different functions should be distributed to different portlets

bull 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

bull 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

512 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 HttpServletRequestgetSession() call in the JSPs called via the IBM Portlet API needs to be replaced when moving to JSR 168 portlets by the RenderRequestgetPortletSession() 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 HttpServletRequestgetSession() will get the HttpSession and therefore need to access the portlet session via the RenderRequest

513 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

514 Persistent data

Portlets can store customization and personalization data persistently Customization data are related to the portlet and are valid for all users (eg 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 (eg 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

515 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

516 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

52 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

521 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 351 353) 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

522 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

53 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 -

531 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

bull no support of the back button in the browser bull current state of the portlet is not bookmarkable bull 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 bull 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

54 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

541 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 -

542 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

543 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

544 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 wersquoll 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

Figure 7After clicking on the Edit mode button the portlet renders the Edit view shown in

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

Figure 8

After we press the ldquoAddrdquo 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

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

bull use JSPs for rendering the output bull customize the portlet output taking user specific data into account bull 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

61 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 comibmwpssampleswp5

import javaio

import javautil

import orgapachejetspeedportlet

import orgapachejetspeedportletevent

public class IbmBookmark extends PortletAdapter implements ActionListener

public void init(PortletConfig portletConfig) throws UnavailableException

superinit(portletConfig)

- 36 -

public void doView(PortletRequest request PortletResponse response)

throws PortletException IOException

String jspName = thisgetPortletConfig()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 = responsecreateReturnURI()

addURIaddAction(add)

requestsetAttribute(addURI addURItoString())

PortletURI cancelURI = responsecreateReturnURI()

requestsetAttribute(cancelURI cancelURItoString())

String jspName = thisgetPortletConfig()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 ldquocancelrdquo and ldquoaddrdquo URLs are created inside the portlet and attached to the request before including the Edit JSP Both URLs are from type ldquoReturnURIrdquo 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 = eventgetRequest()

String action = eventgetActionString()

PortletLog log = getPortletLog()

if ( action=null )

try

if (actionequals(removeURI))

String removeName = requestgetParameter(remove)

PortletData portData = requestgetData()

portDataremoveAttribute(removeName)

portDatastore()

if (actionequals(add))

PortletData portData = requestgetData()

String name = requestgetParameter(name)

String value = requestgetParameter(value)

portDatasetAttribute(name value)

portDatastore()

catch ( AccessDeniedException ade )

logerror(AccessDeniedException occured when adding or deleting a bookmark)

catch ( IOException ioe )

logerror(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 ldquoaddrdquo or ldquodeleterdquo 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 ldquoaddrdquo or ldquoremoveURIrdquo If the user has clicked on the ldquoremoverdquo button the corresponding link is removed from the portlet data whereas if ldquoaddrdquo was clicked the data entered by the user is added to the portlet data

62 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 comibmwpssamplesjsr

import javaio

import javaxportlet

public class Bookmark extends GenericPortlet

public void init(PortletConfig config) throws PortletException

superinit(config)

public void doView(RenderRequest request RenderResponse response)

throws PortletException IOException

responsesetContentType(texthtml)

String jspName = getPortletConfig()getInitParameter(jspView)

PortletRequestDispatcher rd = getPortletContext()getRequestDispatcher(jspName)

rdinclude(requestresponse)

- 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

responsesetContentType(texthtml)

PortletURL addUrl = responsecreateActionURL()

addUrlsetPortletMode(PortletModeVIEW)

addUrlsetParameter(addadd)

requestsetAttribute(addUrladdUrltoString())

PortletURL cancelUrl = responsecreateRenderURL()

cancelUrlsetPortletMode(PortletModeVIEW)

requestsetAttribute(cancelUrlcancelUrltoString())

String jspName = getPortletConfig()getInitParameter(jspEdit)

PortletRequestDispatcher rd = getPortletContext()getRequestDispatcher(jspName)

rdinclude(requestresponse)

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 ldquoaddrdquo button URL an action URL is created as we need to store the user input of the add form persistently For the ldquocancelrdquo 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 = requestgetParameter(remove)

if (removeName = null)

PortletPreferences prefs = requestgetPreferences()

prefsreset(removeName)

prefsstore()

String add = requestgetParameter(add)

if (add = null)

PortletPreferences prefs = requestgetPreferences()

String name = requestgetParameter(name)

String value = requestgetParameter(value)

prefssetValue(name value)

prefsstore()

catch ( IOException ioe )

getPortletContextlog(An IO error occured when trying to remove a bookmark)

catch ( PortletException pe )

getPortletContextlog(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

bull 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

bull 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

bull Persistent portlet data The JSR 168 persistent data PortletPreferences have an API similar to the JDK 14 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

bull 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

63 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

lt page contentType=texthtml import=javautil comibmwpssampleswp5

orgapachejetspeedportlet session=falsegt

lt taglib uri=WEB-INFtldportlettld prefix=portletAPI gt

- 42 -

ltportletAPIinitgt

ltp class=wpsPortletHeadgtltportletAPItext key=available_bookmarks

bundle=nlsTextgtAvailable BookmarksltportletAPItextgtltpgt

lt

PortletData prefs = portletRequestgetData()

Enumeration e = prefsgetAttributeNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltportletAPItext key=no_bookmarks bundle=nlsTextgtNo

bookmarksltportletAPItextgtltpgt

lt

else

gt

ltp class=wpsIndentMediumgt

lt

while (ehasMoreElements())

String name = (String)enextElement()

String value = (String)prefsgetAttribute(name)

gt

lta href=lt=valuegt target=_blankgtlt=namegtltagtltbr gt

lt

gt

ltpgt

The View JSP first call portletAPIinit 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

lt page contentType=texthtml import=javautil

comibmwpssampleswp5orgapachejetspeedportlet session=falsegt

lt taglib uri=WEB-INFtldportlettld prefix=portletAPI gt

ltjspuseBean id=addURI class=javalangString scope=request gt

ltjspuseBean id=cancelURI class=javalangString scope=request gt

ltportletAPIinitgt

lth4gtltportletAPItext key=available_bookmarks bundle=nlsTextgtAvailable

BookmarksltportletAPItextgtlth4gt

lttable class=wpsTablegt

lttr class=wpsTableRowgt

ltth class=portlet-table-headergtltportletAPItext key=name bundle=nlsTextgtltthgt

ltth class=portlet-table-headergtltportletAPItext key=url bundle=nlsTextgtltthgt

lttdgtlttdgt

lttrgt

lt

PortletData prefs = portletRequestgetData()

Enumeration e = prefsgetAttributeNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltportletAPItext key=no_bookmarks bundle=nlsTextgtNo

bookmarksltportletAPItextgtltpgt

lt

else

while (ehasMoreElements())

- 44 -

String name = (String)enextElement()

String value = (String)prefsgetAttribute(name)

gt

lttr class=wpsTableRowgt

lttdgt lt=namegt lttdgt

lttdgt lt=valuegt lttdgt

lttdgt lta href=ltportletAPIcreateURIgtltportletAPIURIAction

name=removeURIgtltportletAPIURIParameter name=remove

value=lt=namegtgtltportletAPIcreateURIgtgt

(ltportletAPItext key=delete bundle=nlsTextgt)ltagt

lttdgt

lttrgt

lt

gt

ltform action=lt=addURIgt method=POSTgt

lttr class=wpsTableRowgt

lttdgtltinput name=ltportletAPIencodeNamespace value=namegt type=text

class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=ltportletAPIencodeNamespace value=valuegt type=text

class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=ltportletAPIencodeNamespace value=addgt type=submit

value=ltportletAPItext key=add bundle=nlsTextgt class=portlet-form-buttongtlttdgt

lttrgt

ltformgt

lttablegt

- 45 -

ltform action=lt=cancelURIgt method=postgt

ltinput name=ltportletAPIencodeNamespace value=cancelgt type=submit

value=ltportletAPItext key=cancel bundle=nlsTextgt class=portlet-form-buttongt

ltformgt

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 ldquodeleterdquo button for which an URL with the action ldquoremoveURIrdquo 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 ldquocancelrdquo button from the request

64 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

lt page import=javaxportlet javautil session=falsegt

lt taglib uri=httpjavasuncomportlet prefix=portletAPI gt

lt taglib prefix=fmt uri=httpjavasuncomjstlfmt gt

ltportletAPIdefineObjects gt

ltfmtsetBundle basename=nlsTextgt

lt

ResourceBundle myText = ResourceBundlegetBundle(nlsText requestgetLocale())

gt

lth4gtltfmtmessage key=available_bookmarksgtlth4gt

lt

PortletPreferences prefs = renderRequestgetPreferences()

Enumeration e = prefsgetNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltfmtmessage key=no_bookmarksgtltpgt

- 46 -

lt

else

gt

ltpgt

lt

while (ehasMoreElements())

String name = (String)enextElement()

String value = prefsgetValue(namelt+myTextgetString(undefined)+gt)

gt

lta href=lt=valuegt target=_blankgtlt=namegtltagtltbr gt

lt

gt

ltpgt

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 fmtmessage 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

lt page import=javaxportlet javautil session=false gt

lt taglib uri=httpjavasuncomportlet prefix=portletAPI gt

lt taglib prefix=fmt uri=httpjavasuncomjstlfmt gt

ltjspuseBean id=addUrl scope=request class=javalangString gt

ltjspuseBean id=cancelUrl scope=request class=javalangString gt

- 47 -

ltportletAPIdefineObjectsgt

lt

ResourceBundle myText = ResourceBundlegetBundle(nlsText requestgetLocale())

gt

ltfmtsetBundle basename=nlsTextgt

lth4gtltfmtmessage key=available_bookmarksgtlth4gt

lttable class=wpsTablegt

lttr class=wpsTableRowgt

ltth class=wpsTableHeadgtltfmtmessage key=namegtltthgt

ltth class=wpsTableHeadgtltfmtmessage key=urlgtltthgt

lttdgtlttdgt

lttrgt

lt

PortletPreferences prefs = renderRequestgetPreferences()

Enumeration e = prefsgetNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltfmtmessage key=no_bookmarksgtltpgt

lt

else

while (ehasMoreElements())

String name = (String)enextElement()

String value = prefsgetValue(namelt+myTextgetString(undefined)+gt)

gt

lttr class=wpsTableRowgt

lttdgt lt=namegt lttdgt

lttdgt lt=valuegt lttdgt

- 48 -

lttdgt ltportletAPIactionURL var=removeUrlgt

ltportletAPIparam name=remove value=lt=namegtgt

ltportletAPIactionURLgt

lta href=lt=removeUrltoString()gtgt(ltfmtmessage key=deletegt)ltagt

lttdgt

lttrgt

lt

gt

ltform action=lt=addUrlgt method=POSTgt

lttr class=wpsTableRowgt

lttdgtltinput name=name type=text class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=value type=text class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=add type=submit value=ltfmtmessage key=addgt

class=portlet-form-buttongtlttdgt

lttrgt

ltformgt

lttablegt

ltform action=lt=cancelUrlgt method=postgt

ltinput name=cancel type=submit value=ltfmtmessage key=cancelgt class=portlet-

form-buttongt

ltformgt

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 14 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 -

- 51 -

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 (eg eventing) the IBM Portlet API still needs to be used Trademarks bull IBM and WebSphere are trademarks or registered trademarks of IBM Corporation in

the United States other countries or both bull 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 bull Other company product and service names may be trademarks or service marks of

others IBM copyright and trademark information httpwwwibmcomlegalcopytradephtml

  • Introduction
  • JSR 168 and the Java Community Process
  • Comparing concepts
    • Basic concepts
      • Portal
      • Portal page
      • Portlet
      • Portlet Container
        • Concepts that are the same
          • Portlet mode
          • Window state
          • Portlet life cycle and request processing
          • URL encoding
          • Include servletsJSPs
          • Portlet application packaging
          • Expiration-based caching
            • Concepts that differ
              • Portlet application entity
              • Portlet entity
              • Action and Render Request Response objects
              • Window concept
              • Portlet API does not extend servlet API
              • TAG libraries
                • Concepts new in the JSR 168
                  • Render parameter
                  • Extension mechanisms
                    • Custom window states
                    • Custom portlet modes
                    • Custom user info
                    • Request Response properties
                      • Web application session scope
                      • Reuse of the HttpSession listeners
                      • J2EE role support
                      • Resource bundles
                      • Multiple response content types
                      • Redirect in action
                      • Preference validator
                      • Portal context
                      • Localization support
                        • Concepts missing in the JSR 168
                          • Eventing
                          • Additional lifecycle events
                          • Property broker
                          • Portlet Menus
                          • Portlet Services
                          • Invalidation-based caching
                            • Alignment with WSRP
                              • Outlook for the next version of the JSR 168
                              • Guidelines for programming IBM Portlet API portlets
                                • Similar Functionality
                                  • Basic programming model
                                  • Portlet private session
                                  • User profile information
                                  • Persistent data
                                  • Portlet modes and window states
                                  • Expiration-based caching
                                    • Slightly different functionality
                                      • Sharing of data between portlets
                                      • Session listeners
                                        • New JSR 168 functionality
                                          • Navigational state (render parameters)
                                            • Pitfalls
                                              • Request response objects for action and render phase
                                              • Include search path
                                              • Form parameter encoding
                                              • Title setting
                                                  • Examples
                                                    • IBM Portlet API Portlet Code
                                                    • JSR 168 Portlet Code
                                                    • IBM Portlet API JSPs
                                                    • JSR 168 JSPs
                                                      • Summary
Page 31: Difference Bw Jsr168 and Ibm

For included JSPs that access the session the HttpServletRequestgetSession() call in the JSPs called via the IBM Portlet API needs to be replaced when moving to JSR 168 portlets by the RenderRequestgetPortletSession() 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 HttpServletRequestgetSession() will get the HttpSession and therefore need to access the portlet session via the RenderRequest

513 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

514 Persistent data

Portlets can store customization and personalization data persistently Customization data are related to the portlet and are valid for all users (eg 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 (eg 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

515 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

516 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

52 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

521 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 351 353) 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

522 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

53 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 -

531 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

bull no support of the back button in the browser bull current state of the portlet is not bookmarkable bull 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 bull 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

54 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

541 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 -

542 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

543 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

544 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 wersquoll 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

Figure 7After clicking on the Edit mode button the portlet renders the Edit view shown in

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

Figure 8

After we press the ldquoAddrdquo 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

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

bull use JSPs for rendering the output bull customize the portlet output taking user specific data into account bull 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

61 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 comibmwpssampleswp5

import javaio

import javautil

import orgapachejetspeedportlet

import orgapachejetspeedportletevent

public class IbmBookmark extends PortletAdapter implements ActionListener

public void init(PortletConfig portletConfig) throws UnavailableException

superinit(portletConfig)

- 36 -

public void doView(PortletRequest request PortletResponse response)

throws PortletException IOException

String jspName = thisgetPortletConfig()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 = responsecreateReturnURI()

addURIaddAction(add)

requestsetAttribute(addURI addURItoString())

PortletURI cancelURI = responsecreateReturnURI()

requestsetAttribute(cancelURI cancelURItoString())

String jspName = thisgetPortletConfig()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 ldquocancelrdquo and ldquoaddrdquo URLs are created inside the portlet and attached to the request before including the Edit JSP Both URLs are from type ldquoReturnURIrdquo 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 = eventgetRequest()

String action = eventgetActionString()

PortletLog log = getPortletLog()

if ( action=null )

try

if (actionequals(removeURI))

String removeName = requestgetParameter(remove)

PortletData portData = requestgetData()

portDataremoveAttribute(removeName)

portDatastore()

if (actionequals(add))

PortletData portData = requestgetData()

String name = requestgetParameter(name)

String value = requestgetParameter(value)

portDatasetAttribute(name value)

portDatastore()

catch ( AccessDeniedException ade )

logerror(AccessDeniedException occured when adding or deleting a bookmark)

catch ( IOException ioe )

logerror(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 ldquoaddrdquo or ldquodeleterdquo 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 ldquoaddrdquo or ldquoremoveURIrdquo If the user has clicked on the ldquoremoverdquo button the corresponding link is removed from the portlet data whereas if ldquoaddrdquo was clicked the data entered by the user is added to the portlet data

62 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 comibmwpssamplesjsr

import javaio

import javaxportlet

public class Bookmark extends GenericPortlet

public void init(PortletConfig config) throws PortletException

superinit(config)

public void doView(RenderRequest request RenderResponse response)

throws PortletException IOException

responsesetContentType(texthtml)

String jspName = getPortletConfig()getInitParameter(jspView)

PortletRequestDispatcher rd = getPortletContext()getRequestDispatcher(jspName)

rdinclude(requestresponse)

- 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

responsesetContentType(texthtml)

PortletURL addUrl = responsecreateActionURL()

addUrlsetPortletMode(PortletModeVIEW)

addUrlsetParameter(addadd)

requestsetAttribute(addUrladdUrltoString())

PortletURL cancelUrl = responsecreateRenderURL()

cancelUrlsetPortletMode(PortletModeVIEW)

requestsetAttribute(cancelUrlcancelUrltoString())

String jspName = getPortletConfig()getInitParameter(jspEdit)

PortletRequestDispatcher rd = getPortletContext()getRequestDispatcher(jspName)

rdinclude(requestresponse)

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 ldquoaddrdquo button URL an action URL is created as we need to store the user input of the add form persistently For the ldquocancelrdquo 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 = requestgetParameter(remove)

if (removeName = null)

PortletPreferences prefs = requestgetPreferences()

prefsreset(removeName)

prefsstore()

String add = requestgetParameter(add)

if (add = null)

PortletPreferences prefs = requestgetPreferences()

String name = requestgetParameter(name)

String value = requestgetParameter(value)

prefssetValue(name value)

prefsstore()

catch ( IOException ioe )

getPortletContextlog(An IO error occured when trying to remove a bookmark)

catch ( PortletException pe )

getPortletContextlog(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

bull 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

bull 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

bull Persistent portlet data The JSR 168 persistent data PortletPreferences have an API similar to the JDK 14 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

bull 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

63 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

lt page contentType=texthtml import=javautil comibmwpssampleswp5

orgapachejetspeedportlet session=falsegt

lt taglib uri=WEB-INFtldportlettld prefix=portletAPI gt

- 42 -

ltportletAPIinitgt

ltp class=wpsPortletHeadgtltportletAPItext key=available_bookmarks

bundle=nlsTextgtAvailable BookmarksltportletAPItextgtltpgt

lt

PortletData prefs = portletRequestgetData()

Enumeration e = prefsgetAttributeNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltportletAPItext key=no_bookmarks bundle=nlsTextgtNo

bookmarksltportletAPItextgtltpgt

lt

else

gt

ltp class=wpsIndentMediumgt

lt

while (ehasMoreElements())

String name = (String)enextElement()

String value = (String)prefsgetAttribute(name)

gt

lta href=lt=valuegt target=_blankgtlt=namegtltagtltbr gt

lt

gt

ltpgt

The View JSP first call portletAPIinit 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

lt page contentType=texthtml import=javautil

comibmwpssampleswp5orgapachejetspeedportlet session=falsegt

lt taglib uri=WEB-INFtldportlettld prefix=portletAPI gt

ltjspuseBean id=addURI class=javalangString scope=request gt

ltjspuseBean id=cancelURI class=javalangString scope=request gt

ltportletAPIinitgt

lth4gtltportletAPItext key=available_bookmarks bundle=nlsTextgtAvailable

BookmarksltportletAPItextgtlth4gt

lttable class=wpsTablegt

lttr class=wpsTableRowgt

ltth class=portlet-table-headergtltportletAPItext key=name bundle=nlsTextgtltthgt

ltth class=portlet-table-headergtltportletAPItext key=url bundle=nlsTextgtltthgt

lttdgtlttdgt

lttrgt

lt

PortletData prefs = portletRequestgetData()

Enumeration e = prefsgetAttributeNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltportletAPItext key=no_bookmarks bundle=nlsTextgtNo

bookmarksltportletAPItextgtltpgt

lt

else

while (ehasMoreElements())

- 44 -

String name = (String)enextElement()

String value = (String)prefsgetAttribute(name)

gt

lttr class=wpsTableRowgt

lttdgt lt=namegt lttdgt

lttdgt lt=valuegt lttdgt

lttdgt lta href=ltportletAPIcreateURIgtltportletAPIURIAction

name=removeURIgtltportletAPIURIParameter name=remove

value=lt=namegtgtltportletAPIcreateURIgtgt

(ltportletAPItext key=delete bundle=nlsTextgt)ltagt

lttdgt

lttrgt

lt

gt

ltform action=lt=addURIgt method=POSTgt

lttr class=wpsTableRowgt

lttdgtltinput name=ltportletAPIencodeNamespace value=namegt type=text

class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=ltportletAPIencodeNamespace value=valuegt type=text

class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=ltportletAPIencodeNamespace value=addgt type=submit

value=ltportletAPItext key=add bundle=nlsTextgt class=portlet-form-buttongtlttdgt

lttrgt

ltformgt

lttablegt

- 45 -

ltform action=lt=cancelURIgt method=postgt

ltinput name=ltportletAPIencodeNamespace value=cancelgt type=submit

value=ltportletAPItext key=cancel bundle=nlsTextgt class=portlet-form-buttongt

ltformgt

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 ldquodeleterdquo button for which an URL with the action ldquoremoveURIrdquo 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 ldquocancelrdquo button from the request

64 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

lt page import=javaxportlet javautil session=falsegt

lt taglib uri=httpjavasuncomportlet prefix=portletAPI gt

lt taglib prefix=fmt uri=httpjavasuncomjstlfmt gt

ltportletAPIdefineObjects gt

ltfmtsetBundle basename=nlsTextgt

lt

ResourceBundle myText = ResourceBundlegetBundle(nlsText requestgetLocale())

gt

lth4gtltfmtmessage key=available_bookmarksgtlth4gt

lt

PortletPreferences prefs = renderRequestgetPreferences()

Enumeration e = prefsgetNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltfmtmessage key=no_bookmarksgtltpgt

- 46 -

lt

else

gt

ltpgt

lt

while (ehasMoreElements())

String name = (String)enextElement()

String value = prefsgetValue(namelt+myTextgetString(undefined)+gt)

gt

lta href=lt=valuegt target=_blankgtlt=namegtltagtltbr gt

lt

gt

ltpgt

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 fmtmessage 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

lt page import=javaxportlet javautil session=false gt

lt taglib uri=httpjavasuncomportlet prefix=portletAPI gt

lt taglib prefix=fmt uri=httpjavasuncomjstlfmt gt

ltjspuseBean id=addUrl scope=request class=javalangString gt

ltjspuseBean id=cancelUrl scope=request class=javalangString gt

- 47 -

ltportletAPIdefineObjectsgt

lt

ResourceBundle myText = ResourceBundlegetBundle(nlsText requestgetLocale())

gt

ltfmtsetBundle basename=nlsTextgt

lth4gtltfmtmessage key=available_bookmarksgtlth4gt

lttable class=wpsTablegt

lttr class=wpsTableRowgt

ltth class=wpsTableHeadgtltfmtmessage key=namegtltthgt

ltth class=wpsTableHeadgtltfmtmessage key=urlgtltthgt

lttdgtlttdgt

lttrgt

lt

PortletPreferences prefs = renderRequestgetPreferences()

Enumeration e = prefsgetNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltfmtmessage key=no_bookmarksgtltpgt

lt

else

while (ehasMoreElements())

String name = (String)enextElement()

String value = prefsgetValue(namelt+myTextgetString(undefined)+gt)

gt

lttr class=wpsTableRowgt

lttdgt lt=namegt lttdgt

lttdgt lt=valuegt lttdgt

- 48 -

lttdgt ltportletAPIactionURL var=removeUrlgt

ltportletAPIparam name=remove value=lt=namegtgt

ltportletAPIactionURLgt

lta href=lt=removeUrltoString()gtgt(ltfmtmessage key=deletegt)ltagt

lttdgt

lttrgt

lt

gt

ltform action=lt=addUrlgt method=POSTgt

lttr class=wpsTableRowgt

lttdgtltinput name=name type=text class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=value type=text class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=add type=submit value=ltfmtmessage key=addgt

class=portlet-form-buttongtlttdgt

lttrgt

ltformgt

lttablegt

ltform action=lt=cancelUrlgt method=postgt

ltinput name=cancel type=submit value=ltfmtmessage key=cancelgt class=portlet-

form-buttongt

ltformgt

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 14 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 -

- 51 -

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 (eg eventing) the IBM Portlet API still needs to be used Trademarks bull IBM and WebSphere are trademarks or registered trademarks of IBM Corporation in

the United States other countries or both bull 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 bull Other company product and service names may be trademarks or service marks of

others IBM copyright and trademark information httpwwwibmcomlegalcopytradephtml

  • Introduction
  • JSR 168 and the Java Community Process
  • Comparing concepts
    • Basic concepts
      • Portal
      • Portal page
      • Portlet
      • Portlet Container
        • Concepts that are the same
          • Portlet mode
          • Window state
          • Portlet life cycle and request processing
          • URL encoding
          • Include servletsJSPs
          • Portlet application packaging
          • Expiration-based caching
            • Concepts that differ
              • Portlet application entity
              • Portlet entity
              • Action and Render Request Response objects
              • Window concept
              • Portlet API does not extend servlet API
              • TAG libraries
                • Concepts new in the JSR 168
                  • Render parameter
                  • Extension mechanisms
                    • Custom window states
                    • Custom portlet modes
                    • Custom user info
                    • Request Response properties
                      • Web application session scope
                      • Reuse of the HttpSession listeners
                      • J2EE role support
                      • Resource bundles
                      • Multiple response content types
                      • Redirect in action
                      • Preference validator
                      • Portal context
                      • Localization support
                        • Concepts missing in the JSR 168
                          • Eventing
                          • Additional lifecycle events
                          • Property broker
                          • Portlet Menus
                          • Portlet Services
                          • Invalidation-based caching
                            • Alignment with WSRP
                              • Outlook for the next version of the JSR 168
                              • Guidelines for programming IBM Portlet API portlets
                                • Similar Functionality
                                  • Basic programming model
                                  • Portlet private session
                                  • User profile information
                                  • Persistent data
                                  • Portlet modes and window states
                                  • Expiration-based caching
                                    • Slightly different functionality
                                      • Sharing of data between portlets
                                      • Session listeners
                                        • New JSR 168 functionality
                                          • Navigational state (render parameters)
                                            • Pitfalls
                                              • Request response objects for action and render phase
                                              • Include search path
                                              • Form parameter encoding
                                              • Title setting
                                                  • Examples
                                                    • IBM Portlet API Portlet Code
                                                    • JSR 168 Portlet Code
                                                    • IBM Portlet API JSPs
                                                    • JSR 168 JSPs
                                                      • Summary
Page 32: Difference Bw Jsr168 and Ibm

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

516 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

52 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

521 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 351 353) 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

522 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

53 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 -

531 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

bull no support of the back button in the browser bull current state of the portlet is not bookmarkable bull 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 bull 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

54 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

541 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 -

542 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

543 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

544 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 wersquoll 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

Figure 7After clicking on the Edit mode button the portlet renders the Edit view shown in

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

Figure 8

After we press the ldquoAddrdquo 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

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

bull use JSPs for rendering the output bull customize the portlet output taking user specific data into account bull 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

61 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 comibmwpssampleswp5

import javaio

import javautil

import orgapachejetspeedportlet

import orgapachejetspeedportletevent

public class IbmBookmark extends PortletAdapter implements ActionListener

public void init(PortletConfig portletConfig) throws UnavailableException

superinit(portletConfig)

- 36 -

public void doView(PortletRequest request PortletResponse response)

throws PortletException IOException

String jspName = thisgetPortletConfig()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 = responsecreateReturnURI()

addURIaddAction(add)

requestsetAttribute(addURI addURItoString())

PortletURI cancelURI = responsecreateReturnURI()

requestsetAttribute(cancelURI cancelURItoString())

String jspName = thisgetPortletConfig()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 ldquocancelrdquo and ldquoaddrdquo URLs are created inside the portlet and attached to the request before including the Edit JSP Both URLs are from type ldquoReturnURIrdquo 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 = eventgetRequest()

String action = eventgetActionString()

PortletLog log = getPortletLog()

if ( action=null )

try

if (actionequals(removeURI))

String removeName = requestgetParameter(remove)

PortletData portData = requestgetData()

portDataremoveAttribute(removeName)

portDatastore()

if (actionequals(add))

PortletData portData = requestgetData()

String name = requestgetParameter(name)

String value = requestgetParameter(value)

portDatasetAttribute(name value)

portDatastore()

catch ( AccessDeniedException ade )

logerror(AccessDeniedException occured when adding or deleting a bookmark)

catch ( IOException ioe )

logerror(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 ldquoaddrdquo or ldquodeleterdquo 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 ldquoaddrdquo or ldquoremoveURIrdquo If the user has clicked on the ldquoremoverdquo button the corresponding link is removed from the portlet data whereas if ldquoaddrdquo was clicked the data entered by the user is added to the portlet data

62 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 comibmwpssamplesjsr

import javaio

import javaxportlet

public class Bookmark extends GenericPortlet

public void init(PortletConfig config) throws PortletException

superinit(config)

public void doView(RenderRequest request RenderResponse response)

throws PortletException IOException

responsesetContentType(texthtml)

String jspName = getPortletConfig()getInitParameter(jspView)

PortletRequestDispatcher rd = getPortletContext()getRequestDispatcher(jspName)

rdinclude(requestresponse)

- 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

responsesetContentType(texthtml)

PortletURL addUrl = responsecreateActionURL()

addUrlsetPortletMode(PortletModeVIEW)

addUrlsetParameter(addadd)

requestsetAttribute(addUrladdUrltoString())

PortletURL cancelUrl = responsecreateRenderURL()

cancelUrlsetPortletMode(PortletModeVIEW)

requestsetAttribute(cancelUrlcancelUrltoString())

String jspName = getPortletConfig()getInitParameter(jspEdit)

PortletRequestDispatcher rd = getPortletContext()getRequestDispatcher(jspName)

rdinclude(requestresponse)

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 ldquoaddrdquo button URL an action URL is created as we need to store the user input of the add form persistently For the ldquocancelrdquo 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 = requestgetParameter(remove)

if (removeName = null)

PortletPreferences prefs = requestgetPreferences()

prefsreset(removeName)

prefsstore()

String add = requestgetParameter(add)

if (add = null)

PortletPreferences prefs = requestgetPreferences()

String name = requestgetParameter(name)

String value = requestgetParameter(value)

prefssetValue(name value)

prefsstore()

catch ( IOException ioe )

getPortletContextlog(An IO error occured when trying to remove a bookmark)

catch ( PortletException pe )

getPortletContextlog(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

bull 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

bull 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

bull Persistent portlet data The JSR 168 persistent data PortletPreferences have an API similar to the JDK 14 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

bull 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

63 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

lt page contentType=texthtml import=javautil comibmwpssampleswp5

orgapachejetspeedportlet session=falsegt

lt taglib uri=WEB-INFtldportlettld prefix=portletAPI gt

- 42 -

ltportletAPIinitgt

ltp class=wpsPortletHeadgtltportletAPItext key=available_bookmarks

bundle=nlsTextgtAvailable BookmarksltportletAPItextgtltpgt

lt

PortletData prefs = portletRequestgetData()

Enumeration e = prefsgetAttributeNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltportletAPItext key=no_bookmarks bundle=nlsTextgtNo

bookmarksltportletAPItextgtltpgt

lt

else

gt

ltp class=wpsIndentMediumgt

lt

while (ehasMoreElements())

String name = (String)enextElement()

String value = (String)prefsgetAttribute(name)

gt

lta href=lt=valuegt target=_blankgtlt=namegtltagtltbr gt

lt

gt

ltpgt

The View JSP first call portletAPIinit 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

lt page contentType=texthtml import=javautil

comibmwpssampleswp5orgapachejetspeedportlet session=falsegt

lt taglib uri=WEB-INFtldportlettld prefix=portletAPI gt

ltjspuseBean id=addURI class=javalangString scope=request gt

ltjspuseBean id=cancelURI class=javalangString scope=request gt

ltportletAPIinitgt

lth4gtltportletAPItext key=available_bookmarks bundle=nlsTextgtAvailable

BookmarksltportletAPItextgtlth4gt

lttable class=wpsTablegt

lttr class=wpsTableRowgt

ltth class=portlet-table-headergtltportletAPItext key=name bundle=nlsTextgtltthgt

ltth class=portlet-table-headergtltportletAPItext key=url bundle=nlsTextgtltthgt

lttdgtlttdgt

lttrgt

lt

PortletData prefs = portletRequestgetData()

Enumeration e = prefsgetAttributeNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltportletAPItext key=no_bookmarks bundle=nlsTextgtNo

bookmarksltportletAPItextgtltpgt

lt

else

while (ehasMoreElements())

- 44 -

String name = (String)enextElement()

String value = (String)prefsgetAttribute(name)

gt

lttr class=wpsTableRowgt

lttdgt lt=namegt lttdgt

lttdgt lt=valuegt lttdgt

lttdgt lta href=ltportletAPIcreateURIgtltportletAPIURIAction

name=removeURIgtltportletAPIURIParameter name=remove

value=lt=namegtgtltportletAPIcreateURIgtgt

(ltportletAPItext key=delete bundle=nlsTextgt)ltagt

lttdgt

lttrgt

lt

gt

ltform action=lt=addURIgt method=POSTgt

lttr class=wpsTableRowgt

lttdgtltinput name=ltportletAPIencodeNamespace value=namegt type=text

class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=ltportletAPIencodeNamespace value=valuegt type=text

class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=ltportletAPIencodeNamespace value=addgt type=submit

value=ltportletAPItext key=add bundle=nlsTextgt class=portlet-form-buttongtlttdgt

lttrgt

ltformgt

lttablegt

- 45 -

ltform action=lt=cancelURIgt method=postgt

ltinput name=ltportletAPIencodeNamespace value=cancelgt type=submit

value=ltportletAPItext key=cancel bundle=nlsTextgt class=portlet-form-buttongt

ltformgt

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 ldquodeleterdquo button for which an URL with the action ldquoremoveURIrdquo 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 ldquocancelrdquo button from the request

64 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

lt page import=javaxportlet javautil session=falsegt

lt taglib uri=httpjavasuncomportlet prefix=portletAPI gt

lt taglib prefix=fmt uri=httpjavasuncomjstlfmt gt

ltportletAPIdefineObjects gt

ltfmtsetBundle basename=nlsTextgt

lt

ResourceBundle myText = ResourceBundlegetBundle(nlsText requestgetLocale())

gt

lth4gtltfmtmessage key=available_bookmarksgtlth4gt

lt

PortletPreferences prefs = renderRequestgetPreferences()

Enumeration e = prefsgetNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltfmtmessage key=no_bookmarksgtltpgt

- 46 -

lt

else

gt

ltpgt

lt

while (ehasMoreElements())

String name = (String)enextElement()

String value = prefsgetValue(namelt+myTextgetString(undefined)+gt)

gt

lta href=lt=valuegt target=_blankgtlt=namegtltagtltbr gt

lt

gt

ltpgt

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 fmtmessage 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

lt page import=javaxportlet javautil session=false gt

lt taglib uri=httpjavasuncomportlet prefix=portletAPI gt

lt taglib prefix=fmt uri=httpjavasuncomjstlfmt gt

ltjspuseBean id=addUrl scope=request class=javalangString gt

ltjspuseBean id=cancelUrl scope=request class=javalangString gt

- 47 -

ltportletAPIdefineObjectsgt

lt

ResourceBundle myText = ResourceBundlegetBundle(nlsText requestgetLocale())

gt

ltfmtsetBundle basename=nlsTextgt

lth4gtltfmtmessage key=available_bookmarksgtlth4gt

lttable class=wpsTablegt

lttr class=wpsTableRowgt

ltth class=wpsTableHeadgtltfmtmessage key=namegtltthgt

ltth class=wpsTableHeadgtltfmtmessage key=urlgtltthgt

lttdgtlttdgt

lttrgt

lt

PortletPreferences prefs = renderRequestgetPreferences()

Enumeration e = prefsgetNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltfmtmessage key=no_bookmarksgtltpgt

lt

else

while (ehasMoreElements())

String name = (String)enextElement()

String value = prefsgetValue(namelt+myTextgetString(undefined)+gt)

gt

lttr class=wpsTableRowgt

lttdgt lt=namegt lttdgt

lttdgt lt=valuegt lttdgt

- 48 -

lttdgt ltportletAPIactionURL var=removeUrlgt

ltportletAPIparam name=remove value=lt=namegtgt

ltportletAPIactionURLgt

lta href=lt=removeUrltoString()gtgt(ltfmtmessage key=deletegt)ltagt

lttdgt

lttrgt

lt

gt

ltform action=lt=addUrlgt method=POSTgt

lttr class=wpsTableRowgt

lttdgtltinput name=name type=text class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=value type=text class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=add type=submit value=ltfmtmessage key=addgt

class=portlet-form-buttongtlttdgt

lttrgt

ltformgt

lttablegt

ltform action=lt=cancelUrlgt method=postgt

ltinput name=cancel type=submit value=ltfmtmessage key=cancelgt class=portlet-

form-buttongt

ltformgt

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 14 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 -

- 51 -

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 (eg eventing) the IBM Portlet API still needs to be used Trademarks bull IBM and WebSphere are trademarks or registered trademarks of IBM Corporation in

the United States other countries or both bull 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 bull Other company product and service names may be trademarks or service marks of

others IBM copyright and trademark information httpwwwibmcomlegalcopytradephtml

  • Introduction
  • JSR 168 and the Java Community Process
  • Comparing concepts
    • Basic concepts
      • Portal
      • Portal page
      • Portlet
      • Portlet Container
        • Concepts that are the same
          • Portlet mode
          • Window state
          • Portlet life cycle and request processing
          • URL encoding
          • Include servletsJSPs
          • Portlet application packaging
          • Expiration-based caching
            • Concepts that differ
              • Portlet application entity
              • Portlet entity
              • Action and Render Request Response objects
              • Window concept
              • Portlet API does not extend servlet API
              • TAG libraries
                • Concepts new in the JSR 168
                  • Render parameter
                  • Extension mechanisms
                    • Custom window states
                    • Custom portlet modes
                    • Custom user info
                    • Request Response properties
                      • Web application session scope
                      • Reuse of the HttpSession listeners
                      • J2EE role support
                      • Resource bundles
                      • Multiple response content types
                      • Redirect in action
                      • Preference validator
                      • Portal context
                      • Localization support
                        • Concepts missing in the JSR 168
                          • Eventing
                          • Additional lifecycle events
                          • Property broker
                          • Portlet Menus
                          • Portlet Services
                          • Invalidation-based caching
                            • Alignment with WSRP
                              • Outlook for the next version of the JSR 168
                              • Guidelines for programming IBM Portlet API portlets
                                • Similar Functionality
                                  • Basic programming model
                                  • Portlet private session
                                  • User profile information
                                  • Persistent data
                                  • Portlet modes and window states
                                  • Expiration-based caching
                                    • Slightly different functionality
                                      • Sharing of data between portlets
                                      • Session listeners
                                        • New JSR 168 functionality
                                          • Navigational state (render parameters)
                                            • Pitfalls
                                              • Request response objects for action and render phase
                                              • Include search path
                                              • Form parameter encoding
                                              • Title setting
                                                  • Examples
                                                    • IBM Portlet API Portlet Code
                                                    • JSR 168 Portlet Code
                                                    • IBM Portlet API JSPs
                                                    • JSR 168 JSPs
                                                      • Summary
Page 33: Difference Bw Jsr168 and Ibm

531 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

bull no support of the back button in the browser bull current state of the portlet is not bookmarkable bull 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 bull 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

54 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

541 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 -

542 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

543 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

544 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 wersquoll 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

Figure 7After clicking on the Edit mode button the portlet renders the Edit view shown in

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

Figure 8

After we press the ldquoAddrdquo 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

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

bull use JSPs for rendering the output bull customize the portlet output taking user specific data into account bull 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

61 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 comibmwpssampleswp5

import javaio

import javautil

import orgapachejetspeedportlet

import orgapachejetspeedportletevent

public class IbmBookmark extends PortletAdapter implements ActionListener

public void init(PortletConfig portletConfig) throws UnavailableException

superinit(portletConfig)

- 36 -

public void doView(PortletRequest request PortletResponse response)

throws PortletException IOException

String jspName = thisgetPortletConfig()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 = responsecreateReturnURI()

addURIaddAction(add)

requestsetAttribute(addURI addURItoString())

PortletURI cancelURI = responsecreateReturnURI()

requestsetAttribute(cancelURI cancelURItoString())

String jspName = thisgetPortletConfig()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 ldquocancelrdquo and ldquoaddrdquo URLs are created inside the portlet and attached to the request before including the Edit JSP Both URLs are from type ldquoReturnURIrdquo 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 = eventgetRequest()

String action = eventgetActionString()

PortletLog log = getPortletLog()

if ( action=null )

try

if (actionequals(removeURI))

String removeName = requestgetParameter(remove)

PortletData portData = requestgetData()

portDataremoveAttribute(removeName)

portDatastore()

if (actionequals(add))

PortletData portData = requestgetData()

String name = requestgetParameter(name)

String value = requestgetParameter(value)

portDatasetAttribute(name value)

portDatastore()

catch ( AccessDeniedException ade )

logerror(AccessDeniedException occured when adding or deleting a bookmark)

catch ( IOException ioe )

logerror(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 ldquoaddrdquo or ldquodeleterdquo 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 ldquoaddrdquo or ldquoremoveURIrdquo If the user has clicked on the ldquoremoverdquo button the corresponding link is removed from the portlet data whereas if ldquoaddrdquo was clicked the data entered by the user is added to the portlet data

62 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 comibmwpssamplesjsr

import javaio

import javaxportlet

public class Bookmark extends GenericPortlet

public void init(PortletConfig config) throws PortletException

superinit(config)

public void doView(RenderRequest request RenderResponse response)

throws PortletException IOException

responsesetContentType(texthtml)

String jspName = getPortletConfig()getInitParameter(jspView)

PortletRequestDispatcher rd = getPortletContext()getRequestDispatcher(jspName)

rdinclude(requestresponse)

- 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

responsesetContentType(texthtml)

PortletURL addUrl = responsecreateActionURL()

addUrlsetPortletMode(PortletModeVIEW)

addUrlsetParameter(addadd)

requestsetAttribute(addUrladdUrltoString())

PortletURL cancelUrl = responsecreateRenderURL()

cancelUrlsetPortletMode(PortletModeVIEW)

requestsetAttribute(cancelUrlcancelUrltoString())

String jspName = getPortletConfig()getInitParameter(jspEdit)

PortletRequestDispatcher rd = getPortletContext()getRequestDispatcher(jspName)

rdinclude(requestresponse)

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 ldquoaddrdquo button URL an action URL is created as we need to store the user input of the add form persistently For the ldquocancelrdquo 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 = requestgetParameter(remove)

if (removeName = null)

PortletPreferences prefs = requestgetPreferences()

prefsreset(removeName)

prefsstore()

String add = requestgetParameter(add)

if (add = null)

PortletPreferences prefs = requestgetPreferences()

String name = requestgetParameter(name)

String value = requestgetParameter(value)

prefssetValue(name value)

prefsstore()

catch ( IOException ioe )

getPortletContextlog(An IO error occured when trying to remove a bookmark)

catch ( PortletException pe )

getPortletContextlog(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

bull 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

bull 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

bull Persistent portlet data The JSR 168 persistent data PortletPreferences have an API similar to the JDK 14 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

bull 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

63 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

lt page contentType=texthtml import=javautil comibmwpssampleswp5

orgapachejetspeedportlet session=falsegt

lt taglib uri=WEB-INFtldportlettld prefix=portletAPI gt

- 42 -

ltportletAPIinitgt

ltp class=wpsPortletHeadgtltportletAPItext key=available_bookmarks

bundle=nlsTextgtAvailable BookmarksltportletAPItextgtltpgt

lt

PortletData prefs = portletRequestgetData()

Enumeration e = prefsgetAttributeNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltportletAPItext key=no_bookmarks bundle=nlsTextgtNo

bookmarksltportletAPItextgtltpgt

lt

else

gt

ltp class=wpsIndentMediumgt

lt

while (ehasMoreElements())

String name = (String)enextElement()

String value = (String)prefsgetAttribute(name)

gt

lta href=lt=valuegt target=_blankgtlt=namegtltagtltbr gt

lt

gt

ltpgt

The View JSP first call portletAPIinit 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

lt page contentType=texthtml import=javautil

comibmwpssampleswp5orgapachejetspeedportlet session=falsegt

lt taglib uri=WEB-INFtldportlettld prefix=portletAPI gt

ltjspuseBean id=addURI class=javalangString scope=request gt

ltjspuseBean id=cancelURI class=javalangString scope=request gt

ltportletAPIinitgt

lth4gtltportletAPItext key=available_bookmarks bundle=nlsTextgtAvailable

BookmarksltportletAPItextgtlth4gt

lttable class=wpsTablegt

lttr class=wpsTableRowgt

ltth class=portlet-table-headergtltportletAPItext key=name bundle=nlsTextgtltthgt

ltth class=portlet-table-headergtltportletAPItext key=url bundle=nlsTextgtltthgt

lttdgtlttdgt

lttrgt

lt

PortletData prefs = portletRequestgetData()

Enumeration e = prefsgetAttributeNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltportletAPItext key=no_bookmarks bundle=nlsTextgtNo

bookmarksltportletAPItextgtltpgt

lt

else

while (ehasMoreElements())

- 44 -

String name = (String)enextElement()

String value = (String)prefsgetAttribute(name)

gt

lttr class=wpsTableRowgt

lttdgt lt=namegt lttdgt

lttdgt lt=valuegt lttdgt

lttdgt lta href=ltportletAPIcreateURIgtltportletAPIURIAction

name=removeURIgtltportletAPIURIParameter name=remove

value=lt=namegtgtltportletAPIcreateURIgtgt

(ltportletAPItext key=delete bundle=nlsTextgt)ltagt

lttdgt

lttrgt

lt

gt

ltform action=lt=addURIgt method=POSTgt

lttr class=wpsTableRowgt

lttdgtltinput name=ltportletAPIencodeNamespace value=namegt type=text

class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=ltportletAPIencodeNamespace value=valuegt type=text

class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=ltportletAPIencodeNamespace value=addgt type=submit

value=ltportletAPItext key=add bundle=nlsTextgt class=portlet-form-buttongtlttdgt

lttrgt

ltformgt

lttablegt

- 45 -

ltform action=lt=cancelURIgt method=postgt

ltinput name=ltportletAPIencodeNamespace value=cancelgt type=submit

value=ltportletAPItext key=cancel bundle=nlsTextgt class=portlet-form-buttongt

ltformgt

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 ldquodeleterdquo button for which an URL with the action ldquoremoveURIrdquo 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 ldquocancelrdquo button from the request

64 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

lt page import=javaxportlet javautil session=falsegt

lt taglib uri=httpjavasuncomportlet prefix=portletAPI gt

lt taglib prefix=fmt uri=httpjavasuncomjstlfmt gt

ltportletAPIdefineObjects gt

ltfmtsetBundle basename=nlsTextgt

lt

ResourceBundle myText = ResourceBundlegetBundle(nlsText requestgetLocale())

gt

lth4gtltfmtmessage key=available_bookmarksgtlth4gt

lt

PortletPreferences prefs = renderRequestgetPreferences()

Enumeration e = prefsgetNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltfmtmessage key=no_bookmarksgtltpgt

- 46 -

lt

else

gt

ltpgt

lt

while (ehasMoreElements())

String name = (String)enextElement()

String value = prefsgetValue(namelt+myTextgetString(undefined)+gt)

gt

lta href=lt=valuegt target=_blankgtlt=namegtltagtltbr gt

lt

gt

ltpgt

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 fmtmessage 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

lt page import=javaxportlet javautil session=false gt

lt taglib uri=httpjavasuncomportlet prefix=portletAPI gt

lt taglib prefix=fmt uri=httpjavasuncomjstlfmt gt

ltjspuseBean id=addUrl scope=request class=javalangString gt

ltjspuseBean id=cancelUrl scope=request class=javalangString gt

- 47 -

ltportletAPIdefineObjectsgt

lt

ResourceBundle myText = ResourceBundlegetBundle(nlsText requestgetLocale())

gt

ltfmtsetBundle basename=nlsTextgt

lth4gtltfmtmessage key=available_bookmarksgtlth4gt

lttable class=wpsTablegt

lttr class=wpsTableRowgt

ltth class=wpsTableHeadgtltfmtmessage key=namegtltthgt

ltth class=wpsTableHeadgtltfmtmessage key=urlgtltthgt

lttdgtlttdgt

lttrgt

lt

PortletPreferences prefs = renderRequestgetPreferences()

Enumeration e = prefsgetNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltfmtmessage key=no_bookmarksgtltpgt

lt

else

while (ehasMoreElements())

String name = (String)enextElement()

String value = prefsgetValue(namelt+myTextgetString(undefined)+gt)

gt

lttr class=wpsTableRowgt

lttdgt lt=namegt lttdgt

lttdgt lt=valuegt lttdgt

- 48 -

lttdgt ltportletAPIactionURL var=removeUrlgt

ltportletAPIparam name=remove value=lt=namegtgt

ltportletAPIactionURLgt

lta href=lt=removeUrltoString()gtgt(ltfmtmessage key=deletegt)ltagt

lttdgt

lttrgt

lt

gt

ltform action=lt=addUrlgt method=POSTgt

lttr class=wpsTableRowgt

lttdgtltinput name=name type=text class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=value type=text class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=add type=submit value=ltfmtmessage key=addgt

class=portlet-form-buttongtlttdgt

lttrgt

ltformgt

lttablegt

ltform action=lt=cancelUrlgt method=postgt

ltinput name=cancel type=submit value=ltfmtmessage key=cancelgt class=portlet-

form-buttongt

ltformgt

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 14 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 -

- 51 -

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 (eg eventing) the IBM Portlet API still needs to be used Trademarks bull IBM and WebSphere are trademarks or registered trademarks of IBM Corporation in

the United States other countries or both bull 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 bull Other company product and service names may be trademarks or service marks of

others IBM copyright and trademark information httpwwwibmcomlegalcopytradephtml

  • Introduction
  • JSR 168 and the Java Community Process
  • Comparing concepts
    • Basic concepts
      • Portal
      • Portal page
      • Portlet
      • Portlet Container
        • Concepts that are the same
          • Portlet mode
          • Window state
          • Portlet life cycle and request processing
          • URL encoding
          • Include servletsJSPs
          • Portlet application packaging
          • Expiration-based caching
            • Concepts that differ
              • Portlet application entity
              • Portlet entity
              • Action and Render Request Response objects
              • Window concept
              • Portlet API does not extend servlet API
              • TAG libraries
                • Concepts new in the JSR 168
                  • Render parameter
                  • Extension mechanisms
                    • Custom window states
                    • Custom portlet modes
                    • Custom user info
                    • Request Response properties
                      • Web application session scope
                      • Reuse of the HttpSession listeners
                      • J2EE role support
                      • Resource bundles
                      • Multiple response content types
                      • Redirect in action
                      • Preference validator
                      • Portal context
                      • Localization support
                        • Concepts missing in the JSR 168
                          • Eventing
                          • Additional lifecycle events
                          • Property broker
                          • Portlet Menus
                          • Portlet Services
                          • Invalidation-based caching
                            • Alignment with WSRP
                              • Outlook for the next version of the JSR 168
                              • Guidelines for programming IBM Portlet API portlets
                                • Similar Functionality
                                  • Basic programming model
                                  • Portlet private session
                                  • User profile information
                                  • Persistent data
                                  • Portlet modes and window states
                                  • Expiration-based caching
                                    • Slightly different functionality
                                      • Sharing of data between portlets
                                      • Session listeners
                                        • New JSR 168 functionality
                                          • Navigational state (render parameters)
                                            • Pitfalls
                                              • Request response objects for action and render phase
                                              • Include search path
                                              • Form parameter encoding
                                              • Title setting
                                                  • Examples
                                                    • IBM Portlet API Portlet Code
                                                    • JSR 168 Portlet Code
                                                    • IBM Portlet API JSPs
                                                    • JSR 168 JSPs
                                                      • Summary
Page 34: Difference Bw Jsr168 and Ibm

542 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

543 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

544 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 wersquoll 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

Figure 7After clicking on the Edit mode button the portlet renders the Edit view shown in

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

Figure 8

After we press the ldquoAddrdquo 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

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

bull use JSPs for rendering the output bull customize the portlet output taking user specific data into account bull 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

61 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 comibmwpssampleswp5

import javaio

import javautil

import orgapachejetspeedportlet

import orgapachejetspeedportletevent

public class IbmBookmark extends PortletAdapter implements ActionListener

public void init(PortletConfig portletConfig) throws UnavailableException

superinit(portletConfig)

- 36 -

public void doView(PortletRequest request PortletResponse response)

throws PortletException IOException

String jspName = thisgetPortletConfig()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 = responsecreateReturnURI()

addURIaddAction(add)

requestsetAttribute(addURI addURItoString())

PortletURI cancelURI = responsecreateReturnURI()

requestsetAttribute(cancelURI cancelURItoString())

String jspName = thisgetPortletConfig()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 ldquocancelrdquo and ldquoaddrdquo URLs are created inside the portlet and attached to the request before including the Edit JSP Both URLs are from type ldquoReturnURIrdquo 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 = eventgetRequest()

String action = eventgetActionString()

PortletLog log = getPortletLog()

if ( action=null )

try

if (actionequals(removeURI))

String removeName = requestgetParameter(remove)

PortletData portData = requestgetData()

portDataremoveAttribute(removeName)

portDatastore()

if (actionequals(add))

PortletData portData = requestgetData()

String name = requestgetParameter(name)

String value = requestgetParameter(value)

portDatasetAttribute(name value)

portDatastore()

catch ( AccessDeniedException ade )

logerror(AccessDeniedException occured when adding or deleting a bookmark)

catch ( IOException ioe )

logerror(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 ldquoaddrdquo or ldquodeleterdquo 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 ldquoaddrdquo or ldquoremoveURIrdquo If the user has clicked on the ldquoremoverdquo button the corresponding link is removed from the portlet data whereas if ldquoaddrdquo was clicked the data entered by the user is added to the portlet data

62 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 comibmwpssamplesjsr

import javaio

import javaxportlet

public class Bookmark extends GenericPortlet

public void init(PortletConfig config) throws PortletException

superinit(config)

public void doView(RenderRequest request RenderResponse response)

throws PortletException IOException

responsesetContentType(texthtml)

String jspName = getPortletConfig()getInitParameter(jspView)

PortletRequestDispatcher rd = getPortletContext()getRequestDispatcher(jspName)

rdinclude(requestresponse)

- 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

responsesetContentType(texthtml)

PortletURL addUrl = responsecreateActionURL()

addUrlsetPortletMode(PortletModeVIEW)

addUrlsetParameter(addadd)

requestsetAttribute(addUrladdUrltoString())

PortletURL cancelUrl = responsecreateRenderURL()

cancelUrlsetPortletMode(PortletModeVIEW)

requestsetAttribute(cancelUrlcancelUrltoString())

String jspName = getPortletConfig()getInitParameter(jspEdit)

PortletRequestDispatcher rd = getPortletContext()getRequestDispatcher(jspName)

rdinclude(requestresponse)

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 ldquoaddrdquo button URL an action URL is created as we need to store the user input of the add form persistently For the ldquocancelrdquo 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 = requestgetParameter(remove)

if (removeName = null)

PortletPreferences prefs = requestgetPreferences()

prefsreset(removeName)

prefsstore()

String add = requestgetParameter(add)

if (add = null)

PortletPreferences prefs = requestgetPreferences()

String name = requestgetParameter(name)

String value = requestgetParameter(value)

prefssetValue(name value)

prefsstore()

catch ( IOException ioe )

getPortletContextlog(An IO error occured when trying to remove a bookmark)

catch ( PortletException pe )

getPortletContextlog(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

bull 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

bull 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

bull Persistent portlet data The JSR 168 persistent data PortletPreferences have an API similar to the JDK 14 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

bull 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

63 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

lt page contentType=texthtml import=javautil comibmwpssampleswp5

orgapachejetspeedportlet session=falsegt

lt taglib uri=WEB-INFtldportlettld prefix=portletAPI gt

- 42 -

ltportletAPIinitgt

ltp class=wpsPortletHeadgtltportletAPItext key=available_bookmarks

bundle=nlsTextgtAvailable BookmarksltportletAPItextgtltpgt

lt

PortletData prefs = portletRequestgetData()

Enumeration e = prefsgetAttributeNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltportletAPItext key=no_bookmarks bundle=nlsTextgtNo

bookmarksltportletAPItextgtltpgt

lt

else

gt

ltp class=wpsIndentMediumgt

lt

while (ehasMoreElements())

String name = (String)enextElement()

String value = (String)prefsgetAttribute(name)

gt

lta href=lt=valuegt target=_blankgtlt=namegtltagtltbr gt

lt

gt

ltpgt

The View JSP first call portletAPIinit 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

lt page contentType=texthtml import=javautil

comibmwpssampleswp5orgapachejetspeedportlet session=falsegt

lt taglib uri=WEB-INFtldportlettld prefix=portletAPI gt

ltjspuseBean id=addURI class=javalangString scope=request gt

ltjspuseBean id=cancelURI class=javalangString scope=request gt

ltportletAPIinitgt

lth4gtltportletAPItext key=available_bookmarks bundle=nlsTextgtAvailable

BookmarksltportletAPItextgtlth4gt

lttable class=wpsTablegt

lttr class=wpsTableRowgt

ltth class=portlet-table-headergtltportletAPItext key=name bundle=nlsTextgtltthgt

ltth class=portlet-table-headergtltportletAPItext key=url bundle=nlsTextgtltthgt

lttdgtlttdgt

lttrgt

lt

PortletData prefs = portletRequestgetData()

Enumeration e = prefsgetAttributeNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltportletAPItext key=no_bookmarks bundle=nlsTextgtNo

bookmarksltportletAPItextgtltpgt

lt

else

while (ehasMoreElements())

- 44 -

String name = (String)enextElement()

String value = (String)prefsgetAttribute(name)

gt

lttr class=wpsTableRowgt

lttdgt lt=namegt lttdgt

lttdgt lt=valuegt lttdgt

lttdgt lta href=ltportletAPIcreateURIgtltportletAPIURIAction

name=removeURIgtltportletAPIURIParameter name=remove

value=lt=namegtgtltportletAPIcreateURIgtgt

(ltportletAPItext key=delete bundle=nlsTextgt)ltagt

lttdgt

lttrgt

lt

gt

ltform action=lt=addURIgt method=POSTgt

lttr class=wpsTableRowgt

lttdgtltinput name=ltportletAPIencodeNamespace value=namegt type=text

class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=ltportletAPIencodeNamespace value=valuegt type=text

class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=ltportletAPIencodeNamespace value=addgt type=submit

value=ltportletAPItext key=add bundle=nlsTextgt class=portlet-form-buttongtlttdgt

lttrgt

ltformgt

lttablegt

- 45 -

ltform action=lt=cancelURIgt method=postgt

ltinput name=ltportletAPIencodeNamespace value=cancelgt type=submit

value=ltportletAPItext key=cancel bundle=nlsTextgt class=portlet-form-buttongt

ltformgt

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 ldquodeleterdquo button for which an URL with the action ldquoremoveURIrdquo 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 ldquocancelrdquo button from the request

64 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

lt page import=javaxportlet javautil session=falsegt

lt taglib uri=httpjavasuncomportlet prefix=portletAPI gt

lt taglib prefix=fmt uri=httpjavasuncomjstlfmt gt

ltportletAPIdefineObjects gt

ltfmtsetBundle basename=nlsTextgt

lt

ResourceBundle myText = ResourceBundlegetBundle(nlsText requestgetLocale())

gt

lth4gtltfmtmessage key=available_bookmarksgtlth4gt

lt

PortletPreferences prefs = renderRequestgetPreferences()

Enumeration e = prefsgetNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltfmtmessage key=no_bookmarksgtltpgt

- 46 -

lt

else

gt

ltpgt

lt

while (ehasMoreElements())

String name = (String)enextElement()

String value = prefsgetValue(namelt+myTextgetString(undefined)+gt)

gt

lta href=lt=valuegt target=_blankgtlt=namegtltagtltbr gt

lt

gt

ltpgt

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 fmtmessage 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

lt page import=javaxportlet javautil session=false gt

lt taglib uri=httpjavasuncomportlet prefix=portletAPI gt

lt taglib prefix=fmt uri=httpjavasuncomjstlfmt gt

ltjspuseBean id=addUrl scope=request class=javalangString gt

ltjspuseBean id=cancelUrl scope=request class=javalangString gt

- 47 -

ltportletAPIdefineObjectsgt

lt

ResourceBundle myText = ResourceBundlegetBundle(nlsText requestgetLocale())

gt

ltfmtsetBundle basename=nlsTextgt

lth4gtltfmtmessage key=available_bookmarksgtlth4gt

lttable class=wpsTablegt

lttr class=wpsTableRowgt

ltth class=wpsTableHeadgtltfmtmessage key=namegtltthgt

ltth class=wpsTableHeadgtltfmtmessage key=urlgtltthgt

lttdgtlttdgt

lttrgt

lt

PortletPreferences prefs = renderRequestgetPreferences()

Enumeration e = prefsgetNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltfmtmessage key=no_bookmarksgtltpgt

lt

else

while (ehasMoreElements())

String name = (String)enextElement()

String value = prefsgetValue(namelt+myTextgetString(undefined)+gt)

gt

lttr class=wpsTableRowgt

lttdgt lt=namegt lttdgt

lttdgt lt=valuegt lttdgt

- 48 -

lttdgt ltportletAPIactionURL var=removeUrlgt

ltportletAPIparam name=remove value=lt=namegtgt

ltportletAPIactionURLgt

lta href=lt=removeUrltoString()gtgt(ltfmtmessage key=deletegt)ltagt

lttdgt

lttrgt

lt

gt

ltform action=lt=addUrlgt method=POSTgt

lttr class=wpsTableRowgt

lttdgtltinput name=name type=text class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=value type=text class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=add type=submit value=ltfmtmessage key=addgt

class=portlet-form-buttongtlttdgt

lttrgt

ltformgt

lttablegt

ltform action=lt=cancelUrlgt method=postgt

ltinput name=cancel type=submit value=ltfmtmessage key=cancelgt class=portlet-

form-buttongt

ltformgt

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 14 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 -

- 51 -

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 (eg eventing) the IBM Portlet API still needs to be used Trademarks bull IBM and WebSphere are trademarks or registered trademarks of IBM Corporation in

the United States other countries or both bull 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 bull Other company product and service names may be trademarks or service marks of

others IBM copyright and trademark information httpwwwibmcomlegalcopytradephtml

  • Introduction
  • JSR 168 and the Java Community Process
  • Comparing concepts
    • Basic concepts
      • Portal
      • Portal page
      • Portlet
      • Portlet Container
        • Concepts that are the same
          • Portlet mode
          • Window state
          • Portlet life cycle and request processing
          • URL encoding
          • Include servletsJSPs
          • Portlet application packaging
          • Expiration-based caching
            • Concepts that differ
              • Portlet application entity
              • Portlet entity
              • Action and Render Request Response objects
              • Window concept
              • Portlet API does not extend servlet API
              • TAG libraries
                • Concepts new in the JSR 168
                  • Render parameter
                  • Extension mechanisms
                    • Custom window states
                    • Custom portlet modes
                    • Custom user info
                    • Request Response properties
                      • Web application session scope
                      • Reuse of the HttpSession listeners
                      • J2EE role support
                      • Resource bundles
                      • Multiple response content types
                      • Redirect in action
                      • Preference validator
                      • Portal context
                      • Localization support
                        • Concepts missing in the JSR 168
                          • Eventing
                          • Additional lifecycle events
                          • Property broker
                          • Portlet Menus
                          • Portlet Services
                          • Invalidation-based caching
                            • Alignment with WSRP
                              • Outlook for the next version of the JSR 168
                              • Guidelines for programming IBM Portlet API portlets
                                • Similar Functionality
                                  • Basic programming model
                                  • Portlet private session
                                  • User profile information
                                  • Persistent data
                                  • Portlet modes and window states
                                  • Expiration-based caching
                                    • Slightly different functionality
                                      • Sharing of data between portlets
                                      • Session listeners
                                        • New JSR 168 functionality
                                          • Navigational state (render parameters)
                                            • Pitfalls
                                              • Request response objects for action and render phase
                                              • Include search path
                                              • Form parameter encoding
                                              • Title setting
                                                  • Examples
                                                    • IBM Portlet API Portlet Code
                                                    • JSR 168 Portlet Code
                                                    • IBM Portlet API JSPs
                                                    • JSR 168 JSPs
                                                      • Summary
Page 35: Difference Bw Jsr168 and Ibm

6 Examples This section shows examples for both the IBM Portlet API and the JSR 168 API and highlights the differences between both First wersquoll 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

Figure 7After clicking on the Edit mode button the portlet renders the Edit view shown in

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

Figure 8

After we press the ldquoAddrdquo 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

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

bull use JSPs for rendering the output bull customize the portlet output taking user specific data into account bull 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

61 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 comibmwpssampleswp5

import javaio

import javautil

import orgapachejetspeedportlet

import orgapachejetspeedportletevent

public class IbmBookmark extends PortletAdapter implements ActionListener

public void init(PortletConfig portletConfig) throws UnavailableException

superinit(portletConfig)

- 36 -

public void doView(PortletRequest request PortletResponse response)

throws PortletException IOException

String jspName = thisgetPortletConfig()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 = responsecreateReturnURI()

addURIaddAction(add)

requestsetAttribute(addURI addURItoString())

PortletURI cancelURI = responsecreateReturnURI()

requestsetAttribute(cancelURI cancelURItoString())

String jspName = thisgetPortletConfig()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 ldquocancelrdquo and ldquoaddrdquo URLs are created inside the portlet and attached to the request before including the Edit JSP Both URLs are from type ldquoReturnURIrdquo 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 = eventgetRequest()

String action = eventgetActionString()

PortletLog log = getPortletLog()

if ( action=null )

try

if (actionequals(removeURI))

String removeName = requestgetParameter(remove)

PortletData portData = requestgetData()

portDataremoveAttribute(removeName)

portDatastore()

if (actionequals(add))

PortletData portData = requestgetData()

String name = requestgetParameter(name)

String value = requestgetParameter(value)

portDatasetAttribute(name value)

portDatastore()

catch ( AccessDeniedException ade )

logerror(AccessDeniedException occured when adding or deleting a bookmark)

catch ( IOException ioe )

logerror(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 ldquoaddrdquo or ldquodeleterdquo 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 ldquoaddrdquo or ldquoremoveURIrdquo If the user has clicked on the ldquoremoverdquo button the corresponding link is removed from the portlet data whereas if ldquoaddrdquo was clicked the data entered by the user is added to the portlet data

62 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 comibmwpssamplesjsr

import javaio

import javaxportlet

public class Bookmark extends GenericPortlet

public void init(PortletConfig config) throws PortletException

superinit(config)

public void doView(RenderRequest request RenderResponse response)

throws PortletException IOException

responsesetContentType(texthtml)

String jspName = getPortletConfig()getInitParameter(jspView)

PortletRequestDispatcher rd = getPortletContext()getRequestDispatcher(jspName)

rdinclude(requestresponse)

- 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

responsesetContentType(texthtml)

PortletURL addUrl = responsecreateActionURL()

addUrlsetPortletMode(PortletModeVIEW)

addUrlsetParameter(addadd)

requestsetAttribute(addUrladdUrltoString())

PortletURL cancelUrl = responsecreateRenderURL()

cancelUrlsetPortletMode(PortletModeVIEW)

requestsetAttribute(cancelUrlcancelUrltoString())

String jspName = getPortletConfig()getInitParameter(jspEdit)

PortletRequestDispatcher rd = getPortletContext()getRequestDispatcher(jspName)

rdinclude(requestresponse)

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 ldquoaddrdquo button URL an action URL is created as we need to store the user input of the add form persistently For the ldquocancelrdquo 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 = requestgetParameter(remove)

if (removeName = null)

PortletPreferences prefs = requestgetPreferences()

prefsreset(removeName)

prefsstore()

String add = requestgetParameter(add)

if (add = null)

PortletPreferences prefs = requestgetPreferences()

String name = requestgetParameter(name)

String value = requestgetParameter(value)

prefssetValue(name value)

prefsstore()

catch ( IOException ioe )

getPortletContextlog(An IO error occured when trying to remove a bookmark)

catch ( PortletException pe )

getPortletContextlog(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

bull 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

bull 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

bull Persistent portlet data The JSR 168 persistent data PortletPreferences have an API similar to the JDK 14 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

bull 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

63 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

lt page contentType=texthtml import=javautil comibmwpssampleswp5

orgapachejetspeedportlet session=falsegt

lt taglib uri=WEB-INFtldportlettld prefix=portletAPI gt

- 42 -

ltportletAPIinitgt

ltp class=wpsPortletHeadgtltportletAPItext key=available_bookmarks

bundle=nlsTextgtAvailable BookmarksltportletAPItextgtltpgt

lt

PortletData prefs = portletRequestgetData()

Enumeration e = prefsgetAttributeNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltportletAPItext key=no_bookmarks bundle=nlsTextgtNo

bookmarksltportletAPItextgtltpgt

lt

else

gt

ltp class=wpsIndentMediumgt

lt

while (ehasMoreElements())

String name = (String)enextElement()

String value = (String)prefsgetAttribute(name)

gt

lta href=lt=valuegt target=_blankgtlt=namegtltagtltbr gt

lt

gt

ltpgt

The View JSP first call portletAPIinit 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

lt page contentType=texthtml import=javautil

comibmwpssampleswp5orgapachejetspeedportlet session=falsegt

lt taglib uri=WEB-INFtldportlettld prefix=portletAPI gt

ltjspuseBean id=addURI class=javalangString scope=request gt

ltjspuseBean id=cancelURI class=javalangString scope=request gt

ltportletAPIinitgt

lth4gtltportletAPItext key=available_bookmarks bundle=nlsTextgtAvailable

BookmarksltportletAPItextgtlth4gt

lttable class=wpsTablegt

lttr class=wpsTableRowgt

ltth class=portlet-table-headergtltportletAPItext key=name bundle=nlsTextgtltthgt

ltth class=portlet-table-headergtltportletAPItext key=url bundle=nlsTextgtltthgt

lttdgtlttdgt

lttrgt

lt

PortletData prefs = portletRequestgetData()

Enumeration e = prefsgetAttributeNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltportletAPItext key=no_bookmarks bundle=nlsTextgtNo

bookmarksltportletAPItextgtltpgt

lt

else

while (ehasMoreElements())

- 44 -

String name = (String)enextElement()

String value = (String)prefsgetAttribute(name)

gt

lttr class=wpsTableRowgt

lttdgt lt=namegt lttdgt

lttdgt lt=valuegt lttdgt

lttdgt lta href=ltportletAPIcreateURIgtltportletAPIURIAction

name=removeURIgtltportletAPIURIParameter name=remove

value=lt=namegtgtltportletAPIcreateURIgtgt

(ltportletAPItext key=delete bundle=nlsTextgt)ltagt

lttdgt

lttrgt

lt

gt

ltform action=lt=addURIgt method=POSTgt

lttr class=wpsTableRowgt

lttdgtltinput name=ltportletAPIencodeNamespace value=namegt type=text

class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=ltportletAPIencodeNamespace value=valuegt type=text

class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=ltportletAPIencodeNamespace value=addgt type=submit

value=ltportletAPItext key=add bundle=nlsTextgt class=portlet-form-buttongtlttdgt

lttrgt

ltformgt

lttablegt

- 45 -

ltform action=lt=cancelURIgt method=postgt

ltinput name=ltportletAPIencodeNamespace value=cancelgt type=submit

value=ltportletAPItext key=cancel bundle=nlsTextgt class=portlet-form-buttongt

ltformgt

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 ldquodeleterdquo button for which an URL with the action ldquoremoveURIrdquo 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 ldquocancelrdquo button from the request

64 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

lt page import=javaxportlet javautil session=falsegt

lt taglib uri=httpjavasuncomportlet prefix=portletAPI gt

lt taglib prefix=fmt uri=httpjavasuncomjstlfmt gt

ltportletAPIdefineObjects gt

ltfmtsetBundle basename=nlsTextgt

lt

ResourceBundle myText = ResourceBundlegetBundle(nlsText requestgetLocale())

gt

lth4gtltfmtmessage key=available_bookmarksgtlth4gt

lt

PortletPreferences prefs = renderRequestgetPreferences()

Enumeration e = prefsgetNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltfmtmessage key=no_bookmarksgtltpgt

- 46 -

lt

else

gt

ltpgt

lt

while (ehasMoreElements())

String name = (String)enextElement()

String value = prefsgetValue(namelt+myTextgetString(undefined)+gt)

gt

lta href=lt=valuegt target=_blankgtlt=namegtltagtltbr gt

lt

gt

ltpgt

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 fmtmessage 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

lt page import=javaxportlet javautil session=false gt

lt taglib uri=httpjavasuncomportlet prefix=portletAPI gt

lt taglib prefix=fmt uri=httpjavasuncomjstlfmt gt

ltjspuseBean id=addUrl scope=request class=javalangString gt

ltjspuseBean id=cancelUrl scope=request class=javalangString gt

- 47 -

ltportletAPIdefineObjectsgt

lt

ResourceBundle myText = ResourceBundlegetBundle(nlsText requestgetLocale())

gt

ltfmtsetBundle basename=nlsTextgt

lth4gtltfmtmessage key=available_bookmarksgtlth4gt

lttable class=wpsTablegt

lttr class=wpsTableRowgt

ltth class=wpsTableHeadgtltfmtmessage key=namegtltthgt

ltth class=wpsTableHeadgtltfmtmessage key=urlgtltthgt

lttdgtlttdgt

lttrgt

lt

PortletPreferences prefs = renderRequestgetPreferences()

Enumeration e = prefsgetNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltfmtmessage key=no_bookmarksgtltpgt

lt

else

while (ehasMoreElements())

String name = (String)enextElement()

String value = prefsgetValue(namelt+myTextgetString(undefined)+gt)

gt

lttr class=wpsTableRowgt

lttdgt lt=namegt lttdgt

lttdgt lt=valuegt lttdgt

- 48 -

lttdgt ltportletAPIactionURL var=removeUrlgt

ltportletAPIparam name=remove value=lt=namegtgt

ltportletAPIactionURLgt

lta href=lt=removeUrltoString()gtgt(ltfmtmessage key=deletegt)ltagt

lttdgt

lttrgt

lt

gt

ltform action=lt=addUrlgt method=POSTgt

lttr class=wpsTableRowgt

lttdgtltinput name=name type=text class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=value type=text class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=add type=submit value=ltfmtmessage key=addgt

class=portlet-form-buttongtlttdgt

lttrgt

ltformgt

lttablegt

ltform action=lt=cancelUrlgt method=postgt

ltinput name=cancel type=submit value=ltfmtmessage key=cancelgt class=portlet-

form-buttongt

ltformgt

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 14 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 -

- 51 -

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 (eg eventing) the IBM Portlet API still needs to be used Trademarks bull IBM and WebSphere are trademarks or registered trademarks of IBM Corporation in

the United States other countries or both bull 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 bull Other company product and service names may be trademarks or service marks of

others IBM copyright and trademark information httpwwwibmcomlegalcopytradephtml

  • Introduction
  • JSR 168 and the Java Community Process
  • Comparing concepts
    • Basic concepts
      • Portal
      • Portal page
      • Portlet
      • Portlet Container
        • Concepts that are the same
          • Portlet mode
          • Window state
          • Portlet life cycle and request processing
          • URL encoding
          • Include servletsJSPs
          • Portlet application packaging
          • Expiration-based caching
            • Concepts that differ
              • Portlet application entity
              • Portlet entity
              • Action and Render Request Response objects
              • Window concept
              • Portlet API does not extend servlet API
              • TAG libraries
                • Concepts new in the JSR 168
                  • Render parameter
                  • Extension mechanisms
                    • Custom window states
                    • Custom portlet modes
                    • Custom user info
                    • Request Response properties
                      • Web application session scope
                      • Reuse of the HttpSession listeners
                      • J2EE role support
                      • Resource bundles
                      • Multiple response content types
                      • Redirect in action
                      • Preference validator
                      • Portal context
                      • Localization support
                        • Concepts missing in the JSR 168
                          • Eventing
                          • Additional lifecycle events
                          • Property broker
                          • Portlet Menus
                          • Portlet Services
                          • Invalidation-based caching
                            • Alignment with WSRP
                              • Outlook for the next version of the JSR 168
                              • Guidelines for programming IBM Portlet API portlets
                                • Similar Functionality
                                  • Basic programming model
                                  • Portlet private session
                                  • User profile information
                                  • Persistent data
                                  • Portlet modes and window states
                                  • Expiration-based caching
                                    • Slightly different functionality
                                      • Sharing of data between portlets
                                      • Session listeners
                                        • New JSR 168 functionality
                                          • Navigational state (render parameters)
                                            • Pitfalls
                                              • Request response objects for action and render phase
                                              • Include search path
                                              • Form parameter encoding
                                              • Title setting
                                                  • Examples
                                                    • IBM Portlet API Portlet Code
                                                    • JSR 168 Portlet Code
                                                    • IBM Portlet API JSPs
                                                    • JSR 168 JSPs
                                                      • Summary
Page 36: Difference Bw Jsr168 and Ibm

Figure 8 View mode of the Bookmark portlet after adding the WSRP bookmark

Figure 8

After we press the ldquoAddrdquo 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

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

bull use JSPs for rendering the output bull customize the portlet output taking user specific data into account bull 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

61 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 comibmwpssampleswp5

import javaio

import javautil

import orgapachejetspeedportlet

import orgapachejetspeedportletevent

public class IbmBookmark extends PortletAdapter implements ActionListener

public void init(PortletConfig portletConfig) throws UnavailableException

superinit(portletConfig)

- 36 -

public void doView(PortletRequest request PortletResponse response)

throws PortletException IOException

String jspName = thisgetPortletConfig()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 = responsecreateReturnURI()

addURIaddAction(add)

requestsetAttribute(addURI addURItoString())

PortletURI cancelURI = responsecreateReturnURI()

requestsetAttribute(cancelURI cancelURItoString())

String jspName = thisgetPortletConfig()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 ldquocancelrdquo and ldquoaddrdquo URLs are created inside the portlet and attached to the request before including the Edit JSP Both URLs are from type ldquoReturnURIrdquo 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 = eventgetRequest()

String action = eventgetActionString()

PortletLog log = getPortletLog()

if ( action=null )

try

if (actionequals(removeURI))

String removeName = requestgetParameter(remove)

PortletData portData = requestgetData()

portDataremoveAttribute(removeName)

portDatastore()

if (actionequals(add))

PortletData portData = requestgetData()

String name = requestgetParameter(name)

String value = requestgetParameter(value)

portDatasetAttribute(name value)

portDatastore()

catch ( AccessDeniedException ade )

logerror(AccessDeniedException occured when adding or deleting a bookmark)

catch ( IOException ioe )

logerror(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 ldquoaddrdquo or ldquodeleterdquo 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 ldquoaddrdquo or ldquoremoveURIrdquo If the user has clicked on the ldquoremoverdquo button the corresponding link is removed from the portlet data whereas if ldquoaddrdquo was clicked the data entered by the user is added to the portlet data

62 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 comibmwpssamplesjsr

import javaio

import javaxportlet

public class Bookmark extends GenericPortlet

public void init(PortletConfig config) throws PortletException

superinit(config)

public void doView(RenderRequest request RenderResponse response)

throws PortletException IOException

responsesetContentType(texthtml)

String jspName = getPortletConfig()getInitParameter(jspView)

PortletRequestDispatcher rd = getPortletContext()getRequestDispatcher(jspName)

rdinclude(requestresponse)

- 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

responsesetContentType(texthtml)

PortletURL addUrl = responsecreateActionURL()

addUrlsetPortletMode(PortletModeVIEW)

addUrlsetParameter(addadd)

requestsetAttribute(addUrladdUrltoString())

PortletURL cancelUrl = responsecreateRenderURL()

cancelUrlsetPortletMode(PortletModeVIEW)

requestsetAttribute(cancelUrlcancelUrltoString())

String jspName = getPortletConfig()getInitParameter(jspEdit)

PortletRequestDispatcher rd = getPortletContext()getRequestDispatcher(jspName)

rdinclude(requestresponse)

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 ldquoaddrdquo button URL an action URL is created as we need to store the user input of the add form persistently For the ldquocancelrdquo 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 = requestgetParameter(remove)

if (removeName = null)

PortletPreferences prefs = requestgetPreferences()

prefsreset(removeName)

prefsstore()

String add = requestgetParameter(add)

if (add = null)

PortletPreferences prefs = requestgetPreferences()

String name = requestgetParameter(name)

String value = requestgetParameter(value)

prefssetValue(name value)

prefsstore()

catch ( IOException ioe )

getPortletContextlog(An IO error occured when trying to remove a bookmark)

catch ( PortletException pe )

getPortletContextlog(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

bull 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

bull 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

bull Persistent portlet data The JSR 168 persistent data PortletPreferences have an API similar to the JDK 14 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

bull 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

63 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

lt page contentType=texthtml import=javautil comibmwpssampleswp5

orgapachejetspeedportlet session=falsegt

lt taglib uri=WEB-INFtldportlettld prefix=portletAPI gt

- 42 -

ltportletAPIinitgt

ltp class=wpsPortletHeadgtltportletAPItext key=available_bookmarks

bundle=nlsTextgtAvailable BookmarksltportletAPItextgtltpgt

lt

PortletData prefs = portletRequestgetData()

Enumeration e = prefsgetAttributeNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltportletAPItext key=no_bookmarks bundle=nlsTextgtNo

bookmarksltportletAPItextgtltpgt

lt

else

gt

ltp class=wpsIndentMediumgt

lt

while (ehasMoreElements())

String name = (String)enextElement()

String value = (String)prefsgetAttribute(name)

gt

lta href=lt=valuegt target=_blankgtlt=namegtltagtltbr gt

lt

gt

ltpgt

The View JSP first call portletAPIinit 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

lt page contentType=texthtml import=javautil

comibmwpssampleswp5orgapachejetspeedportlet session=falsegt

lt taglib uri=WEB-INFtldportlettld prefix=portletAPI gt

ltjspuseBean id=addURI class=javalangString scope=request gt

ltjspuseBean id=cancelURI class=javalangString scope=request gt

ltportletAPIinitgt

lth4gtltportletAPItext key=available_bookmarks bundle=nlsTextgtAvailable

BookmarksltportletAPItextgtlth4gt

lttable class=wpsTablegt

lttr class=wpsTableRowgt

ltth class=portlet-table-headergtltportletAPItext key=name bundle=nlsTextgtltthgt

ltth class=portlet-table-headergtltportletAPItext key=url bundle=nlsTextgtltthgt

lttdgtlttdgt

lttrgt

lt

PortletData prefs = portletRequestgetData()

Enumeration e = prefsgetAttributeNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltportletAPItext key=no_bookmarks bundle=nlsTextgtNo

bookmarksltportletAPItextgtltpgt

lt

else

while (ehasMoreElements())

- 44 -

String name = (String)enextElement()

String value = (String)prefsgetAttribute(name)

gt

lttr class=wpsTableRowgt

lttdgt lt=namegt lttdgt

lttdgt lt=valuegt lttdgt

lttdgt lta href=ltportletAPIcreateURIgtltportletAPIURIAction

name=removeURIgtltportletAPIURIParameter name=remove

value=lt=namegtgtltportletAPIcreateURIgtgt

(ltportletAPItext key=delete bundle=nlsTextgt)ltagt

lttdgt

lttrgt

lt

gt

ltform action=lt=addURIgt method=POSTgt

lttr class=wpsTableRowgt

lttdgtltinput name=ltportletAPIencodeNamespace value=namegt type=text

class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=ltportletAPIencodeNamespace value=valuegt type=text

class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=ltportletAPIencodeNamespace value=addgt type=submit

value=ltportletAPItext key=add bundle=nlsTextgt class=portlet-form-buttongtlttdgt

lttrgt

ltformgt

lttablegt

- 45 -

ltform action=lt=cancelURIgt method=postgt

ltinput name=ltportletAPIencodeNamespace value=cancelgt type=submit

value=ltportletAPItext key=cancel bundle=nlsTextgt class=portlet-form-buttongt

ltformgt

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 ldquodeleterdquo button for which an URL with the action ldquoremoveURIrdquo 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 ldquocancelrdquo button from the request

64 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

lt page import=javaxportlet javautil session=falsegt

lt taglib uri=httpjavasuncomportlet prefix=portletAPI gt

lt taglib prefix=fmt uri=httpjavasuncomjstlfmt gt

ltportletAPIdefineObjects gt

ltfmtsetBundle basename=nlsTextgt

lt

ResourceBundle myText = ResourceBundlegetBundle(nlsText requestgetLocale())

gt

lth4gtltfmtmessage key=available_bookmarksgtlth4gt

lt

PortletPreferences prefs = renderRequestgetPreferences()

Enumeration e = prefsgetNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltfmtmessage key=no_bookmarksgtltpgt

- 46 -

lt

else

gt

ltpgt

lt

while (ehasMoreElements())

String name = (String)enextElement()

String value = prefsgetValue(namelt+myTextgetString(undefined)+gt)

gt

lta href=lt=valuegt target=_blankgtlt=namegtltagtltbr gt

lt

gt

ltpgt

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 fmtmessage 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

lt page import=javaxportlet javautil session=false gt

lt taglib uri=httpjavasuncomportlet prefix=portletAPI gt

lt taglib prefix=fmt uri=httpjavasuncomjstlfmt gt

ltjspuseBean id=addUrl scope=request class=javalangString gt

ltjspuseBean id=cancelUrl scope=request class=javalangString gt

- 47 -

ltportletAPIdefineObjectsgt

lt

ResourceBundle myText = ResourceBundlegetBundle(nlsText requestgetLocale())

gt

ltfmtsetBundle basename=nlsTextgt

lth4gtltfmtmessage key=available_bookmarksgtlth4gt

lttable class=wpsTablegt

lttr class=wpsTableRowgt

ltth class=wpsTableHeadgtltfmtmessage key=namegtltthgt

ltth class=wpsTableHeadgtltfmtmessage key=urlgtltthgt

lttdgtlttdgt

lttrgt

lt

PortletPreferences prefs = renderRequestgetPreferences()

Enumeration e = prefsgetNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltfmtmessage key=no_bookmarksgtltpgt

lt

else

while (ehasMoreElements())

String name = (String)enextElement()

String value = prefsgetValue(namelt+myTextgetString(undefined)+gt)

gt

lttr class=wpsTableRowgt

lttdgt lt=namegt lttdgt

lttdgt lt=valuegt lttdgt

- 48 -

lttdgt ltportletAPIactionURL var=removeUrlgt

ltportletAPIparam name=remove value=lt=namegtgt

ltportletAPIactionURLgt

lta href=lt=removeUrltoString()gtgt(ltfmtmessage key=deletegt)ltagt

lttdgt

lttrgt

lt

gt

ltform action=lt=addUrlgt method=POSTgt

lttr class=wpsTableRowgt

lttdgtltinput name=name type=text class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=value type=text class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=add type=submit value=ltfmtmessage key=addgt

class=portlet-form-buttongtlttdgt

lttrgt

ltformgt

lttablegt

ltform action=lt=cancelUrlgt method=postgt

ltinput name=cancel type=submit value=ltfmtmessage key=cancelgt class=portlet-

form-buttongt

ltformgt

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 14 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 -

- 51 -

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 (eg eventing) the IBM Portlet API still needs to be used Trademarks bull IBM and WebSphere are trademarks or registered trademarks of IBM Corporation in

the United States other countries or both bull 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 bull Other company product and service names may be trademarks or service marks of

others IBM copyright and trademark information httpwwwibmcomlegalcopytradephtml

  • Introduction
  • JSR 168 and the Java Community Process
  • Comparing concepts
    • Basic concepts
      • Portal
      • Portal page
      • Portlet
      • Portlet Container
        • Concepts that are the same
          • Portlet mode
          • Window state
          • Portlet life cycle and request processing
          • URL encoding
          • Include servletsJSPs
          • Portlet application packaging
          • Expiration-based caching
            • Concepts that differ
              • Portlet application entity
              • Portlet entity
              • Action and Render Request Response objects
              • Window concept
              • Portlet API does not extend servlet API
              • TAG libraries
                • Concepts new in the JSR 168
                  • Render parameter
                  • Extension mechanisms
                    • Custom window states
                    • Custom portlet modes
                    • Custom user info
                    • Request Response properties
                      • Web application session scope
                      • Reuse of the HttpSession listeners
                      • J2EE role support
                      • Resource bundles
                      • Multiple response content types
                      • Redirect in action
                      • Preference validator
                      • Portal context
                      • Localization support
                        • Concepts missing in the JSR 168
                          • Eventing
                          • Additional lifecycle events
                          • Property broker
                          • Portlet Menus
                          • Portlet Services
                          • Invalidation-based caching
                            • Alignment with WSRP
                              • Outlook for the next version of the JSR 168
                              • Guidelines for programming IBM Portlet API portlets
                                • Similar Functionality
                                  • Basic programming model
                                  • Portlet private session
                                  • User profile information
                                  • Persistent data
                                  • Portlet modes and window states
                                  • Expiration-based caching
                                    • Slightly different functionality
                                      • Sharing of data between portlets
                                      • Session listeners
                                        • New JSR 168 functionality
                                          • Navigational state (render parameters)
                                            • Pitfalls
                                              • Request response objects for action and render phase
                                              • Include search path
                                              • Form parameter encoding
                                              • Title setting
                                                  • Examples
                                                    • IBM Portlet API Portlet Code
                                                    • JSR 168 Portlet Code
                                                    • IBM Portlet API JSPs
                                                    • JSR 168 JSPs
                                                      • Summary
Page 37: Difference Bw Jsr168 and Ibm

public void doView(PortletRequest request PortletResponse response)

throws PortletException IOException

String jspName = thisgetPortletConfig()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 = responsecreateReturnURI()

addURIaddAction(add)

requestsetAttribute(addURI addURItoString())

PortletURI cancelURI = responsecreateReturnURI()

requestsetAttribute(cancelURI cancelURItoString())

String jspName = thisgetPortletConfig()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 ldquocancelrdquo and ldquoaddrdquo URLs are created inside the portlet and attached to the request before including the Edit JSP Both URLs are from type ldquoReturnURIrdquo 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 = eventgetRequest()

String action = eventgetActionString()

PortletLog log = getPortletLog()

if ( action=null )

try

if (actionequals(removeURI))

String removeName = requestgetParameter(remove)

PortletData portData = requestgetData()

portDataremoveAttribute(removeName)

portDatastore()

if (actionequals(add))

PortletData portData = requestgetData()

String name = requestgetParameter(name)

String value = requestgetParameter(value)

portDatasetAttribute(name value)

portDatastore()

catch ( AccessDeniedException ade )

logerror(AccessDeniedException occured when adding or deleting a bookmark)

catch ( IOException ioe )

logerror(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 ldquoaddrdquo or ldquodeleterdquo 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 ldquoaddrdquo or ldquoremoveURIrdquo If the user has clicked on the ldquoremoverdquo button the corresponding link is removed from the portlet data whereas if ldquoaddrdquo was clicked the data entered by the user is added to the portlet data

62 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 comibmwpssamplesjsr

import javaio

import javaxportlet

public class Bookmark extends GenericPortlet

public void init(PortletConfig config) throws PortletException

superinit(config)

public void doView(RenderRequest request RenderResponse response)

throws PortletException IOException

responsesetContentType(texthtml)

String jspName = getPortletConfig()getInitParameter(jspView)

PortletRequestDispatcher rd = getPortletContext()getRequestDispatcher(jspName)

rdinclude(requestresponse)

- 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

responsesetContentType(texthtml)

PortletURL addUrl = responsecreateActionURL()

addUrlsetPortletMode(PortletModeVIEW)

addUrlsetParameter(addadd)

requestsetAttribute(addUrladdUrltoString())

PortletURL cancelUrl = responsecreateRenderURL()

cancelUrlsetPortletMode(PortletModeVIEW)

requestsetAttribute(cancelUrlcancelUrltoString())

String jspName = getPortletConfig()getInitParameter(jspEdit)

PortletRequestDispatcher rd = getPortletContext()getRequestDispatcher(jspName)

rdinclude(requestresponse)

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 ldquoaddrdquo button URL an action URL is created as we need to store the user input of the add form persistently For the ldquocancelrdquo 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 = requestgetParameter(remove)

if (removeName = null)

PortletPreferences prefs = requestgetPreferences()

prefsreset(removeName)

prefsstore()

String add = requestgetParameter(add)

if (add = null)

PortletPreferences prefs = requestgetPreferences()

String name = requestgetParameter(name)

String value = requestgetParameter(value)

prefssetValue(name value)

prefsstore()

catch ( IOException ioe )

getPortletContextlog(An IO error occured when trying to remove a bookmark)

catch ( PortletException pe )

getPortletContextlog(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

bull 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

bull 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

bull Persistent portlet data The JSR 168 persistent data PortletPreferences have an API similar to the JDK 14 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

bull 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

63 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

lt page contentType=texthtml import=javautil comibmwpssampleswp5

orgapachejetspeedportlet session=falsegt

lt taglib uri=WEB-INFtldportlettld prefix=portletAPI gt

- 42 -

ltportletAPIinitgt

ltp class=wpsPortletHeadgtltportletAPItext key=available_bookmarks

bundle=nlsTextgtAvailable BookmarksltportletAPItextgtltpgt

lt

PortletData prefs = portletRequestgetData()

Enumeration e = prefsgetAttributeNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltportletAPItext key=no_bookmarks bundle=nlsTextgtNo

bookmarksltportletAPItextgtltpgt

lt

else

gt

ltp class=wpsIndentMediumgt

lt

while (ehasMoreElements())

String name = (String)enextElement()

String value = (String)prefsgetAttribute(name)

gt

lta href=lt=valuegt target=_blankgtlt=namegtltagtltbr gt

lt

gt

ltpgt

The View JSP first call portletAPIinit 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

lt page contentType=texthtml import=javautil

comibmwpssampleswp5orgapachejetspeedportlet session=falsegt

lt taglib uri=WEB-INFtldportlettld prefix=portletAPI gt

ltjspuseBean id=addURI class=javalangString scope=request gt

ltjspuseBean id=cancelURI class=javalangString scope=request gt

ltportletAPIinitgt

lth4gtltportletAPItext key=available_bookmarks bundle=nlsTextgtAvailable

BookmarksltportletAPItextgtlth4gt

lttable class=wpsTablegt

lttr class=wpsTableRowgt

ltth class=portlet-table-headergtltportletAPItext key=name bundle=nlsTextgtltthgt

ltth class=portlet-table-headergtltportletAPItext key=url bundle=nlsTextgtltthgt

lttdgtlttdgt

lttrgt

lt

PortletData prefs = portletRequestgetData()

Enumeration e = prefsgetAttributeNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltportletAPItext key=no_bookmarks bundle=nlsTextgtNo

bookmarksltportletAPItextgtltpgt

lt

else

while (ehasMoreElements())

- 44 -

String name = (String)enextElement()

String value = (String)prefsgetAttribute(name)

gt

lttr class=wpsTableRowgt

lttdgt lt=namegt lttdgt

lttdgt lt=valuegt lttdgt

lttdgt lta href=ltportletAPIcreateURIgtltportletAPIURIAction

name=removeURIgtltportletAPIURIParameter name=remove

value=lt=namegtgtltportletAPIcreateURIgtgt

(ltportletAPItext key=delete bundle=nlsTextgt)ltagt

lttdgt

lttrgt

lt

gt

ltform action=lt=addURIgt method=POSTgt

lttr class=wpsTableRowgt

lttdgtltinput name=ltportletAPIencodeNamespace value=namegt type=text

class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=ltportletAPIencodeNamespace value=valuegt type=text

class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=ltportletAPIencodeNamespace value=addgt type=submit

value=ltportletAPItext key=add bundle=nlsTextgt class=portlet-form-buttongtlttdgt

lttrgt

ltformgt

lttablegt

- 45 -

ltform action=lt=cancelURIgt method=postgt

ltinput name=ltportletAPIencodeNamespace value=cancelgt type=submit

value=ltportletAPItext key=cancel bundle=nlsTextgt class=portlet-form-buttongt

ltformgt

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 ldquodeleterdquo button for which an URL with the action ldquoremoveURIrdquo 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 ldquocancelrdquo button from the request

64 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

lt page import=javaxportlet javautil session=falsegt

lt taglib uri=httpjavasuncomportlet prefix=portletAPI gt

lt taglib prefix=fmt uri=httpjavasuncomjstlfmt gt

ltportletAPIdefineObjects gt

ltfmtsetBundle basename=nlsTextgt

lt

ResourceBundle myText = ResourceBundlegetBundle(nlsText requestgetLocale())

gt

lth4gtltfmtmessage key=available_bookmarksgtlth4gt

lt

PortletPreferences prefs = renderRequestgetPreferences()

Enumeration e = prefsgetNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltfmtmessage key=no_bookmarksgtltpgt

- 46 -

lt

else

gt

ltpgt

lt

while (ehasMoreElements())

String name = (String)enextElement()

String value = prefsgetValue(namelt+myTextgetString(undefined)+gt)

gt

lta href=lt=valuegt target=_blankgtlt=namegtltagtltbr gt

lt

gt

ltpgt

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 fmtmessage 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

lt page import=javaxportlet javautil session=false gt

lt taglib uri=httpjavasuncomportlet prefix=portletAPI gt

lt taglib prefix=fmt uri=httpjavasuncomjstlfmt gt

ltjspuseBean id=addUrl scope=request class=javalangString gt

ltjspuseBean id=cancelUrl scope=request class=javalangString gt

- 47 -

ltportletAPIdefineObjectsgt

lt

ResourceBundle myText = ResourceBundlegetBundle(nlsText requestgetLocale())

gt

ltfmtsetBundle basename=nlsTextgt

lth4gtltfmtmessage key=available_bookmarksgtlth4gt

lttable class=wpsTablegt

lttr class=wpsTableRowgt

ltth class=wpsTableHeadgtltfmtmessage key=namegtltthgt

ltth class=wpsTableHeadgtltfmtmessage key=urlgtltthgt

lttdgtlttdgt

lttrgt

lt

PortletPreferences prefs = renderRequestgetPreferences()

Enumeration e = prefsgetNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltfmtmessage key=no_bookmarksgtltpgt

lt

else

while (ehasMoreElements())

String name = (String)enextElement()

String value = prefsgetValue(namelt+myTextgetString(undefined)+gt)

gt

lttr class=wpsTableRowgt

lttdgt lt=namegt lttdgt

lttdgt lt=valuegt lttdgt

- 48 -

lttdgt ltportletAPIactionURL var=removeUrlgt

ltportletAPIparam name=remove value=lt=namegtgt

ltportletAPIactionURLgt

lta href=lt=removeUrltoString()gtgt(ltfmtmessage key=deletegt)ltagt

lttdgt

lttrgt

lt

gt

ltform action=lt=addUrlgt method=POSTgt

lttr class=wpsTableRowgt

lttdgtltinput name=name type=text class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=value type=text class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=add type=submit value=ltfmtmessage key=addgt

class=portlet-form-buttongtlttdgt

lttrgt

ltformgt

lttablegt

ltform action=lt=cancelUrlgt method=postgt

ltinput name=cancel type=submit value=ltfmtmessage key=cancelgt class=portlet-

form-buttongt

ltformgt

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 14 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 -

- 51 -

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 (eg eventing) the IBM Portlet API still needs to be used Trademarks bull IBM and WebSphere are trademarks or registered trademarks of IBM Corporation in

the United States other countries or both bull 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 bull Other company product and service names may be trademarks or service marks of

others IBM copyright and trademark information httpwwwibmcomlegalcopytradephtml

  • Introduction
  • JSR 168 and the Java Community Process
  • Comparing concepts
    • Basic concepts
      • Portal
      • Portal page
      • Portlet
      • Portlet Container
        • Concepts that are the same
          • Portlet mode
          • Window state
          • Portlet life cycle and request processing
          • URL encoding
          • Include servletsJSPs
          • Portlet application packaging
          • Expiration-based caching
            • Concepts that differ
              • Portlet application entity
              • Portlet entity
              • Action and Render Request Response objects
              • Window concept
              • Portlet API does not extend servlet API
              • TAG libraries
                • Concepts new in the JSR 168
                  • Render parameter
                  • Extension mechanisms
                    • Custom window states
                    • Custom portlet modes
                    • Custom user info
                    • Request Response properties
                      • Web application session scope
                      • Reuse of the HttpSession listeners
                      • J2EE role support
                      • Resource bundles
                      • Multiple response content types
                      • Redirect in action
                      • Preference validator
                      • Portal context
                      • Localization support
                        • Concepts missing in the JSR 168
                          • Eventing
                          • Additional lifecycle events
                          • Property broker
                          • Portlet Menus
                          • Portlet Services
                          • Invalidation-based caching
                            • Alignment with WSRP
                              • Outlook for the next version of the JSR 168
                              • Guidelines for programming IBM Portlet API portlets
                                • Similar Functionality
                                  • Basic programming model
                                  • Portlet private session
                                  • User profile information
                                  • Persistent data
                                  • Portlet modes and window states
                                  • Expiration-based caching
                                    • Slightly different functionality
                                      • Sharing of data between portlets
                                      • Session listeners
                                        • New JSR 168 functionality
                                          • Navigational state (render parameters)
                                            • Pitfalls
                                              • Request response objects for action and render phase
                                              • Include search path
                                              • Form parameter encoding
                                              • Title setting
                                                  • Examples
                                                    • IBM Portlet API Portlet Code
                                                    • JSR 168 Portlet Code
                                                    • IBM Portlet API JSPs
                                                    • JSR 168 JSPs
                                                      • Summary
Page 38: Difference Bw Jsr168 and Ibm

public void actionPerformed(ActionEvent event) throws PortletException

PortletRequest request = eventgetRequest()

String action = eventgetActionString()

PortletLog log = getPortletLog()

if ( action=null )

try

if (actionequals(removeURI))

String removeName = requestgetParameter(remove)

PortletData portData = requestgetData()

portDataremoveAttribute(removeName)

portDatastore()

if (actionequals(add))

PortletData portData = requestgetData()

String name = requestgetParameter(name)

String value = requestgetParameter(value)

portDatasetAttribute(name value)

portDatastore()

catch ( AccessDeniedException ade )

logerror(AccessDeniedException occured when adding or deleting a bookmark)

catch ( IOException ioe )

logerror(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 ldquoaddrdquo or ldquodeleterdquo 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 ldquoaddrdquo or ldquoremoveURIrdquo If the user has clicked on the ldquoremoverdquo button the corresponding link is removed from the portlet data whereas if ldquoaddrdquo was clicked the data entered by the user is added to the portlet data

62 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 comibmwpssamplesjsr

import javaio

import javaxportlet

public class Bookmark extends GenericPortlet

public void init(PortletConfig config) throws PortletException

superinit(config)

public void doView(RenderRequest request RenderResponse response)

throws PortletException IOException

responsesetContentType(texthtml)

String jspName = getPortletConfig()getInitParameter(jspView)

PortletRequestDispatcher rd = getPortletContext()getRequestDispatcher(jspName)

rdinclude(requestresponse)

- 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

responsesetContentType(texthtml)

PortletURL addUrl = responsecreateActionURL()

addUrlsetPortletMode(PortletModeVIEW)

addUrlsetParameter(addadd)

requestsetAttribute(addUrladdUrltoString())

PortletURL cancelUrl = responsecreateRenderURL()

cancelUrlsetPortletMode(PortletModeVIEW)

requestsetAttribute(cancelUrlcancelUrltoString())

String jspName = getPortletConfig()getInitParameter(jspEdit)

PortletRequestDispatcher rd = getPortletContext()getRequestDispatcher(jspName)

rdinclude(requestresponse)

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 ldquoaddrdquo button URL an action URL is created as we need to store the user input of the add form persistently For the ldquocancelrdquo 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 = requestgetParameter(remove)

if (removeName = null)

PortletPreferences prefs = requestgetPreferences()

prefsreset(removeName)

prefsstore()

String add = requestgetParameter(add)

if (add = null)

PortletPreferences prefs = requestgetPreferences()

String name = requestgetParameter(name)

String value = requestgetParameter(value)

prefssetValue(name value)

prefsstore()

catch ( IOException ioe )

getPortletContextlog(An IO error occured when trying to remove a bookmark)

catch ( PortletException pe )

getPortletContextlog(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

bull 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

bull 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

bull Persistent portlet data The JSR 168 persistent data PortletPreferences have an API similar to the JDK 14 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

bull 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

63 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

lt page contentType=texthtml import=javautil comibmwpssampleswp5

orgapachejetspeedportlet session=falsegt

lt taglib uri=WEB-INFtldportlettld prefix=portletAPI gt

- 42 -

ltportletAPIinitgt

ltp class=wpsPortletHeadgtltportletAPItext key=available_bookmarks

bundle=nlsTextgtAvailable BookmarksltportletAPItextgtltpgt

lt

PortletData prefs = portletRequestgetData()

Enumeration e = prefsgetAttributeNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltportletAPItext key=no_bookmarks bundle=nlsTextgtNo

bookmarksltportletAPItextgtltpgt

lt

else

gt

ltp class=wpsIndentMediumgt

lt

while (ehasMoreElements())

String name = (String)enextElement()

String value = (String)prefsgetAttribute(name)

gt

lta href=lt=valuegt target=_blankgtlt=namegtltagtltbr gt

lt

gt

ltpgt

The View JSP first call portletAPIinit 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

lt page contentType=texthtml import=javautil

comibmwpssampleswp5orgapachejetspeedportlet session=falsegt

lt taglib uri=WEB-INFtldportlettld prefix=portletAPI gt

ltjspuseBean id=addURI class=javalangString scope=request gt

ltjspuseBean id=cancelURI class=javalangString scope=request gt

ltportletAPIinitgt

lth4gtltportletAPItext key=available_bookmarks bundle=nlsTextgtAvailable

BookmarksltportletAPItextgtlth4gt

lttable class=wpsTablegt

lttr class=wpsTableRowgt

ltth class=portlet-table-headergtltportletAPItext key=name bundle=nlsTextgtltthgt

ltth class=portlet-table-headergtltportletAPItext key=url bundle=nlsTextgtltthgt

lttdgtlttdgt

lttrgt

lt

PortletData prefs = portletRequestgetData()

Enumeration e = prefsgetAttributeNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltportletAPItext key=no_bookmarks bundle=nlsTextgtNo

bookmarksltportletAPItextgtltpgt

lt

else

while (ehasMoreElements())

- 44 -

String name = (String)enextElement()

String value = (String)prefsgetAttribute(name)

gt

lttr class=wpsTableRowgt

lttdgt lt=namegt lttdgt

lttdgt lt=valuegt lttdgt

lttdgt lta href=ltportletAPIcreateURIgtltportletAPIURIAction

name=removeURIgtltportletAPIURIParameter name=remove

value=lt=namegtgtltportletAPIcreateURIgtgt

(ltportletAPItext key=delete bundle=nlsTextgt)ltagt

lttdgt

lttrgt

lt

gt

ltform action=lt=addURIgt method=POSTgt

lttr class=wpsTableRowgt

lttdgtltinput name=ltportletAPIencodeNamespace value=namegt type=text

class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=ltportletAPIencodeNamespace value=valuegt type=text

class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=ltportletAPIencodeNamespace value=addgt type=submit

value=ltportletAPItext key=add bundle=nlsTextgt class=portlet-form-buttongtlttdgt

lttrgt

ltformgt

lttablegt

- 45 -

ltform action=lt=cancelURIgt method=postgt

ltinput name=ltportletAPIencodeNamespace value=cancelgt type=submit

value=ltportletAPItext key=cancel bundle=nlsTextgt class=portlet-form-buttongt

ltformgt

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 ldquodeleterdquo button for which an URL with the action ldquoremoveURIrdquo 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 ldquocancelrdquo button from the request

64 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

lt page import=javaxportlet javautil session=falsegt

lt taglib uri=httpjavasuncomportlet prefix=portletAPI gt

lt taglib prefix=fmt uri=httpjavasuncomjstlfmt gt

ltportletAPIdefineObjects gt

ltfmtsetBundle basename=nlsTextgt

lt

ResourceBundle myText = ResourceBundlegetBundle(nlsText requestgetLocale())

gt

lth4gtltfmtmessage key=available_bookmarksgtlth4gt

lt

PortletPreferences prefs = renderRequestgetPreferences()

Enumeration e = prefsgetNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltfmtmessage key=no_bookmarksgtltpgt

- 46 -

lt

else

gt

ltpgt

lt

while (ehasMoreElements())

String name = (String)enextElement()

String value = prefsgetValue(namelt+myTextgetString(undefined)+gt)

gt

lta href=lt=valuegt target=_blankgtlt=namegtltagtltbr gt

lt

gt

ltpgt

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 fmtmessage 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

lt page import=javaxportlet javautil session=false gt

lt taglib uri=httpjavasuncomportlet prefix=portletAPI gt

lt taglib prefix=fmt uri=httpjavasuncomjstlfmt gt

ltjspuseBean id=addUrl scope=request class=javalangString gt

ltjspuseBean id=cancelUrl scope=request class=javalangString gt

- 47 -

ltportletAPIdefineObjectsgt

lt

ResourceBundle myText = ResourceBundlegetBundle(nlsText requestgetLocale())

gt

ltfmtsetBundle basename=nlsTextgt

lth4gtltfmtmessage key=available_bookmarksgtlth4gt

lttable class=wpsTablegt

lttr class=wpsTableRowgt

ltth class=wpsTableHeadgtltfmtmessage key=namegtltthgt

ltth class=wpsTableHeadgtltfmtmessage key=urlgtltthgt

lttdgtlttdgt

lttrgt

lt

PortletPreferences prefs = renderRequestgetPreferences()

Enumeration e = prefsgetNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltfmtmessage key=no_bookmarksgtltpgt

lt

else

while (ehasMoreElements())

String name = (String)enextElement()

String value = prefsgetValue(namelt+myTextgetString(undefined)+gt)

gt

lttr class=wpsTableRowgt

lttdgt lt=namegt lttdgt

lttdgt lt=valuegt lttdgt

- 48 -

lttdgt ltportletAPIactionURL var=removeUrlgt

ltportletAPIparam name=remove value=lt=namegtgt

ltportletAPIactionURLgt

lta href=lt=removeUrltoString()gtgt(ltfmtmessage key=deletegt)ltagt

lttdgt

lttrgt

lt

gt

ltform action=lt=addUrlgt method=POSTgt

lttr class=wpsTableRowgt

lttdgtltinput name=name type=text class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=value type=text class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=add type=submit value=ltfmtmessage key=addgt

class=portlet-form-buttongtlttdgt

lttrgt

ltformgt

lttablegt

ltform action=lt=cancelUrlgt method=postgt

ltinput name=cancel type=submit value=ltfmtmessage key=cancelgt class=portlet-

form-buttongt

ltformgt

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 14 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 -

- 51 -

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 (eg eventing) the IBM Portlet API still needs to be used Trademarks bull IBM and WebSphere are trademarks or registered trademarks of IBM Corporation in

the United States other countries or both bull 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 bull Other company product and service names may be trademarks or service marks of

others IBM copyright and trademark information httpwwwibmcomlegalcopytradephtml

  • Introduction
  • JSR 168 and the Java Community Process
  • Comparing concepts
    • Basic concepts
      • Portal
      • Portal page
      • Portlet
      • Portlet Container
        • Concepts that are the same
          • Portlet mode
          • Window state
          • Portlet life cycle and request processing
          • URL encoding
          • Include servletsJSPs
          • Portlet application packaging
          • Expiration-based caching
            • Concepts that differ
              • Portlet application entity
              • Portlet entity
              • Action and Render Request Response objects
              • Window concept
              • Portlet API does not extend servlet API
              • TAG libraries
                • Concepts new in the JSR 168
                  • Render parameter
                  • Extension mechanisms
                    • Custom window states
                    • Custom portlet modes
                    • Custom user info
                    • Request Response properties
                      • Web application session scope
                      • Reuse of the HttpSession listeners
                      • J2EE role support
                      • Resource bundles
                      • Multiple response content types
                      • Redirect in action
                      • Preference validator
                      • Portal context
                      • Localization support
                        • Concepts missing in the JSR 168
                          • Eventing
                          • Additional lifecycle events
                          • Property broker
                          • Portlet Menus
                          • Portlet Services
                          • Invalidation-based caching
                            • Alignment with WSRP
                              • Outlook for the next version of the JSR 168
                              • Guidelines for programming IBM Portlet API portlets
                                • Similar Functionality
                                  • Basic programming model
                                  • Portlet private session
                                  • User profile information
                                  • Persistent data
                                  • Portlet modes and window states
                                  • Expiration-based caching
                                    • Slightly different functionality
                                      • Sharing of data between portlets
                                      • Session listeners
                                        • New JSR 168 functionality
                                          • Navigational state (render parameters)
                                            • Pitfalls
                                              • Request response objects for action and render phase
                                              • Include search path
                                              • Form parameter encoding
                                              • Title setting
                                                  • Examples
                                                    • IBM Portlet API Portlet Code
                                                    • JSR 168 Portlet Code
                                                    • IBM Portlet API JSPs
                                                    • JSR 168 JSPs
                                                      • Summary
Page 39: Difference Bw Jsr168 and Ibm

The third part shows the action handling The actionPerformed method is called when the user clicks on one of the buttons ldquoaddrdquo or ldquodeleterdquo 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 ldquoaddrdquo or ldquoremoveURIrdquo If the user has clicked on the ldquoremoverdquo button the corresponding link is removed from the portlet data whereas if ldquoaddrdquo was clicked the data entered by the user is added to the portlet data

62 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 comibmwpssamplesjsr

import javaio

import javaxportlet

public class Bookmark extends GenericPortlet

public void init(PortletConfig config) throws PortletException

superinit(config)

public void doView(RenderRequest request RenderResponse response)

throws PortletException IOException

responsesetContentType(texthtml)

String jspName = getPortletConfig()getInitParameter(jspView)

PortletRequestDispatcher rd = getPortletContext()getRequestDispatcher(jspName)

rdinclude(requestresponse)

- 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

responsesetContentType(texthtml)

PortletURL addUrl = responsecreateActionURL()

addUrlsetPortletMode(PortletModeVIEW)

addUrlsetParameter(addadd)

requestsetAttribute(addUrladdUrltoString())

PortletURL cancelUrl = responsecreateRenderURL()

cancelUrlsetPortletMode(PortletModeVIEW)

requestsetAttribute(cancelUrlcancelUrltoString())

String jspName = getPortletConfig()getInitParameter(jspEdit)

PortletRequestDispatcher rd = getPortletContext()getRequestDispatcher(jspName)

rdinclude(requestresponse)

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 ldquoaddrdquo button URL an action URL is created as we need to store the user input of the add form persistently For the ldquocancelrdquo 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 = requestgetParameter(remove)

if (removeName = null)

PortletPreferences prefs = requestgetPreferences()

prefsreset(removeName)

prefsstore()

String add = requestgetParameter(add)

if (add = null)

PortletPreferences prefs = requestgetPreferences()

String name = requestgetParameter(name)

String value = requestgetParameter(value)

prefssetValue(name value)

prefsstore()

catch ( IOException ioe )

getPortletContextlog(An IO error occured when trying to remove a bookmark)

catch ( PortletException pe )

getPortletContextlog(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

bull 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

bull 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

bull Persistent portlet data The JSR 168 persistent data PortletPreferences have an API similar to the JDK 14 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

bull 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

63 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

lt page contentType=texthtml import=javautil comibmwpssampleswp5

orgapachejetspeedportlet session=falsegt

lt taglib uri=WEB-INFtldportlettld prefix=portletAPI gt

- 42 -

ltportletAPIinitgt

ltp class=wpsPortletHeadgtltportletAPItext key=available_bookmarks

bundle=nlsTextgtAvailable BookmarksltportletAPItextgtltpgt

lt

PortletData prefs = portletRequestgetData()

Enumeration e = prefsgetAttributeNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltportletAPItext key=no_bookmarks bundle=nlsTextgtNo

bookmarksltportletAPItextgtltpgt

lt

else

gt

ltp class=wpsIndentMediumgt

lt

while (ehasMoreElements())

String name = (String)enextElement()

String value = (String)prefsgetAttribute(name)

gt

lta href=lt=valuegt target=_blankgtlt=namegtltagtltbr gt

lt

gt

ltpgt

The View JSP first call portletAPIinit 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

lt page contentType=texthtml import=javautil

comibmwpssampleswp5orgapachejetspeedportlet session=falsegt

lt taglib uri=WEB-INFtldportlettld prefix=portletAPI gt

ltjspuseBean id=addURI class=javalangString scope=request gt

ltjspuseBean id=cancelURI class=javalangString scope=request gt

ltportletAPIinitgt

lth4gtltportletAPItext key=available_bookmarks bundle=nlsTextgtAvailable

BookmarksltportletAPItextgtlth4gt

lttable class=wpsTablegt

lttr class=wpsTableRowgt

ltth class=portlet-table-headergtltportletAPItext key=name bundle=nlsTextgtltthgt

ltth class=portlet-table-headergtltportletAPItext key=url bundle=nlsTextgtltthgt

lttdgtlttdgt

lttrgt

lt

PortletData prefs = portletRequestgetData()

Enumeration e = prefsgetAttributeNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltportletAPItext key=no_bookmarks bundle=nlsTextgtNo

bookmarksltportletAPItextgtltpgt

lt

else

while (ehasMoreElements())

- 44 -

String name = (String)enextElement()

String value = (String)prefsgetAttribute(name)

gt

lttr class=wpsTableRowgt

lttdgt lt=namegt lttdgt

lttdgt lt=valuegt lttdgt

lttdgt lta href=ltportletAPIcreateURIgtltportletAPIURIAction

name=removeURIgtltportletAPIURIParameter name=remove

value=lt=namegtgtltportletAPIcreateURIgtgt

(ltportletAPItext key=delete bundle=nlsTextgt)ltagt

lttdgt

lttrgt

lt

gt

ltform action=lt=addURIgt method=POSTgt

lttr class=wpsTableRowgt

lttdgtltinput name=ltportletAPIencodeNamespace value=namegt type=text

class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=ltportletAPIencodeNamespace value=valuegt type=text

class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=ltportletAPIencodeNamespace value=addgt type=submit

value=ltportletAPItext key=add bundle=nlsTextgt class=portlet-form-buttongtlttdgt

lttrgt

ltformgt

lttablegt

- 45 -

ltform action=lt=cancelURIgt method=postgt

ltinput name=ltportletAPIencodeNamespace value=cancelgt type=submit

value=ltportletAPItext key=cancel bundle=nlsTextgt class=portlet-form-buttongt

ltformgt

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 ldquodeleterdquo button for which an URL with the action ldquoremoveURIrdquo 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 ldquocancelrdquo button from the request

64 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

lt page import=javaxportlet javautil session=falsegt

lt taglib uri=httpjavasuncomportlet prefix=portletAPI gt

lt taglib prefix=fmt uri=httpjavasuncomjstlfmt gt

ltportletAPIdefineObjects gt

ltfmtsetBundle basename=nlsTextgt

lt

ResourceBundle myText = ResourceBundlegetBundle(nlsText requestgetLocale())

gt

lth4gtltfmtmessage key=available_bookmarksgtlth4gt

lt

PortletPreferences prefs = renderRequestgetPreferences()

Enumeration e = prefsgetNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltfmtmessage key=no_bookmarksgtltpgt

- 46 -

lt

else

gt

ltpgt

lt

while (ehasMoreElements())

String name = (String)enextElement()

String value = prefsgetValue(namelt+myTextgetString(undefined)+gt)

gt

lta href=lt=valuegt target=_blankgtlt=namegtltagtltbr gt

lt

gt

ltpgt

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 fmtmessage 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

lt page import=javaxportlet javautil session=false gt

lt taglib uri=httpjavasuncomportlet prefix=portletAPI gt

lt taglib prefix=fmt uri=httpjavasuncomjstlfmt gt

ltjspuseBean id=addUrl scope=request class=javalangString gt

ltjspuseBean id=cancelUrl scope=request class=javalangString gt

- 47 -

ltportletAPIdefineObjectsgt

lt

ResourceBundle myText = ResourceBundlegetBundle(nlsText requestgetLocale())

gt

ltfmtsetBundle basename=nlsTextgt

lth4gtltfmtmessage key=available_bookmarksgtlth4gt

lttable class=wpsTablegt

lttr class=wpsTableRowgt

ltth class=wpsTableHeadgtltfmtmessage key=namegtltthgt

ltth class=wpsTableHeadgtltfmtmessage key=urlgtltthgt

lttdgtlttdgt

lttrgt

lt

PortletPreferences prefs = renderRequestgetPreferences()

Enumeration e = prefsgetNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltfmtmessage key=no_bookmarksgtltpgt

lt

else

while (ehasMoreElements())

String name = (String)enextElement()

String value = prefsgetValue(namelt+myTextgetString(undefined)+gt)

gt

lttr class=wpsTableRowgt

lttdgt lt=namegt lttdgt

lttdgt lt=valuegt lttdgt

- 48 -

lttdgt ltportletAPIactionURL var=removeUrlgt

ltportletAPIparam name=remove value=lt=namegtgt

ltportletAPIactionURLgt

lta href=lt=removeUrltoString()gtgt(ltfmtmessage key=deletegt)ltagt

lttdgt

lttrgt

lt

gt

ltform action=lt=addUrlgt method=POSTgt

lttr class=wpsTableRowgt

lttdgtltinput name=name type=text class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=value type=text class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=add type=submit value=ltfmtmessage key=addgt

class=portlet-form-buttongtlttdgt

lttrgt

ltformgt

lttablegt

ltform action=lt=cancelUrlgt method=postgt

ltinput name=cancel type=submit value=ltfmtmessage key=cancelgt class=portlet-

form-buttongt

ltformgt

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 14 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 -

- 51 -

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 (eg eventing) the IBM Portlet API still needs to be used Trademarks bull IBM and WebSphere are trademarks or registered trademarks of IBM Corporation in

the United States other countries or both bull 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 bull Other company product and service names may be trademarks or service marks of

others IBM copyright and trademark information httpwwwibmcomlegalcopytradephtml

  • Introduction
  • JSR 168 and the Java Community Process
  • Comparing concepts
    • Basic concepts
      • Portal
      • Portal page
      • Portlet
      • Portlet Container
        • Concepts that are the same
          • Portlet mode
          • Window state
          • Portlet life cycle and request processing
          • URL encoding
          • Include servletsJSPs
          • Portlet application packaging
          • Expiration-based caching
            • Concepts that differ
              • Portlet application entity
              • Portlet entity
              • Action and Render Request Response objects
              • Window concept
              • Portlet API does not extend servlet API
              • TAG libraries
                • Concepts new in the JSR 168
                  • Render parameter
                  • Extension mechanisms
                    • Custom window states
                    • Custom portlet modes
                    • Custom user info
                    • Request Response properties
                      • Web application session scope
                      • Reuse of the HttpSession listeners
                      • J2EE role support
                      • Resource bundles
                      • Multiple response content types
                      • Redirect in action
                      • Preference validator
                      • Portal context
                      • Localization support
                        • Concepts missing in the JSR 168
                          • Eventing
                          • Additional lifecycle events
                          • Property broker
                          • Portlet Menus
                          • Portlet Services
                          • Invalidation-based caching
                            • Alignment with WSRP
                              • Outlook for the next version of the JSR 168
                              • Guidelines for programming IBM Portlet API portlets
                                • Similar Functionality
                                  • Basic programming model
                                  • Portlet private session
                                  • User profile information
                                  • Persistent data
                                  • Portlet modes and window states
                                  • Expiration-based caching
                                    • Slightly different functionality
                                      • Sharing of data between portlets
                                      • Session listeners
                                        • New JSR 168 functionality
                                          • Navigational state (render parameters)
                                            • Pitfalls
                                              • Request response objects for action and render phase
                                              • Include search path
                                              • Form parameter encoding
                                              • Title setting
                                                  • Examples
                                                    • IBM Portlet API Portlet Code
                                                    • JSR 168 Portlet Code
                                                    • IBM Portlet API JSPs
                                                    • JSR 168 JSPs
                                                      • Summary
Page 40: Difference Bw Jsr168 and Ibm

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

responsesetContentType(texthtml)

PortletURL addUrl = responsecreateActionURL()

addUrlsetPortletMode(PortletModeVIEW)

addUrlsetParameter(addadd)

requestsetAttribute(addUrladdUrltoString())

PortletURL cancelUrl = responsecreateRenderURL()

cancelUrlsetPortletMode(PortletModeVIEW)

requestsetAttribute(cancelUrlcancelUrltoString())

String jspName = getPortletConfig()getInitParameter(jspEdit)

PortletRequestDispatcher rd = getPortletContext()getRequestDispatcher(jspName)

rdinclude(requestresponse)

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 ldquoaddrdquo button URL an action URL is created as we need to store the user input of the add form persistently For the ldquocancelrdquo 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 = requestgetParameter(remove)

if (removeName = null)

PortletPreferences prefs = requestgetPreferences()

prefsreset(removeName)

prefsstore()

String add = requestgetParameter(add)

if (add = null)

PortletPreferences prefs = requestgetPreferences()

String name = requestgetParameter(name)

String value = requestgetParameter(value)

prefssetValue(name value)

prefsstore()

catch ( IOException ioe )

getPortletContextlog(An IO error occured when trying to remove a bookmark)

catch ( PortletException pe )

getPortletContextlog(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

bull 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

bull 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

bull Persistent portlet data The JSR 168 persistent data PortletPreferences have an API similar to the JDK 14 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

bull 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

63 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

lt page contentType=texthtml import=javautil comibmwpssampleswp5

orgapachejetspeedportlet session=falsegt

lt taglib uri=WEB-INFtldportlettld prefix=portletAPI gt

- 42 -

ltportletAPIinitgt

ltp class=wpsPortletHeadgtltportletAPItext key=available_bookmarks

bundle=nlsTextgtAvailable BookmarksltportletAPItextgtltpgt

lt

PortletData prefs = portletRequestgetData()

Enumeration e = prefsgetAttributeNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltportletAPItext key=no_bookmarks bundle=nlsTextgtNo

bookmarksltportletAPItextgtltpgt

lt

else

gt

ltp class=wpsIndentMediumgt

lt

while (ehasMoreElements())

String name = (String)enextElement()

String value = (String)prefsgetAttribute(name)

gt

lta href=lt=valuegt target=_blankgtlt=namegtltagtltbr gt

lt

gt

ltpgt

The View JSP first call portletAPIinit 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

lt page contentType=texthtml import=javautil

comibmwpssampleswp5orgapachejetspeedportlet session=falsegt

lt taglib uri=WEB-INFtldportlettld prefix=portletAPI gt

ltjspuseBean id=addURI class=javalangString scope=request gt

ltjspuseBean id=cancelURI class=javalangString scope=request gt

ltportletAPIinitgt

lth4gtltportletAPItext key=available_bookmarks bundle=nlsTextgtAvailable

BookmarksltportletAPItextgtlth4gt

lttable class=wpsTablegt

lttr class=wpsTableRowgt

ltth class=portlet-table-headergtltportletAPItext key=name bundle=nlsTextgtltthgt

ltth class=portlet-table-headergtltportletAPItext key=url bundle=nlsTextgtltthgt

lttdgtlttdgt

lttrgt

lt

PortletData prefs = portletRequestgetData()

Enumeration e = prefsgetAttributeNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltportletAPItext key=no_bookmarks bundle=nlsTextgtNo

bookmarksltportletAPItextgtltpgt

lt

else

while (ehasMoreElements())

- 44 -

String name = (String)enextElement()

String value = (String)prefsgetAttribute(name)

gt

lttr class=wpsTableRowgt

lttdgt lt=namegt lttdgt

lttdgt lt=valuegt lttdgt

lttdgt lta href=ltportletAPIcreateURIgtltportletAPIURIAction

name=removeURIgtltportletAPIURIParameter name=remove

value=lt=namegtgtltportletAPIcreateURIgtgt

(ltportletAPItext key=delete bundle=nlsTextgt)ltagt

lttdgt

lttrgt

lt

gt

ltform action=lt=addURIgt method=POSTgt

lttr class=wpsTableRowgt

lttdgtltinput name=ltportletAPIencodeNamespace value=namegt type=text

class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=ltportletAPIencodeNamespace value=valuegt type=text

class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=ltportletAPIencodeNamespace value=addgt type=submit

value=ltportletAPItext key=add bundle=nlsTextgt class=portlet-form-buttongtlttdgt

lttrgt

ltformgt

lttablegt

- 45 -

ltform action=lt=cancelURIgt method=postgt

ltinput name=ltportletAPIencodeNamespace value=cancelgt type=submit

value=ltportletAPItext key=cancel bundle=nlsTextgt class=portlet-form-buttongt

ltformgt

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 ldquodeleterdquo button for which an URL with the action ldquoremoveURIrdquo 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 ldquocancelrdquo button from the request

64 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

lt page import=javaxportlet javautil session=falsegt

lt taglib uri=httpjavasuncomportlet prefix=portletAPI gt

lt taglib prefix=fmt uri=httpjavasuncomjstlfmt gt

ltportletAPIdefineObjects gt

ltfmtsetBundle basename=nlsTextgt

lt

ResourceBundle myText = ResourceBundlegetBundle(nlsText requestgetLocale())

gt

lth4gtltfmtmessage key=available_bookmarksgtlth4gt

lt

PortletPreferences prefs = renderRequestgetPreferences()

Enumeration e = prefsgetNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltfmtmessage key=no_bookmarksgtltpgt

- 46 -

lt

else

gt

ltpgt

lt

while (ehasMoreElements())

String name = (String)enextElement()

String value = prefsgetValue(namelt+myTextgetString(undefined)+gt)

gt

lta href=lt=valuegt target=_blankgtlt=namegtltagtltbr gt

lt

gt

ltpgt

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 fmtmessage 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

lt page import=javaxportlet javautil session=false gt

lt taglib uri=httpjavasuncomportlet prefix=portletAPI gt

lt taglib prefix=fmt uri=httpjavasuncomjstlfmt gt

ltjspuseBean id=addUrl scope=request class=javalangString gt

ltjspuseBean id=cancelUrl scope=request class=javalangString gt

- 47 -

ltportletAPIdefineObjectsgt

lt

ResourceBundle myText = ResourceBundlegetBundle(nlsText requestgetLocale())

gt

ltfmtsetBundle basename=nlsTextgt

lth4gtltfmtmessage key=available_bookmarksgtlth4gt

lttable class=wpsTablegt

lttr class=wpsTableRowgt

ltth class=wpsTableHeadgtltfmtmessage key=namegtltthgt

ltth class=wpsTableHeadgtltfmtmessage key=urlgtltthgt

lttdgtlttdgt

lttrgt

lt

PortletPreferences prefs = renderRequestgetPreferences()

Enumeration e = prefsgetNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltfmtmessage key=no_bookmarksgtltpgt

lt

else

while (ehasMoreElements())

String name = (String)enextElement()

String value = prefsgetValue(namelt+myTextgetString(undefined)+gt)

gt

lttr class=wpsTableRowgt

lttdgt lt=namegt lttdgt

lttdgt lt=valuegt lttdgt

- 48 -

lttdgt ltportletAPIactionURL var=removeUrlgt

ltportletAPIparam name=remove value=lt=namegtgt

ltportletAPIactionURLgt

lta href=lt=removeUrltoString()gtgt(ltfmtmessage key=deletegt)ltagt

lttdgt

lttrgt

lt

gt

ltform action=lt=addUrlgt method=POSTgt

lttr class=wpsTableRowgt

lttdgtltinput name=name type=text class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=value type=text class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=add type=submit value=ltfmtmessage key=addgt

class=portlet-form-buttongtlttdgt

lttrgt

ltformgt

lttablegt

ltform action=lt=cancelUrlgt method=postgt

ltinput name=cancel type=submit value=ltfmtmessage key=cancelgt class=portlet-

form-buttongt

ltformgt

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 14 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 -

- 51 -

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 (eg eventing) the IBM Portlet API still needs to be used Trademarks bull IBM and WebSphere are trademarks or registered trademarks of IBM Corporation in

the United States other countries or both bull 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 bull Other company product and service names may be trademarks or service marks of

others IBM copyright and trademark information httpwwwibmcomlegalcopytradephtml

  • Introduction
  • JSR 168 and the Java Community Process
  • Comparing concepts
    • Basic concepts
      • Portal
      • Portal page
      • Portlet
      • Portlet Container
        • Concepts that are the same
          • Portlet mode
          • Window state
          • Portlet life cycle and request processing
          • URL encoding
          • Include servletsJSPs
          • Portlet application packaging
          • Expiration-based caching
            • Concepts that differ
              • Portlet application entity
              • Portlet entity
              • Action and Render Request Response objects
              • Window concept
              • Portlet API does not extend servlet API
              • TAG libraries
                • Concepts new in the JSR 168
                  • Render parameter
                  • Extension mechanisms
                    • Custom window states
                    • Custom portlet modes
                    • Custom user info
                    • Request Response properties
                      • Web application session scope
                      • Reuse of the HttpSession listeners
                      • J2EE role support
                      • Resource bundles
                      • Multiple response content types
                      • Redirect in action
                      • Preference validator
                      • Portal context
                      • Localization support
                        • Concepts missing in the JSR 168
                          • Eventing
                          • Additional lifecycle events
                          • Property broker
                          • Portlet Menus
                          • Portlet Services
                          • Invalidation-based caching
                            • Alignment with WSRP
                              • Outlook for the next version of the JSR 168
                              • Guidelines for programming IBM Portlet API portlets
                                • Similar Functionality
                                  • Basic programming model
                                  • Portlet private session
                                  • User profile information
                                  • Persistent data
                                  • Portlet modes and window states
                                  • Expiration-based caching
                                    • Slightly different functionality
                                      • Sharing of data between portlets
                                      • Session listeners
                                        • New JSR 168 functionality
                                          • Navigational state (render parameters)
                                            • Pitfalls
                                              • Request response objects for action and render phase
                                              • Include search path
                                              • Form parameter encoding
                                              • Title setting
                                                  • Examples
                                                    • IBM Portlet API Portlet Code
                                                    • JSR 168 Portlet Code
                                                    • IBM Portlet API JSPs
                                                    • JSR 168 JSPs
                                                      • Summary
Page 41: Difference Bw Jsr168 and Ibm

JSR 168 BOOKMARK EXAMPLE - PROCESSACTION

public void processAction(ActionRequest request ActionResponse response)

throws PortletException IOException

try

String removeName = requestgetParameter(remove)

if (removeName = null)

PortletPreferences prefs = requestgetPreferences()

prefsreset(removeName)

prefsstore()

String add = requestgetParameter(add)

if (add = null)

PortletPreferences prefs = requestgetPreferences()

String name = requestgetParameter(name)

String value = requestgetParameter(value)

prefssetValue(name value)

prefsstore()

catch ( IOException ioe )

getPortletContextlog(An IO error occured when trying to remove a bookmark)

catch ( PortletException pe )

getPortletContextlog(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

bull 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

bull 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

bull Persistent portlet data The JSR 168 persistent data PortletPreferences have an API similar to the JDK 14 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

bull 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

63 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

lt page contentType=texthtml import=javautil comibmwpssampleswp5

orgapachejetspeedportlet session=falsegt

lt taglib uri=WEB-INFtldportlettld prefix=portletAPI gt

- 42 -

ltportletAPIinitgt

ltp class=wpsPortletHeadgtltportletAPItext key=available_bookmarks

bundle=nlsTextgtAvailable BookmarksltportletAPItextgtltpgt

lt

PortletData prefs = portletRequestgetData()

Enumeration e = prefsgetAttributeNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltportletAPItext key=no_bookmarks bundle=nlsTextgtNo

bookmarksltportletAPItextgtltpgt

lt

else

gt

ltp class=wpsIndentMediumgt

lt

while (ehasMoreElements())

String name = (String)enextElement()

String value = (String)prefsgetAttribute(name)

gt

lta href=lt=valuegt target=_blankgtlt=namegtltagtltbr gt

lt

gt

ltpgt

The View JSP first call portletAPIinit 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

lt page contentType=texthtml import=javautil

comibmwpssampleswp5orgapachejetspeedportlet session=falsegt

lt taglib uri=WEB-INFtldportlettld prefix=portletAPI gt

ltjspuseBean id=addURI class=javalangString scope=request gt

ltjspuseBean id=cancelURI class=javalangString scope=request gt

ltportletAPIinitgt

lth4gtltportletAPItext key=available_bookmarks bundle=nlsTextgtAvailable

BookmarksltportletAPItextgtlth4gt

lttable class=wpsTablegt

lttr class=wpsTableRowgt

ltth class=portlet-table-headergtltportletAPItext key=name bundle=nlsTextgtltthgt

ltth class=portlet-table-headergtltportletAPItext key=url bundle=nlsTextgtltthgt

lttdgtlttdgt

lttrgt

lt

PortletData prefs = portletRequestgetData()

Enumeration e = prefsgetAttributeNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltportletAPItext key=no_bookmarks bundle=nlsTextgtNo

bookmarksltportletAPItextgtltpgt

lt

else

while (ehasMoreElements())

- 44 -

String name = (String)enextElement()

String value = (String)prefsgetAttribute(name)

gt

lttr class=wpsTableRowgt

lttdgt lt=namegt lttdgt

lttdgt lt=valuegt lttdgt

lttdgt lta href=ltportletAPIcreateURIgtltportletAPIURIAction

name=removeURIgtltportletAPIURIParameter name=remove

value=lt=namegtgtltportletAPIcreateURIgtgt

(ltportletAPItext key=delete bundle=nlsTextgt)ltagt

lttdgt

lttrgt

lt

gt

ltform action=lt=addURIgt method=POSTgt

lttr class=wpsTableRowgt

lttdgtltinput name=ltportletAPIencodeNamespace value=namegt type=text

class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=ltportletAPIencodeNamespace value=valuegt type=text

class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=ltportletAPIencodeNamespace value=addgt type=submit

value=ltportletAPItext key=add bundle=nlsTextgt class=portlet-form-buttongtlttdgt

lttrgt

ltformgt

lttablegt

- 45 -

ltform action=lt=cancelURIgt method=postgt

ltinput name=ltportletAPIencodeNamespace value=cancelgt type=submit

value=ltportletAPItext key=cancel bundle=nlsTextgt class=portlet-form-buttongt

ltformgt

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 ldquodeleterdquo button for which an URL with the action ldquoremoveURIrdquo 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 ldquocancelrdquo button from the request

64 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

lt page import=javaxportlet javautil session=falsegt

lt taglib uri=httpjavasuncomportlet prefix=portletAPI gt

lt taglib prefix=fmt uri=httpjavasuncomjstlfmt gt

ltportletAPIdefineObjects gt

ltfmtsetBundle basename=nlsTextgt

lt

ResourceBundle myText = ResourceBundlegetBundle(nlsText requestgetLocale())

gt

lth4gtltfmtmessage key=available_bookmarksgtlth4gt

lt

PortletPreferences prefs = renderRequestgetPreferences()

Enumeration e = prefsgetNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltfmtmessage key=no_bookmarksgtltpgt

- 46 -

lt

else

gt

ltpgt

lt

while (ehasMoreElements())

String name = (String)enextElement()

String value = prefsgetValue(namelt+myTextgetString(undefined)+gt)

gt

lta href=lt=valuegt target=_blankgtlt=namegtltagtltbr gt

lt

gt

ltpgt

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 fmtmessage 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

lt page import=javaxportlet javautil session=false gt

lt taglib uri=httpjavasuncomportlet prefix=portletAPI gt

lt taglib prefix=fmt uri=httpjavasuncomjstlfmt gt

ltjspuseBean id=addUrl scope=request class=javalangString gt

ltjspuseBean id=cancelUrl scope=request class=javalangString gt

- 47 -

ltportletAPIdefineObjectsgt

lt

ResourceBundle myText = ResourceBundlegetBundle(nlsText requestgetLocale())

gt

ltfmtsetBundle basename=nlsTextgt

lth4gtltfmtmessage key=available_bookmarksgtlth4gt

lttable class=wpsTablegt

lttr class=wpsTableRowgt

ltth class=wpsTableHeadgtltfmtmessage key=namegtltthgt

ltth class=wpsTableHeadgtltfmtmessage key=urlgtltthgt

lttdgtlttdgt

lttrgt

lt

PortletPreferences prefs = renderRequestgetPreferences()

Enumeration e = prefsgetNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltfmtmessage key=no_bookmarksgtltpgt

lt

else

while (ehasMoreElements())

String name = (String)enextElement()

String value = prefsgetValue(namelt+myTextgetString(undefined)+gt)

gt

lttr class=wpsTableRowgt

lttdgt lt=namegt lttdgt

lttdgt lt=valuegt lttdgt

- 48 -

lttdgt ltportletAPIactionURL var=removeUrlgt

ltportletAPIparam name=remove value=lt=namegtgt

ltportletAPIactionURLgt

lta href=lt=removeUrltoString()gtgt(ltfmtmessage key=deletegt)ltagt

lttdgt

lttrgt

lt

gt

ltform action=lt=addUrlgt method=POSTgt

lttr class=wpsTableRowgt

lttdgtltinput name=name type=text class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=value type=text class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=add type=submit value=ltfmtmessage key=addgt

class=portlet-form-buttongtlttdgt

lttrgt

ltformgt

lttablegt

ltform action=lt=cancelUrlgt method=postgt

ltinput name=cancel type=submit value=ltfmtmessage key=cancelgt class=portlet-

form-buttongt

ltformgt

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 14 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 -

- 51 -

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 (eg eventing) the IBM Portlet API still needs to be used Trademarks bull IBM and WebSphere are trademarks or registered trademarks of IBM Corporation in

the United States other countries or both bull 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 bull Other company product and service names may be trademarks or service marks of

others IBM copyright and trademark information httpwwwibmcomlegalcopytradephtml

  • Introduction
  • JSR 168 and the Java Community Process
  • Comparing concepts
    • Basic concepts
      • Portal
      • Portal page
      • Portlet
      • Portlet Container
        • Concepts that are the same
          • Portlet mode
          • Window state
          • Portlet life cycle and request processing
          • URL encoding
          • Include servletsJSPs
          • Portlet application packaging
          • Expiration-based caching
            • Concepts that differ
              • Portlet application entity
              • Portlet entity
              • Action and Render Request Response objects
              • Window concept
              • Portlet API does not extend servlet API
              • TAG libraries
                • Concepts new in the JSR 168
                  • Render parameter
                  • Extension mechanisms
                    • Custom window states
                    • Custom portlet modes
                    • Custom user info
                    • Request Response properties
                      • Web application session scope
                      • Reuse of the HttpSession listeners
                      • J2EE role support
                      • Resource bundles
                      • Multiple response content types
                      • Redirect in action
                      • Preference validator
                      • Portal context
                      • Localization support
                        • Concepts missing in the JSR 168
                          • Eventing
                          • Additional lifecycle events
                          • Property broker
                          • Portlet Menus
                          • Portlet Services
                          • Invalidation-based caching
                            • Alignment with WSRP
                              • Outlook for the next version of the JSR 168
                              • Guidelines for programming IBM Portlet API portlets
                                • Similar Functionality
                                  • Basic programming model
                                  • Portlet private session
                                  • User profile information
                                  • Persistent data
                                  • Portlet modes and window states
                                  • Expiration-based caching
                                    • Slightly different functionality
                                      • Sharing of data between portlets
                                      • Session listeners
                                        • New JSR 168 functionality
                                          • Navigational state (render parameters)
                                            • Pitfalls
                                              • Request response objects for action and render phase
                                              • Include search path
                                              • Form parameter encoding
                                              • Title setting
                                                  • Examples
                                                    • IBM Portlet API Portlet Code
                                                    • JSR 168 Portlet Code
                                                    • IBM Portlet API JSPs
                                                    • JSR 168 JSPs
                                                      • Summary
Page 42: Difference Bw Jsr168 and Ibm

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

bull 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

bull 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

bull Persistent portlet data The JSR 168 persistent data PortletPreferences have an API similar to the JDK 14 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

bull 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

63 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

lt page contentType=texthtml import=javautil comibmwpssampleswp5

orgapachejetspeedportlet session=falsegt

lt taglib uri=WEB-INFtldportlettld prefix=portletAPI gt

- 42 -

ltportletAPIinitgt

ltp class=wpsPortletHeadgtltportletAPItext key=available_bookmarks

bundle=nlsTextgtAvailable BookmarksltportletAPItextgtltpgt

lt

PortletData prefs = portletRequestgetData()

Enumeration e = prefsgetAttributeNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltportletAPItext key=no_bookmarks bundle=nlsTextgtNo

bookmarksltportletAPItextgtltpgt

lt

else

gt

ltp class=wpsIndentMediumgt

lt

while (ehasMoreElements())

String name = (String)enextElement()

String value = (String)prefsgetAttribute(name)

gt

lta href=lt=valuegt target=_blankgtlt=namegtltagtltbr gt

lt

gt

ltpgt

The View JSP first call portletAPIinit 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

lt page contentType=texthtml import=javautil

comibmwpssampleswp5orgapachejetspeedportlet session=falsegt

lt taglib uri=WEB-INFtldportlettld prefix=portletAPI gt

ltjspuseBean id=addURI class=javalangString scope=request gt

ltjspuseBean id=cancelURI class=javalangString scope=request gt

ltportletAPIinitgt

lth4gtltportletAPItext key=available_bookmarks bundle=nlsTextgtAvailable

BookmarksltportletAPItextgtlth4gt

lttable class=wpsTablegt

lttr class=wpsTableRowgt

ltth class=portlet-table-headergtltportletAPItext key=name bundle=nlsTextgtltthgt

ltth class=portlet-table-headergtltportletAPItext key=url bundle=nlsTextgtltthgt

lttdgtlttdgt

lttrgt

lt

PortletData prefs = portletRequestgetData()

Enumeration e = prefsgetAttributeNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltportletAPItext key=no_bookmarks bundle=nlsTextgtNo

bookmarksltportletAPItextgtltpgt

lt

else

while (ehasMoreElements())

- 44 -

String name = (String)enextElement()

String value = (String)prefsgetAttribute(name)

gt

lttr class=wpsTableRowgt

lttdgt lt=namegt lttdgt

lttdgt lt=valuegt lttdgt

lttdgt lta href=ltportletAPIcreateURIgtltportletAPIURIAction

name=removeURIgtltportletAPIURIParameter name=remove

value=lt=namegtgtltportletAPIcreateURIgtgt

(ltportletAPItext key=delete bundle=nlsTextgt)ltagt

lttdgt

lttrgt

lt

gt

ltform action=lt=addURIgt method=POSTgt

lttr class=wpsTableRowgt

lttdgtltinput name=ltportletAPIencodeNamespace value=namegt type=text

class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=ltportletAPIencodeNamespace value=valuegt type=text

class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=ltportletAPIencodeNamespace value=addgt type=submit

value=ltportletAPItext key=add bundle=nlsTextgt class=portlet-form-buttongtlttdgt

lttrgt

ltformgt

lttablegt

- 45 -

ltform action=lt=cancelURIgt method=postgt

ltinput name=ltportletAPIencodeNamespace value=cancelgt type=submit

value=ltportletAPItext key=cancel bundle=nlsTextgt class=portlet-form-buttongt

ltformgt

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 ldquodeleterdquo button for which an URL with the action ldquoremoveURIrdquo 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 ldquocancelrdquo button from the request

64 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

lt page import=javaxportlet javautil session=falsegt

lt taglib uri=httpjavasuncomportlet prefix=portletAPI gt

lt taglib prefix=fmt uri=httpjavasuncomjstlfmt gt

ltportletAPIdefineObjects gt

ltfmtsetBundle basename=nlsTextgt

lt

ResourceBundle myText = ResourceBundlegetBundle(nlsText requestgetLocale())

gt

lth4gtltfmtmessage key=available_bookmarksgtlth4gt

lt

PortletPreferences prefs = renderRequestgetPreferences()

Enumeration e = prefsgetNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltfmtmessage key=no_bookmarksgtltpgt

- 46 -

lt

else

gt

ltpgt

lt

while (ehasMoreElements())

String name = (String)enextElement()

String value = prefsgetValue(namelt+myTextgetString(undefined)+gt)

gt

lta href=lt=valuegt target=_blankgtlt=namegtltagtltbr gt

lt

gt

ltpgt

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 fmtmessage 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

lt page import=javaxportlet javautil session=false gt

lt taglib uri=httpjavasuncomportlet prefix=portletAPI gt

lt taglib prefix=fmt uri=httpjavasuncomjstlfmt gt

ltjspuseBean id=addUrl scope=request class=javalangString gt

ltjspuseBean id=cancelUrl scope=request class=javalangString gt

- 47 -

ltportletAPIdefineObjectsgt

lt

ResourceBundle myText = ResourceBundlegetBundle(nlsText requestgetLocale())

gt

ltfmtsetBundle basename=nlsTextgt

lth4gtltfmtmessage key=available_bookmarksgtlth4gt

lttable class=wpsTablegt

lttr class=wpsTableRowgt

ltth class=wpsTableHeadgtltfmtmessage key=namegtltthgt

ltth class=wpsTableHeadgtltfmtmessage key=urlgtltthgt

lttdgtlttdgt

lttrgt

lt

PortletPreferences prefs = renderRequestgetPreferences()

Enumeration e = prefsgetNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltfmtmessage key=no_bookmarksgtltpgt

lt

else

while (ehasMoreElements())

String name = (String)enextElement()

String value = prefsgetValue(namelt+myTextgetString(undefined)+gt)

gt

lttr class=wpsTableRowgt

lttdgt lt=namegt lttdgt

lttdgt lt=valuegt lttdgt

- 48 -

lttdgt ltportletAPIactionURL var=removeUrlgt

ltportletAPIparam name=remove value=lt=namegtgt

ltportletAPIactionURLgt

lta href=lt=removeUrltoString()gtgt(ltfmtmessage key=deletegt)ltagt

lttdgt

lttrgt

lt

gt

ltform action=lt=addUrlgt method=POSTgt

lttr class=wpsTableRowgt

lttdgtltinput name=name type=text class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=value type=text class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=add type=submit value=ltfmtmessage key=addgt

class=portlet-form-buttongtlttdgt

lttrgt

ltformgt

lttablegt

ltform action=lt=cancelUrlgt method=postgt

ltinput name=cancel type=submit value=ltfmtmessage key=cancelgt class=portlet-

form-buttongt

ltformgt

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 14 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 -

- 51 -

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 (eg eventing) the IBM Portlet API still needs to be used Trademarks bull IBM and WebSphere are trademarks or registered trademarks of IBM Corporation in

the United States other countries or both bull 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 bull Other company product and service names may be trademarks or service marks of

others IBM copyright and trademark information httpwwwibmcomlegalcopytradephtml

  • Introduction
  • JSR 168 and the Java Community Process
  • Comparing concepts
    • Basic concepts
      • Portal
      • Portal page
      • Portlet
      • Portlet Container
        • Concepts that are the same
          • Portlet mode
          • Window state
          • Portlet life cycle and request processing
          • URL encoding
          • Include servletsJSPs
          • Portlet application packaging
          • Expiration-based caching
            • Concepts that differ
              • Portlet application entity
              • Portlet entity
              • Action and Render Request Response objects
              • Window concept
              • Portlet API does not extend servlet API
              • TAG libraries
                • Concepts new in the JSR 168
                  • Render parameter
                  • Extension mechanisms
                    • Custom window states
                    • Custom portlet modes
                    • Custom user info
                    • Request Response properties
                      • Web application session scope
                      • Reuse of the HttpSession listeners
                      • J2EE role support
                      • Resource bundles
                      • Multiple response content types
                      • Redirect in action
                      • Preference validator
                      • Portal context
                      • Localization support
                        • Concepts missing in the JSR 168
                          • Eventing
                          • Additional lifecycle events
                          • Property broker
                          • Portlet Menus
                          • Portlet Services
                          • Invalidation-based caching
                            • Alignment with WSRP
                              • Outlook for the next version of the JSR 168
                              • Guidelines for programming IBM Portlet API portlets
                                • Similar Functionality
                                  • Basic programming model
                                  • Portlet private session
                                  • User profile information
                                  • Persistent data
                                  • Portlet modes and window states
                                  • Expiration-based caching
                                    • Slightly different functionality
                                      • Sharing of data between portlets
                                      • Session listeners
                                        • New JSR 168 functionality
                                          • Navigational state (render parameters)
                                            • Pitfalls
                                              • Request response objects for action and render phase
                                              • Include search path
                                              • Form parameter encoding
                                              • Title setting
                                                  • Examples
                                                    • IBM Portlet API Portlet Code
                                                    • JSR 168 Portlet Code
                                                    • IBM Portlet API JSPs
                                                    • JSR 168 JSPs
                                                      • Summary
Page 43: Difference Bw Jsr168 and Ibm

ltportletAPIinitgt

ltp class=wpsPortletHeadgtltportletAPItext key=available_bookmarks

bundle=nlsTextgtAvailable BookmarksltportletAPItextgtltpgt

lt

PortletData prefs = portletRequestgetData()

Enumeration e = prefsgetAttributeNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltportletAPItext key=no_bookmarks bundle=nlsTextgtNo

bookmarksltportletAPItextgtltpgt

lt

else

gt

ltp class=wpsIndentMediumgt

lt

while (ehasMoreElements())

String name = (String)enextElement()

String value = (String)prefsgetAttribute(name)

gt

lta href=lt=valuegt target=_blankgtlt=namegtltagtltbr gt

lt

gt

ltpgt

The View JSP first call portletAPIinit 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

lt page contentType=texthtml import=javautil

comibmwpssampleswp5orgapachejetspeedportlet session=falsegt

lt taglib uri=WEB-INFtldportlettld prefix=portletAPI gt

ltjspuseBean id=addURI class=javalangString scope=request gt

ltjspuseBean id=cancelURI class=javalangString scope=request gt

ltportletAPIinitgt

lth4gtltportletAPItext key=available_bookmarks bundle=nlsTextgtAvailable

BookmarksltportletAPItextgtlth4gt

lttable class=wpsTablegt

lttr class=wpsTableRowgt

ltth class=portlet-table-headergtltportletAPItext key=name bundle=nlsTextgtltthgt

ltth class=portlet-table-headergtltportletAPItext key=url bundle=nlsTextgtltthgt

lttdgtlttdgt

lttrgt

lt

PortletData prefs = portletRequestgetData()

Enumeration e = prefsgetAttributeNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltportletAPItext key=no_bookmarks bundle=nlsTextgtNo

bookmarksltportletAPItextgtltpgt

lt

else

while (ehasMoreElements())

- 44 -

String name = (String)enextElement()

String value = (String)prefsgetAttribute(name)

gt

lttr class=wpsTableRowgt

lttdgt lt=namegt lttdgt

lttdgt lt=valuegt lttdgt

lttdgt lta href=ltportletAPIcreateURIgtltportletAPIURIAction

name=removeURIgtltportletAPIURIParameter name=remove

value=lt=namegtgtltportletAPIcreateURIgtgt

(ltportletAPItext key=delete bundle=nlsTextgt)ltagt

lttdgt

lttrgt

lt

gt

ltform action=lt=addURIgt method=POSTgt

lttr class=wpsTableRowgt

lttdgtltinput name=ltportletAPIencodeNamespace value=namegt type=text

class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=ltportletAPIencodeNamespace value=valuegt type=text

class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=ltportletAPIencodeNamespace value=addgt type=submit

value=ltportletAPItext key=add bundle=nlsTextgt class=portlet-form-buttongtlttdgt

lttrgt

ltformgt

lttablegt

- 45 -

ltform action=lt=cancelURIgt method=postgt

ltinput name=ltportletAPIencodeNamespace value=cancelgt type=submit

value=ltportletAPItext key=cancel bundle=nlsTextgt class=portlet-form-buttongt

ltformgt

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 ldquodeleterdquo button for which an URL with the action ldquoremoveURIrdquo 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 ldquocancelrdquo button from the request

64 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

lt page import=javaxportlet javautil session=falsegt

lt taglib uri=httpjavasuncomportlet prefix=portletAPI gt

lt taglib prefix=fmt uri=httpjavasuncomjstlfmt gt

ltportletAPIdefineObjects gt

ltfmtsetBundle basename=nlsTextgt

lt

ResourceBundle myText = ResourceBundlegetBundle(nlsText requestgetLocale())

gt

lth4gtltfmtmessage key=available_bookmarksgtlth4gt

lt

PortletPreferences prefs = renderRequestgetPreferences()

Enumeration e = prefsgetNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltfmtmessage key=no_bookmarksgtltpgt

- 46 -

lt

else

gt

ltpgt

lt

while (ehasMoreElements())

String name = (String)enextElement()

String value = prefsgetValue(namelt+myTextgetString(undefined)+gt)

gt

lta href=lt=valuegt target=_blankgtlt=namegtltagtltbr gt

lt

gt

ltpgt

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 fmtmessage 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

lt page import=javaxportlet javautil session=false gt

lt taglib uri=httpjavasuncomportlet prefix=portletAPI gt

lt taglib prefix=fmt uri=httpjavasuncomjstlfmt gt

ltjspuseBean id=addUrl scope=request class=javalangString gt

ltjspuseBean id=cancelUrl scope=request class=javalangString gt

- 47 -

ltportletAPIdefineObjectsgt

lt

ResourceBundle myText = ResourceBundlegetBundle(nlsText requestgetLocale())

gt

ltfmtsetBundle basename=nlsTextgt

lth4gtltfmtmessage key=available_bookmarksgtlth4gt

lttable class=wpsTablegt

lttr class=wpsTableRowgt

ltth class=wpsTableHeadgtltfmtmessage key=namegtltthgt

ltth class=wpsTableHeadgtltfmtmessage key=urlgtltthgt

lttdgtlttdgt

lttrgt

lt

PortletPreferences prefs = renderRequestgetPreferences()

Enumeration e = prefsgetNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltfmtmessage key=no_bookmarksgtltpgt

lt

else

while (ehasMoreElements())

String name = (String)enextElement()

String value = prefsgetValue(namelt+myTextgetString(undefined)+gt)

gt

lttr class=wpsTableRowgt

lttdgt lt=namegt lttdgt

lttdgt lt=valuegt lttdgt

- 48 -

lttdgt ltportletAPIactionURL var=removeUrlgt

ltportletAPIparam name=remove value=lt=namegtgt

ltportletAPIactionURLgt

lta href=lt=removeUrltoString()gtgt(ltfmtmessage key=deletegt)ltagt

lttdgt

lttrgt

lt

gt

ltform action=lt=addUrlgt method=POSTgt

lttr class=wpsTableRowgt

lttdgtltinput name=name type=text class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=value type=text class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=add type=submit value=ltfmtmessage key=addgt

class=portlet-form-buttongtlttdgt

lttrgt

ltformgt

lttablegt

ltform action=lt=cancelUrlgt method=postgt

ltinput name=cancel type=submit value=ltfmtmessage key=cancelgt class=portlet-

form-buttongt

ltformgt

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 14 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 -

- 51 -

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 (eg eventing) the IBM Portlet API still needs to be used Trademarks bull IBM and WebSphere are trademarks or registered trademarks of IBM Corporation in

the United States other countries or both bull 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 bull Other company product and service names may be trademarks or service marks of

others IBM copyright and trademark information httpwwwibmcomlegalcopytradephtml

  • Introduction
  • JSR 168 and the Java Community Process
  • Comparing concepts
    • Basic concepts
      • Portal
      • Portal page
      • Portlet
      • Portlet Container
        • Concepts that are the same
          • Portlet mode
          • Window state
          • Portlet life cycle and request processing
          • URL encoding
          • Include servletsJSPs
          • Portlet application packaging
          • Expiration-based caching
            • Concepts that differ
              • Portlet application entity
              • Portlet entity
              • Action and Render Request Response objects
              • Window concept
              • Portlet API does not extend servlet API
              • TAG libraries
                • Concepts new in the JSR 168
                  • Render parameter
                  • Extension mechanisms
                    • Custom window states
                    • Custom portlet modes
                    • Custom user info
                    • Request Response properties
                      • Web application session scope
                      • Reuse of the HttpSession listeners
                      • J2EE role support
                      • Resource bundles
                      • Multiple response content types
                      • Redirect in action
                      • Preference validator
                      • Portal context
                      • Localization support
                        • Concepts missing in the JSR 168
                          • Eventing
                          • Additional lifecycle events
                          • Property broker
                          • Portlet Menus
                          • Portlet Services
                          • Invalidation-based caching
                            • Alignment with WSRP
                              • Outlook for the next version of the JSR 168
                              • Guidelines for programming IBM Portlet API portlets
                                • Similar Functionality
                                  • Basic programming model
                                  • Portlet private session
                                  • User profile information
                                  • Persistent data
                                  • Portlet modes and window states
                                  • Expiration-based caching
                                    • Slightly different functionality
                                      • Sharing of data between portlets
                                      • Session listeners
                                        • New JSR 168 functionality
                                          • Navigational state (render parameters)
                                            • Pitfalls
                                              • Request response objects for action and render phase
                                              • Include search path
                                              • Form parameter encoding
                                              • Title setting
                                                  • Examples
                                                    • IBM Portlet API Portlet Code
                                                    • JSR 168 Portlet Code
                                                    • IBM Portlet API JSPs
                                                    • JSR 168 JSPs
                                                      • Summary
Page 44: Difference Bw Jsr168 and Ibm

IBM PORTLET API EDIT JSP

lt page contentType=texthtml import=javautil

comibmwpssampleswp5orgapachejetspeedportlet session=falsegt

lt taglib uri=WEB-INFtldportlettld prefix=portletAPI gt

ltjspuseBean id=addURI class=javalangString scope=request gt

ltjspuseBean id=cancelURI class=javalangString scope=request gt

ltportletAPIinitgt

lth4gtltportletAPItext key=available_bookmarks bundle=nlsTextgtAvailable

BookmarksltportletAPItextgtlth4gt

lttable class=wpsTablegt

lttr class=wpsTableRowgt

ltth class=portlet-table-headergtltportletAPItext key=name bundle=nlsTextgtltthgt

ltth class=portlet-table-headergtltportletAPItext key=url bundle=nlsTextgtltthgt

lttdgtlttdgt

lttrgt

lt

PortletData prefs = portletRequestgetData()

Enumeration e = prefsgetAttributeNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltportletAPItext key=no_bookmarks bundle=nlsTextgtNo

bookmarksltportletAPItextgtltpgt

lt

else

while (ehasMoreElements())

- 44 -

String name = (String)enextElement()

String value = (String)prefsgetAttribute(name)

gt

lttr class=wpsTableRowgt

lttdgt lt=namegt lttdgt

lttdgt lt=valuegt lttdgt

lttdgt lta href=ltportletAPIcreateURIgtltportletAPIURIAction

name=removeURIgtltportletAPIURIParameter name=remove

value=lt=namegtgtltportletAPIcreateURIgtgt

(ltportletAPItext key=delete bundle=nlsTextgt)ltagt

lttdgt

lttrgt

lt

gt

ltform action=lt=addURIgt method=POSTgt

lttr class=wpsTableRowgt

lttdgtltinput name=ltportletAPIencodeNamespace value=namegt type=text

class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=ltportletAPIencodeNamespace value=valuegt type=text

class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=ltportletAPIencodeNamespace value=addgt type=submit

value=ltportletAPItext key=add bundle=nlsTextgt class=portlet-form-buttongtlttdgt

lttrgt

ltformgt

lttablegt

- 45 -

ltform action=lt=cancelURIgt method=postgt

ltinput name=ltportletAPIencodeNamespace value=cancelgt type=submit

value=ltportletAPItext key=cancel bundle=nlsTextgt class=portlet-form-buttongt

ltformgt

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 ldquodeleterdquo button for which an URL with the action ldquoremoveURIrdquo 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 ldquocancelrdquo button from the request

64 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

lt page import=javaxportlet javautil session=falsegt

lt taglib uri=httpjavasuncomportlet prefix=portletAPI gt

lt taglib prefix=fmt uri=httpjavasuncomjstlfmt gt

ltportletAPIdefineObjects gt

ltfmtsetBundle basename=nlsTextgt

lt

ResourceBundle myText = ResourceBundlegetBundle(nlsText requestgetLocale())

gt

lth4gtltfmtmessage key=available_bookmarksgtlth4gt

lt

PortletPreferences prefs = renderRequestgetPreferences()

Enumeration e = prefsgetNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltfmtmessage key=no_bookmarksgtltpgt

- 46 -

lt

else

gt

ltpgt

lt

while (ehasMoreElements())

String name = (String)enextElement()

String value = prefsgetValue(namelt+myTextgetString(undefined)+gt)

gt

lta href=lt=valuegt target=_blankgtlt=namegtltagtltbr gt

lt

gt

ltpgt

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 fmtmessage 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

lt page import=javaxportlet javautil session=false gt

lt taglib uri=httpjavasuncomportlet prefix=portletAPI gt

lt taglib prefix=fmt uri=httpjavasuncomjstlfmt gt

ltjspuseBean id=addUrl scope=request class=javalangString gt

ltjspuseBean id=cancelUrl scope=request class=javalangString gt

- 47 -

ltportletAPIdefineObjectsgt

lt

ResourceBundle myText = ResourceBundlegetBundle(nlsText requestgetLocale())

gt

ltfmtsetBundle basename=nlsTextgt

lth4gtltfmtmessage key=available_bookmarksgtlth4gt

lttable class=wpsTablegt

lttr class=wpsTableRowgt

ltth class=wpsTableHeadgtltfmtmessage key=namegtltthgt

ltth class=wpsTableHeadgtltfmtmessage key=urlgtltthgt

lttdgtlttdgt

lttrgt

lt

PortletPreferences prefs = renderRequestgetPreferences()

Enumeration e = prefsgetNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltfmtmessage key=no_bookmarksgtltpgt

lt

else

while (ehasMoreElements())

String name = (String)enextElement()

String value = prefsgetValue(namelt+myTextgetString(undefined)+gt)

gt

lttr class=wpsTableRowgt

lttdgt lt=namegt lttdgt

lttdgt lt=valuegt lttdgt

- 48 -

lttdgt ltportletAPIactionURL var=removeUrlgt

ltportletAPIparam name=remove value=lt=namegtgt

ltportletAPIactionURLgt

lta href=lt=removeUrltoString()gtgt(ltfmtmessage key=deletegt)ltagt

lttdgt

lttrgt

lt

gt

ltform action=lt=addUrlgt method=POSTgt

lttr class=wpsTableRowgt

lttdgtltinput name=name type=text class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=value type=text class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=add type=submit value=ltfmtmessage key=addgt

class=portlet-form-buttongtlttdgt

lttrgt

ltformgt

lttablegt

ltform action=lt=cancelUrlgt method=postgt

ltinput name=cancel type=submit value=ltfmtmessage key=cancelgt class=portlet-

form-buttongt

ltformgt

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 14 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 -

- 51 -

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 (eg eventing) the IBM Portlet API still needs to be used Trademarks bull IBM and WebSphere are trademarks or registered trademarks of IBM Corporation in

the United States other countries or both bull 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 bull Other company product and service names may be trademarks or service marks of

others IBM copyright and trademark information httpwwwibmcomlegalcopytradephtml

  • Introduction
  • JSR 168 and the Java Community Process
  • Comparing concepts
    • Basic concepts
      • Portal
      • Portal page
      • Portlet
      • Portlet Container
        • Concepts that are the same
          • Portlet mode
          • Window state
          • Portlet life cycle and request processing
          • URL encoding
          • Include servletsJSPs
          • Portlet application packaging
          • Expiration-based caching
            • Concepts that differ
              • Portlet application entity
              • Portlet entity
              • Action and Render Request Response objects
              • Window concept
              • Portlet API does not extend servlet API
              • TAG libraries
                • Concepts new in the JSR 168
                  • Render parameter
                  • Extension mechanisms
                    • Custom window states
                    • Custom portlet modes
                    • Custom user info
                    • Request Response properties
                      • Web application session scope
                      • Reuse of the HttpSession listeners
                      • J2EE role support
                      • Resource bundles
                      • Multiple response content types
                      • Redirect in action
                      • Preference validator
                      • Portal context
                      • Localization support
                        • Concepts missing in the JSR 168
                          • Eventing
                          • Additional lifecycle events
                          • Property broker
                          • Portlet Menus
                          • Portlet Services
                          • Invalidation-based caching
                            • Alignment with WSRP
                              • Outlook for the next version of the JSR 168
                              • Guidelines for programming IBM Portlet API portlets
                                • Similar Functionality
                                  • Basic programming model
                                  • Portlet private session
                                  • User profile information
                                  • Persistent data
                                  • Portlet modes and window states
                                  • Expiration-based caching
                                    • Slightly different functionality
                                      • Sharing of data between portlets
                                      • Session listeners
                                        • New JSR 168 functionality
                                          • Navigational state (render parameters)
                                            • Pitfalls
                                              • Request response objects for action and render phase
                                              • Include search path
                                              • Form parameter encoding
                                              • Title setting
                                                  • Examples
                                                    • IBM Portlet API Portlet Code
                                                    • JSR 168 Portlet Code
                                                    • IBM Portlet API JSPs
                                                    • JSR 168 JSPs
                                                      • Summary
Page 45: Difference Bw Jsr168 and Ibm

String name = (String)enextElement()

String value = (String)prefsgetAttribute(name)

gt

lttr class=wpsTableRowgt

lttdgt lt=namegt lttdgt

lttdgt lt=valuegt lttdgt

lttdgt lta href=ltportletAPIcreateURIgtltportletAPIURIAction

name=removeURIgtltportletAPIURIParameter name=remove

value=lt=namegtgtltportletAPIcreateURIgtgt

(ltportletAPItext key=delete bundle=nlsTextgt)ltagt

lttdgt

lttrgt

lt

gt

ltform action=lt=addURIgt method=POSTgt

lttr class=wpsTableRowgt

lttdgtltinput name=ltportletAPIencodeNamespace value=namegt type=text

class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=ltportletAPIencodeNamespace value=valuegt type=text

class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=ltportletAPIencodeNamespace value=addgt type=submit

value=ltportletAPItext key=add bundle=nlsTextgt class=portlet-form-buttongtlttdgt

lttrgt

ltformgt

lttablegt

- 45 -

ltform action=lt=cancelURIgt method=postgt

ltinput name=ltportletAPIencodeNamespace value=cancelgt type=submit

value=ltportletAPItext key=cancel bundle=nlsTextgt class=portlet-form-buttongt

ltformgt

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 ldquodeleterdquo button for which an URL with the action ldquoremoveURIrdquo 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 ldquocancelrdquo button from the request

64 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

lt page import=javaxportlet javautil session=falsegt

lt taglib uri=httpjavasuncomportlet prefix=portletAPI gt

lt taglib prefix=fmt uri=httpjavasuncomjstlfmt gt

ltportletAPIdefineObjects gt

ltfmtsetBundle basename=nlsTextgt

lt

ResourceBundle myText = ResourceBundlegetBundle(nlsText requestgetLocale())

gt

lth4gtltfmtmessage key=available_bookmarksgtlth4gt

lt

PortletPreferences prefs = renderRequestgetPreferences()

Enumeration e = prefsgetNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltfmtmessage key=no_bookmarksgtltpgt

- 46 -

lt

else

gt

ltpgt

lt

while (ehasMoreElements())

String name = (String)enextElement()

String value = prefsgetValue(namelt+myTextgetString(undefined)+gt)

gt

lta href=lt=valuegt target=_blankgtlt=namegtltagtltbr gt

lt

gt

ltpgt

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 fmtmessage 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

lt page import=javaxportlet javautil session=false gt

lt taglib uri=httpjavasuncomportlet prefix=portletAPI gt

lt taglib prefix=fmt uri=httpjavasuncomjstlfmt gt

ltjspuseBean id=addUrl scope=request class=javalangString gt

ltjspuseBean id=cancelUrl scope=request class=javalangString gt

- 47 -

ltportletAPIdefineObjectsgt

lt

ResourceBundle myText = ResourceBundlegetBundle(nlsText requestgetLocale())

gt

ltfmtsetBundle basename=nlsTextgt

lth4gtltfmtmessage key=available_bookmarksgtlth4gt

lttable class=wpsTablegt

lttr class=wpsTableRowgt

ltth class=wpsTableHeadgtltfmtmessage key=namegtltthgt

ltth class=wpsTableHeadgtltfmtmessage key=urlgtltthgt

lttdgtlttdgt

lttrgt

lt

PortletPreferences prefs = renderRequestgetPreferences()

Enumeration e = prefsgetNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltfmtmessage key=no_bookmarksgtltpgt

lt

else

while (ehasMoreElements())

String name = (String)enextElement()

String value = prefsgetValue(namelt+myTextgetString(undefined)+gt)

gt

lttr class=wpsTableRowgt

lttdgt lt=namegt lttdgt

lttdgt lt=valuegt lttdgt

- 48 -

lttdgt ltportletAPIactionURL var=removeUrlgt

ltportletAPIparam name=remove value=lt=namegtgt

ltportletAPIactionURLgt

lta href=lt=removeUrltoString()gtgt(ltfmtmessage key=deletegt)ltagt

lttdgt

lttrgt

lt

gt

ltform action=lt=addUrlgt method=POSTgt

lttr class=wpsTableRowgt

lttdgtltinput name=name type=text class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=value type=text class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=add type=submit value=ltfmtmessage key=addgt

class=portlet-form-buttongtlttdgt

lttrgt

ltformgt

lttablegt

ltform action=lt=cancelUrlgt method=postgt

ltinput name=cancel type=submit value=ltfmtmessage key=cancelgt class=portlet-

form-buttongt

ltformgt

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 14 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 -

- 51 -

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 (eg eventing) the IBM Portlet API still needs to be used Trademarks bull IBM and WebSphere are trademarks or registered trademarks of IBM Corporation in

the United States other countries or both bull 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 bull Other company product and service names may be trademarks or service marks of

others IBM copyright and trademark information httpwwwibmcomlegalcopytradephtml

  • Introduction
  • JSR 168 and the Java Community Process
  • Comparing concepts
    • Basic concepts
      • Portal
      • Portal page
      • Portlet
      • Portlet Container
        • Concepts that are the same
          • Portlet mode
          • Window state
          • Portlet life cycle and request processing
          • URL encoding
          • Include servletsJSPs
          • Portlet application packaging
          • Expiration-based caching
            • Concepts that differ
              • Portlet application entity
              • Portlet entity
              • Action and Render Request Response objects
              • Window concept
              • Portlet API does not extend servlet API
              • TAG libraries
                • Concepts new in the JSR 168
                  • Render parameter
                  • Extension mechanisms
                    • Custom window states
                    • Custom portlet modes
                    • Custom user info
                    • Request Response properties
                      • Web application session scope
                      • Reuse of the HttpSession listeners
                      • J2EE role support
                      • Resource bundles
                      • Multiple response content types
                      • Redirect in action
                      • Preference validator
                      • Portal context
                      • Localization support
                        • Concepts missing in the JSR 168
                          • Eventing
                          • Additional lifecycle events
                          • Property broker
                          • Portlet Menus
                          • Portlet Services
                          • Invalidation-based caching
                            • Alignment with WSRP
                              • Outlook for the next version of the JSR 168
                              • Guidelines for programming IBM Portlet API portlets
                                • Similar Functionality
                                  • Basic programming model
                                  • Portlet private session
                                  • User profile information
                                  • Persistent data
                                  • Portlet modes and window states
                                  • Expiration-based caching
                                    • Slightly different functionality
                                      • Sharing of data between portlets
                                      • Session listeners
                                        • New JSR 168 functionality
                                          • Navigational state (render parameters)
                                            • Pitfalls
                                              • Request response objects for action and render phase
                                              • Include search path
                                              • Form parameter encoding
                                              • Title setting
                                                  • Examples
                                                    • IBM Portlet API Portlet Code
                                                    • JSR 168 Portlet Code
                                                    • IBM Portlet API JSPs
                                                    • JSR 168 JSPs
                                                      • Summary
Page 46: Difference Bw Jsr168 and Ibm

ltform action=lt=cancelURIgt method=postgt

ltinput name=ltportletAPIencodeNamespace value=cancelgt type=submit

value=ltportletAPItext key=cancel bundle=nlsTextgt class=portlet-form-buttongt

ltformgt

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 ldquodeleterdquo button for which an URL with the action ldquoremoveURIrdquo 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 ldquocancelrdquo button from the request

64 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

lt page import=javaxportlet javautil session=falsegt

lt taglib uri=httpjavasuncomportlet prefix=portletAPI gt

lt taglib prefix=fmt uri=httpjavasuncomjstlfmt gt

ltportletAPIdefineObjects gt

ltfmtsetBundle basename=nlsTextgt

lt

ResourceBundle myText = ResourceBundlegetBundle(nlsText requestgetLocale())

gt

lth4gtltfmtmessage key=available_bookmarksgtlth4gt

lt

PortletPreferences prefs = renderRequestgetPreferences()

Enumeration e = prefsgetNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltfmtmessage key=no_bookmarksgtltpgt

- 46 -

lt

else

gt

ltpgt

lt

while (ehasMoreElements())

String name = (String)enextElement()

String value = prefsgetValue(namelt+myTextgetString(undefined)+gt)

gt

lta href=lt=valuegt target=_blankgtlt=namegtltagtltbr gt

lt

gt

ltpgt

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 fmtmessage 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

lt page import=javaxportlet javautil session=false gt

lt taglib uri=httpjavasuncomportlet prefix=portletAPI gt

lt taglib prefix=fmt uri=httpjavasuncomjstlfmt gt

ltjspuseBean id=addUrl scope=request class=javalangString gt

ltjspuseBean id=cancelUrl scope=request class=javalangString gt

- 47 -

ltportletAPIdefineObjectsgt

lt

ResourceBundle myText = ResourceBundlegetBundle(nlsText requestgetLocale())

gt

ltfmtsetBundle basename=nlsTextgt

lth4gtltfmtmessage key=available_bookmarksgtlth4gt

lttable class=wpsTablegt

lttr class=wpsTableRowgt

ltth class=wpsTableHeadgtltfmtmessage key=namegtltthgt

ltth class=wpsTableHeadgtltfmtmessage key=urlgtltthgt

lttdgtlttdgt

lttrgt

lt

PortletPreferences prefs = renderRequestgetPreferences()

Enumeration e = prefsgetNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltfmtmessage key=no_bookmarksgtltpgt

lt

else

while (ehasMoreElements())

String name = (String)enextElement()

String value = prefsgetValue(namelt+myTextgetString(undefined)+gt)

gt

lttr class=wpsTableRowgt

lttdgt lt=namegt lttdgt

lttdgt lt=valuegt lttdgt

- 48 -

lttdgt ltportletAPIactionURL var=removeUrlgt

ltportletAPIparam name=remove value=lt=namegtgt

ltportletAPIactionURLgt

lta href=lt=removeUrltoString()gtgt(ltfmtmessage key=deletegt)ltagt

lttdgt

lttrgt

lt

gt

ltform action=lt=addUrlgt method=POSTgt

lttr class=wpsTableRowgt

lttdgtltinput name=name type=text class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=value type=text class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=add type=submit value=ltfmtmessage key=addgt

class=portlet-form-buttongtlttdgt

lttrgt

ltformgt

lttablegt

ltform action=lt=cancelUrlgt method=postgt

ltinput name=cancel type=submit value=ltfmtmessage key=cancelgt class=portlet-

form-buttongt

ltformgt

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 14 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 -

- 51 -

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 (eg eventing) the IBM Portlet API still needs to be used Trademarks bull IBM and WebSphere are trademarks or registered trademarks of IBM Corporation in

the United States other countries or both bull 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 bull Other company product and service names may be trademarks or service marks of

others IBM copyright and trademark information httpwwwibmcomlegalcopytradephtml

  • Introduction
  • JSR 168 and the Java Community Process
  • Comparing concepts
    • Basic concepts
      • Portal
      • Portal page
      • Portlet
      • Portlet Container
        • Concepts that are the same
          • Portlet mode
          • Window state
          • Portlet life cycle and request processing
          • URL encoding
          • Include servletsJSPs
          • Portlet application packaging
          • Expiration-based caching
            • Concepts that differ
              • Portlet application entity
              • Portlet entity
              • Action and Render Request Response objects
              • Window concept
              • Portlet API does not extend servlet API
              • TAG libraries
                • Concepts new in the JSR 168
                  • Render parameter
                  • Extension mechanisms
                    • Custom window states
                    • Custom portlet modes
                    • Custom user info
                    • Request Response properties
                      • Web application session scope
                      • Reuse of the HttpSession listeners
                      • J2EE role support
                      • Resource bundles
                      • Multiple response content types
                      • Redirect in action
                      • Preference validator
                      • Portal context
                      • Localization support
                        • Concepts missing in the JSR 168
                          • Eventing
                          • Additional lifecycle events
                          • Property broker
                          • Portlet Menus
                          • Portlet Services
                          • Invalidation-based caching
                            • Alignment with WSRP
                              • Outlook for the next version of the JSR 168
                              • Guidelines for programming IBM Portlet API portlets
                                • Similar Functionality
                                  • Basic programming model
                                  • Portlet private session
                                  • User profile information
                                  • Persistent data
                                  • Portlet modes and window states
                                  • Expiration-based caching
                                    • Slightly different functionality
                                      • Sharing of data between portlets
                                      • Session listeners
                                        • New JSR 168 functionality
                                          • Navigational state (render parameters)
                                            • Pitfalls
                                              • Request response objects for action and render phase
                                              • Include search path
                                              • Form parameter encoding
                                              • Title setting
                                                  • Examples
                                                    • IBM Portlet API Portlet Code
                                                    • JSR 168 Portlet Code
                                                    • IBM Portlet API JSPs
                                                    • JSR 168 JSPs
                                                      • Summary
Page 47: Difference Bw Jsr168 and Ibm

lt

else

gt

ltpgt

lt

while (ehasMoreElements())

String name = (String)enextElement()

String value = prefsgetValue(namelt+myTextgetString(undefined)+gt)

gt

lta href=lt=valuegt target=_blankgtlt=namegtltagtltbr gt

lt

gt

ltpgt

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 fmtmessage 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

lt page import=javaxportlet javautil session=false gt

lt taglib uri=httpjavasuncomportlet prefix=portletAPI gt

lt taglib prefix=fmt uri=httpjavasuncomjstlfmt gt

ltjspuseBean id=addUrl scope=request class=javalangString gt

ltjspuseBean id=cancelUrl scope=request class=javalangString gt

- 47 -

ltportletAPIdefineObjectsgt

lt

ResourceBundle myText = ResourceBundlegetBundle(nlsText requestgetLocale())

gt

ltfmtsetBundle basename=nlsTextgt

lth4gtltfmtmessage key=available_bookmarksgtlth4gt

lttable class=wpsTablegt

lttr class=wpsTableRowgt

ltth class=wpsTableHeadgtltfmtmessage key=namegtltthgt

ltth class=wpsTableHeadgtltfmtmessage key=urlgtltthgt

lttdgtlttdgt

lttrgt

lt

PortletPreferences prefs = renderRequestgetPreferences()

Enumeration e = prefsgetNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltfmtmessage key=no_bookmarksgtltpgt

lt

else

while (ehasMoreElements())

String name = (String)enextElement()

String value = prefsgetValue(namelt+myTextgetString(undefined)+gt)

gt

lttr class=wpsTableRowgt

lttdgt lt=namegt lttdgt

lttdgt lt=valuegt lttdgt

- 48 -

lttdgt ltportletAPIactionURL var=removeUrlgt

ltportletAPIparam name=remove value=lt=namegtgt

ltportletAPIactionURLgt

lta href=lt=removeUrltoString()gtgt(ltfmtmessage key=deletegt)ltagt

lttdgt

lttrgt

lt

gt

ltform action=lt=addUrlgt method=POSTgt

lttr class=wpsTableRowgt

lttdgtltinput name=name type=text class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=value type=text class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=add type=submit value=ltfmtmessage key=addgt

class=portlet-form-buttongtlttdgt

lttrgt

ltformgt

lttablegt

ltform action=lt=cancelUrlgt method=postgt

ltinput name=cancel type=submit value=ltfmtmessage key=cancelgt class=portlet-

form-buttongt

ltformgt

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 14 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 -

- 51 -

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 (eg eventing) the IBM Portlet API still needs to be used Trademarks bull IBM and WebSphere are trademarks or registered trademarks of IBM Corporation in

the United States other countries or both bull 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 bull Other company product and service names may be trademarks or service marks of

others IBM copyright and trademark information httpwwwibmcomlegalcopytradephtml

  • Introduction
  • JSR 168 and the Java Community Process
  • Comparing concepts
    • Basic concepts
      • Portal
      • Portal page
      • Portlet
      • Portlet Container
        • Concepts that are the same
          • Portlet mode
          • Window state
          • Portlet life cycle and request processing
          • URL encoding
          • Include servletsJSPs
          • Portlet application packaging
          • Expiration-based caching
            • Concepts that differ
              • Portlet application entity
              • Portlet entity
              • Action and Render Request Response objects
              • Window concept
              • Portlet API does not extend servlet API
              • TAG libraries
                • Concepts new in the JSR 168
                  • Render parameter
                  • Extension mechanisms
                    • Custom window states
                    • Custom portlet modes
                    • Custom user info
                    • Request Response properties
                      • Web application session scope
                      • Reuse of the HttpSession listeners
                      • J2EE role support
                      • Resource bundles
                      • Multiple response content types
                      • Redirect in action
                      • Preference validator
                      • Portal context
                      • Localization support
                        • Concepts missing in the JSR 168
                          • Eventing
                          • Additional lifecycle events
                          • Property broker
                          • Portlet Menus
                          • Portlet Services
                          • Invalidation-based caching
                            • Alignment with WSRP
                              • Outlook for the next version of the JSR 168
                              • Guidelines for programming IBM Portlet API portlets
                                • Similar Functionality
                                  • Basic programming model
                                  • Portlet private session
                                  • User profile information
                                  • Persistent data
                                  • Portlet modes and window states
                                  • Expiration-based caching
                                    • Slightly different functionality
                                      • Sharing of data between portlets
                                      • Session listeners
                                        • New JSR 168 functionality
                                          • Navigational state (render parameters)
                                            • Pitfalls
                                              • Request response objects for action and render phase
                                              • Include search path
                                              • Form parameter encoding
                                              • Title setting
                                                  • Examples
                                                    • IBM Portlet API Portlet Code
                                                    • JSR 168 Portlet Code
                                                    • IBM Portlet API JSPs
                                                    • JSR 168 JSPs
                                                      • Summary
Page 48: Difference Bw Jsr168 and Ibm

ltportletAPIdefineObjectsgt

lt

ResourceBundle myText = ResourceBundlegetBundle(nlsText requestgetLocale())

gt

ltfmtsetBundle basename=nlsTextgt

lth4gtltfmtmessage key=available_bookmarksgtlth4gt

lttable class=wpsTablegt

lttr class=wpsTableRowgt

ltth class=wpsTableHeadgtltfmtmessage key=namegtltthgt

ltth class=wpsTableHeadgtltfmtmessage key=urlgtltthgt

lttdgtlttdgt

lttrgt

lt

PortletPreferences prefs = renderRequestgetPreferences()

Enumeration e = prefsgetNames()

if (ehasMoreElements()) no bookmarks

gt

ltpgtltfmtmessage key=no_bookmarksgtltpgt

lt

else

while (ehasMoreElements())

String name = (String)enextElement()

String value = prefsgetValue(namelt+myTextgetString(undefined)+gt)

gt

lttr class=wpsTableRowgt

lttdgt lt=namegt lttdgt

lttdgt lt=valuegt lttdgt

- 48 -

lttdgt ltportletAPIactionURL var=removeUrlgt

ltportletAPIparam name=remove value=lt=namegtgt

ltportletAPIactionURLgt

lta href=lt=removeUrltoString()gtgt(ltfmtmessage key=deletegt)ltagt

lttdgt

lttrgt

lt

gt

ltform action=lt=addUrlgt method=POSTgt

lttr class=wpsTableRowgt

lttdgtltinput name=name type=text class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=value type=text class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=add type=submit value=ltfmtmessage key=addgt

class=portlet-form-buttongtlttdgt

lttrgt

ltformgt

lttablegt

ltform action=lt=cancelUrlgt method=postgt

ltinput name=cancel type=submit value=ltfmtmessage key=cancelgt class=portlet-

form-buttongt

ltformgt

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 14 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 -

- 51 -

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 (eg eventing) the IBM Portlet API still needs to be used Trademarks bull IBM and WebSphere are trademarks or registered trademarks of IBM Corporation in

the United States other countries or both bull 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 bull Other company product and service names may be trademarks or service marks of

others IBM copyright and trademark information httpwwwibmcomlegalcopytradephtml

  • Introduction
  • JSR 168 and the Java Community Process
  • Comparing concepts
    • Basic concepts
      • Portal
      • Portal page
      • Portlet
      • Portlet Container
        • Concepts that are the same
          • Portlet mode
          • Window state
          • Portlet life cycle and request processing
          • URL encoding
          • Include servletsJSPs
          • Portlet application packaging
          • Expiration-based caching
            • Concepts that differ
              • Portlet application entity
              • Portlet entity
              • Action and Render Request Response objects
              • Window concept
              • Portlet API does not extend servlet API
              • TAG libraries
                • Concepts new in the JSR 168
                  • Render parameter
                  • Extension mechanisms
                    • Custom window states
                    • Custom portlet modes
                    • Custom user info
                    • Request Response properties
                      • Web application session scope
                      • Reuse of the HttpSession listeners
                      • J2EE role support
                      • Resource bundles
                      • Multiple response content types
                      • Redirect in action
                      • Preference validator
                      • Portal context
                      • Localization support
                        • Concepts missing in the JSR 168
                          • Eventing
                          • Additional lifecycle events
                          • Property broker
                          • Portlet Menus
                          • Portlet Services
                          • Invalidation-based caching
                            • Alignment with WSRP
                              • Outlook for the next version of the JSR 168
                              • Guidelines for programming IBM Portlet API portlets
                                • Similar Functionality
                                  • Basic programming model
                                  • Portlet private session
                                  • User profile information
                                  • Persistent data
                                  • Portlet modes and window states
                                  • Expiration-based caching
                                    • Slightly different functionality
                                      • Sharing of data between portlets
                                      • Session listeners
                                        • New JSR 168 functionality
                                          • Navigational state (render parameters)
                                            • Pitfalls
                                              • Request response objects for action and render phase
                                              • Include search path
                                              • Form parameter encoding
                                              • Title setting
                                                  • Examples
                                                    • IBM Portlet API Portlet Code
                                                    • JSR 168 Portlet Code
                                                    • IBM Portlet API JSPs
                                                    • JSR 168 JSPs
                                                      • Summary
Page 49: Difference Bw Jsr168 and Ibm

lttdgt ltportletAPIactionURL var=removeUrlgt

ltportletAPIparam name=remove value=lt=namegtgt

ltportletAPIactionURLgt

lta href=lt=removeUrltoString()gtgt(ltfmtmessage key=deletegt)ltagt

lttdgt

lttrgt

lt

gt

ltform action=lt=addUrlgt method=POSTgt

lttr class=wpsTableRowgt

lttdgtltinput name=name type=text class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=value type=text class=portlet-form-input-fieldgtlttdgt

lttdgtltinput name=add type=submit value=ltfmtmessage key=addgt

class=portlet-form-buttongtlttdgt

lttrgt

ltformgt

lttablegt

ltform action=lt=cancelUrlgt method=postgt

ltinput name=cancel type=submit value=ltfmtmessage key=cancelgt class=portlet-

form-buttongt

ltformgt

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 14 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 -

- 51 -

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 (eg eventing) the IBM Portlet API still needs to be used Trademarks bull IBM and WebSphere are trademarks or registered trademarks of IBM Corporation in

the United States other countries or both bull 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 bull Other company product and service names may be trademarks or service marks of

others IBM copyright and trademark information httpwwwibmcomlegalcopytradephtml

  • Introduction
  • JSR 168 and the Java Community Process
  • Comparing concepts
    • Basic concepts
      • Portal
      • Portal page
      • Portlet
      • Portlet Container
        • Concepts that are the same
          • Portlet mode
          • Window state
          • Portlet life cycle and request processing
          • URL encoding
          • Include servletsJSPs
          • Portlet application packaging
          • Expiration-based caching
            • Concepts that differ
              • Portlet application entity
              • Portlet entity
              • Action and Render Request Response objects
              • Window concept
              • Portlet API does not extend servlet API
              • TAG libraries
                • Concepts new in the JSR 168
                  • Render parameter
                  • Extension mechanisms
                    • Custom window states
                    • Custom portlet modes
                    • Custom user info
                    • Request Response properties
                      • Web application session scope
                      • Reuse of the HttpSession listeners
                      • J2EE role support
                      • Resource bundles
                      • Multiple response content types
                      • Redirect in action
                      • Preference validator
                      • Portal context
                      • Localization support
                        • Concepts missing in the JSR 168
                          • Eventing
                          • Additional lifecycle events
                          • Property broker
                          • Portlet Menus
                          • Portlet Services
                          • Invalidation-based caching
                            • Alignment with WSRP
                              • Outlook for the next version of the JSR 168
                              • Guidelines for programming IBM Portlet API portlets
                                • Similar Functionality
                                  • Basic programming model
                                  • Portlet private session
                                  • User profile information
                                  • Persistent data
                                  • Portlet modes and window states
                                  • Expiration-based caching
                                    • Slightly different functionality
                                      • Sharing of data between portlets
                                      • Session listeners
                                        • New JSR 168 functionality
                                          • Navigational state (render parameters)
                                            • Pitfalls
                                              • Request response objects for action and render phase
                                              • Include search path
                                              • Form parameter encoding
                                              • Title setting
                                                  • Examples
                                                    • IBM Portlet API Portlet Code
                                                    • JSR 168 Portlet Code
                                                    • IBM Portlet API JSPs
                                                    • JSR 168 JSPs
                                                      • Summary
Page 50: Difference Bw Jsr168 and Ibm

can specify a default value like in the JDK 14 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 -

- 51 -

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 (eg eventing) the IBM Portlet API still needs to be used Trademarks bull IBM and WebSphere are trademarks or registered trademarks of IBM Corporation in

the United States other countries or both bull 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 bull Other company product and service names may be trademarks or service marks of

others IBM copyright and trademark information httpwwwibmcomlegalcopytradephtml

  • Introduction
  • JSR 168 and the Java Community Process
  • Comparing concepts
    • Basic concepts
      • Portal
      • Portal page
      • Portlet
      • Portlet Container
        • Concepts that are the same
          • Portlet mode
          • Window state
          • Portlet life cycle and request processing
          • URL encoding
          • Include servletsJSPs
          • Portlet application packaging
          • Expiration-based caching
            • Concepts that differ
              • Portlet application entity
              • Portlet entity
              • Action and Render Request Response objects
              • Window concept
              • Portlet API does not extend servlet API
              • TAG libraries
                • Concepts new in the JSR 168
                  • Render parameter
                  • Extension mechanisms
                    • Custom window states
                    • Custom portlet modes
                    • Custom user info
                    • Request Response properties
                      • Web application session scope
                      • Reuse of the HttpSession listeners
                      • J2EE role support
                      • Resource bundles
                      • Multiple response content types
                      • Redirect in action
                      • Preference validator
                      • Portal context
                      • Localization support
                        • Concepts missing in the JSR 168
                          • Eventing
                          • Additional lifecycle events
                          • Property broker
                          • Portlet Menus
                          • Portlet Services
                          • Invalidation-based caching
                            • Alignment with WSRP
                              • Outlook for the next version of the JSR 168
                              • Guidelines for programming IBM Portlet API portlets
                                • Similar Functionality
                                  • Basic programming model
                                  • Portlet private session
                                  • User profile information
                                  • Persistent data
                                  • Portlet modes and window states
                                  • Expiration-based caching
                                    • Slightly different functionality
                                      • Sharing of data between portlets
                                      • Session listeners
                                        • New JSR 168 functionality
                                          • Navigational state (render parameters)
                                            • Pitfalls
                                              • Request response objects for action and render phase
                                              • Include search path
                                              • Form parameter encoding
                                              • Title setting
                                                  • Examples
                                                    • IBM Portlet API Portlet Code
                                                    • JSR 168 Portlet Code
                                                    • IBM Portlet API JSPs
                                                    • JSR 168 JSPs
                                                      • Summary
Page 51: Difference Bw Jsr168 and Ibm

- 51 -

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 (eg eventing) the IBM Portlet API still needs to be used Trademarks bull IBM and WebSphere are trademarks or registered trademarks of IBM Corporation in

the United States other countries or both bull 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 bull Other company product and service names may be trademarks or service marks of

others IBM copyright and trademark information httpwwwibmcomlegalcopytradephtml

  • Introduction
  • JSR 168 and the Java Community Process
  • Comparing concepts
    • Basic concepts
      • Portal
      • Portal page
      • Portlet
      • Portlet Container
        • Concepts that are the same
          • Portlet mode
          • Window state
          • Portlet life cycle and request processing
          • URL encoding
          • Include servletsJSPs
          • Portlet application packaging
          • Expiration-based caching
            • Concepts that differ
              • Portlet application entity
              • Portlet entity
              • Action and Render Request Response objects
              • Window concept
              • Portlet API does not extend servlet API
              • TAG libraries
                • Concepts new in the JSR 168
                  • Render parameter
                  • Extension mechanisms
                    • Custom window states
                    • Custom portlet modes
                    • Custom user info
                    • Request Response properties
                      • Web application session scope
                      • Reuse of the HttpSession listeners
                      • J2EE role support
                      • Resource bundles
                      • Multiple response content types
                      • Redirect in action
                      • Preference validator
                      • Portal context
                      • Localization support
                        • Concepts missing in the JSR 168
                          • Eventing
                          • Additional lifecycle events
                          • Property broker
                          • Portlet Menus
                          • Portlet Services
                          • Invalidation-based caching
                            • Alignment with WSRP
                              • Outlook for the next version of the JSR 168
                              • Guidelines for programming IBM Portlet API portlets
                                • Similar Functionality
                                  • Basic programming model
                                  • Portlet private session
                                  • User profile information
                                  • Persistent data
                                  • Portlet modes and window states
                                  • Expiration-based caching
                                    • Slightly different functionality
                                      • Sharing of data between portlets
                                      • Session listeners
                                        • New JSR 168 functionality
                                          • Navigational state (render parameters)
                                            • Pitfalls
                                              • Request response objects for action and render phase
                                              • Include search path
                                              • Form parameter encoding
                                              • Title setting
                                                  • Examples
                                                    • IBM Portlet API Portlet Code
                                                    • JSR 168 Portlet Code
                                                    • IBM Portlet API JSPs
                                                    • JSR 168 JSPs
                                                      • Summary