difference bw jsr168 and ibm
TRANSCRIPT
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
-
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
-
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
-
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
-
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
-
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
-
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
-
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
-
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
-
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
-
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
-
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
-
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
-
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
-
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
-
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
-
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
-
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
-
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
-
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
-
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
-
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
-
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
-
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
-
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
-
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
-
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
-
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
-
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
-
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
-
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
-
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
-
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
-
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
-
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
-
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
-
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
-
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
-
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
-
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
-
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
-
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
-
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
-
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
-
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
-
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
-
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
-
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
-
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
-
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
-
- 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
-