Portalizing Domino Applications for Websphere Portal
| < Day Day Up > |
|
5.2 Technical introduction to portlets
A portlet is a server-side application that runs in the context of the WebSphere Portal. It inherits from the javax.servlet.http.HttpServlet class, and as such, is treated as a servlet by the application server.
The portlet is executed inside a Web container managed by the application server. In the Portlet API, this container is referred to as the Portlet container.
It is not possible to directly execute the portlet functionality by addressing the portlet via HTTP. Though a portlet may provide dual functionality as both a servlet and a portlet, it is certainly a best practice to keep these Controller functions separate. A portlet is visible on a portal page as a single small window; each portal page may have many. The portlet is the content inside the window, not the window itself. The window is defined by the selected skin.
More in-depth information about portlets is in IBM Websphere Portal V4 Developer's Handbook, SG24-6897.
5.2.1 Basic portlet terms
In order to fully understand some of the introductory topics, it is necessary to define a few of the most basic terms used when discussing portlets. (Additional information about basic portlet topics is in 1.3.1, "Introduction to portlets" on page 9.)
Portlet window
This is the window that surrounds the portlet, including the title bar and any border images.
State
This is the current state of the portlet window. Valid states are Normal, Minimized, and Maximized.
Mode
This defines the current condition of the portlet. The modes that are available for any particular user depend on the permissions for that user, the device they are using to access the portlet and the configuration and implementation of the portlet. The supported modes are View, Edit, Configure, and Help.
5.2.2 Model-view-controller (MVC) design pattern
To help you understand the role of a portlet and to help prepare you to develop effective and well-designed portlets, a review of the Model View Control (MVC) architecture is necessary. Several benefits of the portlet architecture are available to you only if you employ a good MVC design.
The Model View Control architecture is concerned with separation of responsibilities. The objective, no matter how it is applied or to what type of application, is to separate a system into tiers. Each tier should be small, identifiable, self-contained, and reusable. These tiers are identified by the role they play in the system. Each role in that system may have several classes working in conjunction to achieve the goal of that role. This section covers the three roles of MVC: Model, View and Control.
Though the MVC architecture was originally applied to Java Swing applications, it has gained popularity and widespread acceptance throughout the J2EE community.
The correct portlet design is broken down into three distinct parts: the model, the view, and the controller (MVC). This design follows classical object-oriented design patterns where each part is self-contained and modular, easing maintenance, extensions, and advancements.
The model is the data to which the portlet provides an interface. Common data models are XML documents, database tables, and even other Web applications. The Java classes accessing the data model should have no knowledge of the form that the data is in, the idea being that the model can be changed without affecting the rest of the portlet application.
The view is the interface to the data model, presenting it in some usable format. The view accesses the data to be rendered through the model interfaces and thus should not care what format the model takes. It should also not understand the relationships between data models or represent any of the business logic for manipulating the data. Like the data model, the view should be independent and interchangeable, allowing other views to be substituted without affecting the business logic or the model. The typical embodiment of the view is through a series of Java Server Pages (JSPs), but can also be through other rendering techniques such as using XSL stylesheets to format XML documents.
The controller is the glue that ties the model to the view and defines the interaction pattern in the portlet. The controller handles user requests from the view and passes control to the appropriate model objects to complete the requested action. The results of the action are then rendered back to the user by the controller using appropriate view objects and perhaps model objects that represent the data results of the completed action.
The controller resides in the portlet Java classes themselves. It knows the data model only through the model interfaces and it knows the view only in that it dispatches the view to render the data. Therefore, the controller logic can be just as easily replaced as the view and the model. Typical controller implementations utilize intrinsic functions in the portlet API for coordinating action sequences around user input, model data calculations, and result rendering.
As you design your portlets, it is extremely important to hold true to the MVC design principles. Portlets typically evolve over time and are largely reused as the foundation for new portlets. The ability to adapt a portlet to a new back-end data provider, or add markup support for mobile devices, or enhance the portlet to include user personalization, requires that each part of the portlet be self-contained and extensible.
5.2.3 Portlet API overview
The WebSphere Portal is based on a portlet container that provides a runtime environment in which portlets are instantiated, used, and finally destroyed. Portlets rely on the portal infrastructure to access user profile information, participate in window and action events, communicate with other portlets, access remote content, lookup credentials, and to store persistent data. The Portlet API provides standard interfaces for these functions. The portlet container is not a stand-alone container like the servlet container. Instead, it is implemented as a thin layer on top of the servlet container and reuses the functionality provided by the servlet container.
IBM is working with other companies to standardize the Portlet API, making portlets interoperable between portal servers that implement the specification. The Portlet API offered in WebSphere Portal Version 4.2 is the first step toward the Portlet API standardization. For more information about the portlet specification, see:
-
http://jcp.org/jsr/detail/168.jsp
5.2.4 Portlets and the Servlet API
The abstract Portlet class is the central abstraction of the Portlet API. The Portlet class extends HTTPServlet, of the Servlet API. All portlets extend this abstract class indirectly, and inherit from HttpServlet, as shown in Figure 5-1.
Therefore, portlets are a special type of servlet, with properties that allow them to easily plug in to and run in the portal server. Unlike servlets, portlets cannot send redirects or errors to browsers directly, forward requests, or write arbitrary markup to the output stream. The portlet container relies on the J2EE architecture implemented by WebSphere Application Server. As a result, portlets are packaged similar to J2EE Web applications and are deployed like servlets.
Generally, portlets are administered more dynamically than servlets. For example, the following changes can be applied without having to start and restart the portal server:
-
Portlet applications consisting of several portlets can be installed and removed using the portal administration user interface.
-
The settings of a portlet can be changed by an administrator with appropriate access rights.
-
Portlets can be created and deleted dynamically by administration portlets. For example, the clipping portlet can be used to create new portlet instances whenever an administrator creates a new clipping.
The portlet container relies on the J2EE architecture implemented by WebSphere Application Server. As a result, portlets are packaged in WAR files similar to J2EE Web applications and are deployed like servlets. Like other servlets, a portlet is defined to the application server using the servlet deployment descriptor (web.xml). This file defines the portlet's class file and read-only initialization parameters.
The initialization parameters are set by the portlet developer and can be read by the portlet using the PortletConfig object. The servlet deployment descriptor can contain multiple Web applications, each defined by the <servlet> element. In addition, each servlet definition can point to the same portlet class file, thus creating different PortletConfig objects with different initialization parameters for each portlet class instance.
5.2.5 Portlet concepts
The following figure shows different variations of a portlet as it is created, placed on a page, and accessed by users. Notice that the first two steps involve the use of persistent data, but for the third step, the data is available only for the duration of the session.
-
The portal administrator uses the administrative interface to deploy a new portlet application WAR file or install a copy of a portlet. Either action creates a concrete portlet, which is a portlet parameterized by a single PortletSettings object. There can be many concrete portlets for each portlet. PortletSettings are read/write accessible and persistent. The PortletSettings contain configuration parameters initially defined in the portlet deployment descriptor.
The use of concrete portlets allows many instances of a portlet to run with different configurations, without creating extra portlet class instances. During the lifecycle of a single portlet, many concrete portlets can be created and destroyed. There is no object that explicitly represents the concrete portlet. The same concrete portlet can be shared across many users.
-
The portlet is placed on a page by a user or an administrator. This creates a concrete portlet instance, which is a concrete portlet parameterized by a single PortletData object. There can be many concrete portlet instances per concrete portlet. PortletData stores persistent information for a portlet that has been added to a page. For example, a user can edit a stock quotes portlet and save a list of stock symbols for the companies to track.
-
The scope of the PortletData depends on the scope of the page that the concrete portlet is on.
-
If an administrator puts a concrete portlet on a group page, then the PortletData object contains data stored for the group of users. This holds true for a group of users who have view access to the page. However, if users have edit access to the portlet on a group page, then a new concrete portlet instance is created for each user that edits the portlet. In this case, PortletData contains data for each user that edits the portlet.
-
If a concrete portlet is put on a user's page, the PortletData contains data for that user.
-
When a user accesses a page that contains a portlet, that creates a user portlet instance. When a user logs into the portal, the portal server creates a PortletSession for each of the user's portlets. A concrete portlet instance parameterized by a PortletSession is known as a user portlet instance. There can be many user portlet instances per concrete portlet instance.
A user portlet instance is a concrete portlet instance parameterized by a single PortletSession. There can be many user portlet instances per concrete portlet instance. The PortletSession stores transient information related to a single use of the portlet.
5.2.6 Portlet applications
Portlet applications provide the means to package a group of related portlets that share the same context. The context contains all resources, for example, images, properties files, and classes. All portlets must be packaged as part of a portlet application.
Concrete portlet application
A concrete portlet application is a portlet application parameterized with a single PortletApplicationSettings object. For each portlet application, there may be many concrete portlet applications. PortletApplicationSettings are read/write accessible and persistent. There is no object that explicitly represents the concrete portlet application.
A concrete portlet application contains at least one concrete portlet from the portlet application, but it is not required to contain all of them.
Portlet applications provide no code on their own but form a logical group of portlets. Beside this more logical gain, portlets of the same portlet application can also exchange messages.
5.2.7 Basic elements of the Portlet API
This section describes the basic elements of the Portlet API. Figure 5-4 shows a map of many of the common objects in the Portlet API.
Portlet class
The abstract Portlet class is the central abstraction of the Portlet API. All portlets extend this abstract class by extending one of its subclasses, such as PortletAdapter, that provide methods helpful for the developer.
Portlet life cycle
The portlet container calls the following methods of the abstract portlet during the portlet's life cycle:
-
init()
The portlet is constructed, after portal initialization, and then initialized with the init() method. The portal always instantiates only a single instance of the portlet, and this instance is shared among all users, exactly the same way a servlet is shared among all users of an application server.
-
initConcrete()
After constructing the portlet and before the portlet is accessed for the first time, the concrete portlet is initialized with the PortletSettings.
-
service()
The portal calls the service() method when the portlet is required to render it's content. During the life cycle of the portlet, the service() method is typically called many times. For each portlet on the page, the service() method is not called in a guaranteed order and may even be called in a different order for each request.
-
destroyConcrete()
The concrete portlet is taken out of service with the destroyConcrete() method. This can happen when an administrator deletes a concrete portlet during runtime on the portal server.
-
destroy()
When the portal is terminating, portlets are taken out of service, then destroyed with the destroy() method. Finally, the portlet is garbage collected and finalized.
Wrapper classes
Portlets do not extend the abstract Portlet class directly, but rather extend PortletAdapter or any other helper class that in turn extends Portlet. Extending one of these classes helps protect your portlet from changes in the abstract Portlet class. Moreover, it saves you the work of having to implement all of the methods of the Portlet interface, even if your portlet does not need to use them all. Using the PortletAdapter class, you only have to overwrite the methods you really need.
In its service() method, the PortletAdapter class invokes methods corresponding to the portlet mode. Portlets that extend this class can overwrite the doView(), doEdit(), and doHelp() methods without having to test the mode or write a specific service() method.
5.2.8 Frequently used objects
The following objects are most often used by a portlet:
-
PortletRequest
-
PortletResponse
-
PortletSession
Each of these objects is an extension of its counterpart in the Servlet API.
PortletRequest
The PortletRequest object is passed to the portlet through the login(), beginPage(), endPage(), and service() methods, providing the portlet with request-specific data and the opportunity to access further important information as listed below.
Attributes
Attributes are name/value pairs associated with a request. Attributes are available only for the scope of the request. The portlet can get, set, and remove attributes during one request. In the following example we are adding, getting, and removing an attribute.
portletRequest.setAttribute("key", objectToStore); portletRequest.getAttribute("key"); portletRequest.removeAttribute("key");
Parameters
Parameters are name/value pairs sent by the client in the URI query string as part of a request. Often the parameters are posted from a form. Parameters are available for the scope of a specific request. The portlet can get but not set parameters from a request. Notice that it differs from the attribute, since you can only get the parameters that are sent from the client, and the attributes can be set and modified at the Java code, so use the attributes when you are trying to send special attributes to the redirected JSP page. The extraction of a parameter would be similar to the following:
portletRequest.getParameter("nameOfTheHTMLfield");
Client
The Client object encapsulates request-dependent information about the user agent of a specific request. Information from the Client includes the manufacturer of the user agent or the type of markup that the client supports. The Client is extracted from the PortletRequest using the getClient() method. The following information can be obtained from the Client:
-
User agent
The portlet can get the String sent by the user agent to identify itself to the portal. The following code will return the user agent information:
portletRequest.getClient().getUserAgent();
-
Markup name
The portlet can get the String that indicates the markup language that the client supports, for example, "wml".
portletRequest.getClient().getMarkupName();
-
MIME type
The portlet can get the String that indicates the MIME types supported by the client (for example, text/vnd.wap.wml). If the portlet supports multiple types of devices, it should get the markup name rather than the MIME type.
portletRequest.getClient().getMimeType();
-
Capabilities
The Capability object contains more detailed information than the markup type about what the client can support, such as the level of HTML, JavaScript, or WML tables.
portletRequest.getClient().isCapableOf(Capability);
User data
The PortletData object represents data for a concrete portlet instance that is saved to persistent store. For example, a user can set a portlet e-mail application to check for new mail every 30 minutes. This preference is stored for the instance in the PortletData object.This is an excellent tool for storing user-portlet information without having to mind the persistence infrastructure.
portletRequest.getData().setAttribute("key", serializedObject); portletRequest.getData().store(); portletRequest.getData().removeAttribute("key"); portletRequest.getData().removeAllAttributes();
Session
The PortletSession represents user-specific, transient data for more than one request. In contrast with the request, which does not retain data after the request is completely processed, session attributes can be remembered and saved over more than one request.
portletRequest.getPortletSession().setAttribute("key",object); portletRequest.getPortletSession().getAttribute("key"); portletRequest.getPortletSession().removeAttribute("key");
Portlet settings
The PortletSettings object represents the configuration for a concrete portlet that is saved to persistent store. For example, an administrator can set to which host and port a Stock portlet should connect to get live data. This preference is stored for the concrete portlet in the PortletSettings object.
portletRequest.getPortletSettings().setAttribute("key",object); portletRequest.getPortletSettings().store(); portletRequest.getPortletSettings().getAttribute("key"); portletRequest.getPortletSettings().removeAttribute("key");
Mode
Portlet.Mode provides the current or previous mode of the portlet.
portletRequest.getMode(); //Will return a Portlet.Mode static value
PortletWindow
The PortletWindow object represents the state of the current portlet window. The portlet can access this object to determine if the portlet is currently maximized, minimized, or rendered in its normal view.
ModeModifier
This object can be used in a portlet action to set the portlet mode to its current, previous, or requested mode before the portlet is rendered. For example, a portlet in edit mode could process a user action and return the portlet to edit mode for more input before returning to view mode.
portletRequest.setModeModifier(Portlet.ModeModifier);
PortletResponse
The response object encapsulates information to be returned from the server to the client. PortletResponse is passed via the beginPage(), endPage(), and service() methods and can be used by the portlet to return portlet output using a Java PrintWriter. The response also includes methods for creating the PortletURI object or qualifying portlet markup with the portlet's namespace.
Use one of the following methods to create the PortletURI:
createURI()
Creates a PortletURI object pointing to the calling portlet with the current mode.
portletResponse.createURI();
createURI(PortletWindow.State state)
Creates a PortletURI object pointing to the calling portlet with the current mode and given portlet window state.
portletResponse.createURI(PortletWindow.State);
createReturnURI()
Creates a portletURI pointing at the caller of the portlet. For example, createReturnURI() can used to create a back button in an edit mode.
Each portlet runs in its own unique namespace. The encodeNamespace() method is used by portlets to bring attributes in the portlet output to avoid name clashes with other portlets. Attributes can include parameter names, global variables, or JavaScript function names.
portletResponse.createReturnURI();
PortletSession
The PortletSession holds user-specific data for the concrete portlet instance of the portlet, creating a portlet user instance. Concrete portlet instances differ from each other only by the data stored in their PortletData. Portlet user instances differ from each other only by the transient data stored in their PortletSession. Any persistent data must be stored using PortletData. Information stored in a portlet's instance variables is shared between all concrete portlet instances and even between all concrete portlets-with read and write access. Make sure you do not use instance attributes for user-specific data.
On the other hand, you have to be cautious about what the portlet adds to the session, especially if the portlet ever runs in a cluster environment where the session is being serialized to a shared database. Everything being stored in the session must be serializable, too.
Like the HttpSession, a PortletSession is not available on an anonymous page. However, in cases where an administrator places a portlet on an unauthenticated page, such as the Welcome page shipped with WebSphere Portal, the portlet should provide code to handle it.
During login, a PortletSession is automatically created for each portlet on a page. To get a PortletSession, the getSession() method (available from the PortletRequest) has to be used. The method returns the current session or, if there is no current session and the given parameter "create" is true, it creates one and returns it. For an example inspect the Portlet Request object.
5.2.9 Configuration objects
The following objects are used by the portlet to retrieve and store data, depending on how the data is used:
-
PortletConfig
-
PortletSettings
-
PortletApplicationSettings
-
PortletData
PortletConfig
PortletConfig provides the non-concrete portlet with its initial configuration. The configuration holds information about the portlet class. This information is valid for every concrete portlet derived from the portlet.
A portlet's configuration is initially read from its servlet deployment descriptor. This information is set by the portlet developer. The configuration is read-only and cannot be changed by the portlet.
The PortletConfig is passed to the portlet in the init() method of the abstract Portlet and is used to access portlet-specific configuration parameters using getInitParameters(). PortletConfig parameters are name/value pairs available for the complete life cycle of the non-concrete portlet. Non-concrete portlet parameters are defined by the <init-param> tag in the servlet deployment descriptor.
getPortletConfig().getInitParameter("parameterName"); getPortletConfig().getContext().send("string",PortletMessage); getPortletConfig().supports(Portlet.Mode); getPortletConfig().supports(PortletWindow.State);
PortletSettings
The PortletSettings object provides the concrete portlet with its dynamic configuration. The configuration holds information about the concrete portlet. This information is valid for every concrete portlet instance of the concrete portlet.
A concrete portlet's configuration is initially read from the portlet deployment descriptor. The configuration is read-only and can be written by the portlet only when the portlet is in configure mode. This information is normally maintained by the portal administrator and may be changed while the portal server is running. The portlet can get, set, and remove attributes during one request. To commit the changes, the store() method has to be called.
The PortletSettings object can be accessed with the getPortletSettings() method, available from the PortletRequest. Often, it is used to access portlet-specific configuration parameters using getAttribute(). Attributes are name/value pairs available for the complete life cycle of a concrete portlet. Concrete portlet attributes are defined by the <config-param> tag in the portlet deployment descriptor.
portletRequest.getPortletSettings().setAttribute("key",object); portletRequest.getPortletSettings().store(); portletRequest.getPortletSettings().getAttribute("key"); portletRequest.getPortletSettings().removeAttribute("key");
PortletApplicationSettings
The PortletApplicationSettings object provides the concrete portlet application with its dynamic configuration. The configuration holds information about the portlet application that is shared across all concrete portlets included in the application.
A concrete portlet application's configuration is initially read from the portlet deployment descriptor. The configuration is read-only and can be written by the portlet only when the portlet is in configure mode. This information is normally maintained by the portal administrator and may be changed while the portal server is running. A portlet in the application can get, set, and remove attributes during one request. To commit the changes, the store() method has to be called.
The PortletApplicationSettings can be accessed with the getApplicationSettings() method, available from the PortletSettings object. It is used to access portlet-specific configuration parameters using getAttribute(). Attributes are name/value pairs available for the complete life cycle of a concrete portlet application. Concrete portlet application attributes are defined by the <context-param> tag in the portlet deployment descriptor.
portletRequest.getPortletSettings().getApplicationSettings().setAttribute(" key",object); portletRequest.getPortletSettings().getApplicationSettings().store(); portletRequest.getPortletSettings().getApplicationSettings().getAttribute(" key"); portletRequest.getPortletSettings().getApplicationSettings().removeAttribut e("key");
PortletData
PortletData holds data for the concrete portlet instance. For each occurrence on a page there is a concrete portlet instance. The PortletData contains persistent information about the concrete portlet instance, while the PortletSession contains only the transient data of the user portlet instance.
There is one concrete portlet instance for each occurrence of a portlet on a page. A page can be owned by either a single user (personal page) or by a single group of users (group page). PortletData contains user-specific data on a personal page and group-specific data on a group page.
The PortletData object stores attributes as name/value pairs. The portlet can get, set, and remove attributes during one request. To commit the changes, the store() method has to be called. The data is read-only and can be written by the portlet only when the portlet is in edit mode.
portletRequest.getData().setAttribute("key", serializedObject); portletRequest.getData().store(); portletRequest.getData().removeAttribute("key"); portletRequest.getData().removeAllAttributes();
5.2.10 Miscellaneous objects
The following miscellaneous objects are used by portlets:
-
PortletContext
-
PortletWindow
-
User
PortletContext
The PortletContext interface defines a portlet's view of the portlet container within which each portlet is running. PortletContext also allows a portlet to access resources available to it. For example, using the context, a portlet can access the portlet log, access context parameters common to all portlets within the portlet application, obtain URL references to resources, or access portlet services.
The most important information related to the PortletContext is described in the following paragraphs.
InitParameters
Parameters are name/value pairs available to all portlets within the Web application. These are defined in the Web deployment descriptor under the <context-param> element. For example, if a group of portlets share a context parameter called "Webmaster" that contains the portal site's administrator e-mail, each portlet could get that value and provide a "mailto" link in their help.
Attributes
Attributes are name/value pairs available to all portlets within the Web application. The portlet can get, set, and remove attributes. Attributes of the context are stored on a single machine and are not distributed in a cluster.
getPortletConfig().getContext().setAttribute("key", object); getPortletConfig().getContext().getAttribute("key"); getPortletConfig().getContext().removeAttribute("key");
Localized text
The getText() method is used by the portlet to access resource bundles within a given locale.
getPortletConfig().getContext().getText("bundle", "key", "locale");
Resources
It is through the PortletContext that a portlet can load or include resources located in the portlet's application scope. Available methods are include() and getResourceAsStream(). The include() method is typically used to invoke JSPs for output.
getPortletConfig().getContext().include("JSP",request,response); getPortletConfig().getContext().getResourceAsStream("path");
Messaging
Through messaging it is possible to communicate between portlets and share data or send notifications. A message is sent by using the send() method. For more information, see Portlet messaging.
getPortletConfig().getContext().send("portletName", PortletMessage);
Portlet services
The PortletService object allows portlets to use pluggable services via dynamic discovery.
getPortletConfig().getContext().getService(service);
PortletWindow
The PortletWindow object represents the window that encloses a portlet. For example, on an HTML page, the portlet window can typically be rendered as a table cell. The portlet window can send events on manipulation of its various window controls, like when the user clicks minimize or close. The portlet, in turn, can interrogate the window about its current state. For example, a portlet may render its content differently depending on whether its window is maximized or not. The PortletWindow is available using the getWindow() method of the PortletRequest object.
PortletWindow.getWindowState(); PortletWindow.setWindowState(PortletWindow.State);
User
The User class represents the users of the portal. The User class contains methods for accessing attributes that make up the user profile, such as the user's full name or the username. The User class abstracts the underlying physical implementation of the one or more data stores which actually hold the user information.
In WebSphere Portal, the User class is part of the com.ibm.wps.puma package. This class and several others represent the portal server's API to the user subsystem in Member Services. To obtain the Javadoc for this API, locate the document titled "Javadoc for the WebSphere Portal User and Group objects" on the software support site:
-
http://www.ibm.com/software/support
The classes in the com.ibm.wps.puma package provide the only API available to access attributes of the user. In subsequent releases of WebSphere Portal, a new API will become available to access the new features of the user subsystem. In that time frame, the com.ibm.wps.puma package will be maintained for a time for backward compatibility, but will no longer be enhanced to accommodate new function.
Note | The getUser() method is located at the PortletRequest and PortletSession. The portletsession.getUser() method is deprecated and, in subsequent releases, will only return null.
portletRequest.getUser().getFamilyName(); portletRequest.getUser().getFullName(); portletRequest.getUser().getGivenName(); portletRequest.getUser().getID(); portletRequest.getUser().getLastLoginTime(); portletRequest.getUser().getNickName(); portletRequest.getUser().getUserID(); |
5.2.11 Portlet events
Portlet events contain information about an event to which a portlet might need to respond. For example, when a user clicks a link or button, this generates an action event. To receive notification of the event, the portlet must have an event listener implemented within the portlet class.
-
Action events: Generated when an HTTP request is received by the portlet container that is associated with an action, such as when the user clicks a link.
-
Message events: Generated when another portlet within the portlet application sends a message.
-
Window events: Generated when the user changes the state of the portlet window.
A portlet has a different processing and rendering sequence than a servlet. A servlet does all of its processing in the service() method. A portlet, on the other hand, uses a two-phase processing that is split between an action processing and service. This split is necessary to accommodate communication between portlets before rendering output in the service stage. The action processing is guaranteed to complete before a portlet is called to render.
During action processing, the portlet implements an ActionListener interface. The ActionListener interface provides the actionPerformed() method, to which an ActionEvent object is passed. When a user clicks on a link or a submit button, an ActionEvent can be generated. The portlet action can be obtained from the ActionEvent, which describes the triggering event. When the actionPerformed() method is invoked, a response object is not available because this is not a rendering step. All state changes should be handled during action processing.
Portlets should use the service phase only to render portlet output. The service() method is not only called following the actionPerformed() processing when a user clicks on a link or button in a portlet, but is also called when the portal page is refreshed. Thus, given a page with two portlets, A and B, when the user clicks on a link in portlet A, actionPerformed() and doView() is called for portlet A, but only the doView() method is called for portlet B. Once the content generation phase has started, no further events will be delivered. For example, messages cannot be sent from within the beginPage(), service(), and endPage() methods. The resulting message event would not be delivered and is essentially discarded.
The event listener is implemented directly in the portlet class. The listener can access the PortletRequest from the event and respond using the PortletRequest or PortletSession attributes.
Action events
An ActionEvent is sent to the portlet when an HTTP request is received that is associated with a portlet action. To receive action events, the portlet class must implement the ActionListener interface and a portlet action. A portlet action can be one of the following types:
-
Simple portlet action String
-
PortletAction object
These actions are explained in the following paragraphs.
Simple portlet action String
Actions created as simple actions can be executed multiple times, enabling a user's back button to work. Links created with simple portlet actions are represented in the URL rather than in the session. Therefore, portlets with simple actions can be placed on an anonymous page where no session exists. Simple portlet actions are associated with action events using the getActionString() method.
PortletURI.addAction(String simpleAction); String ActionEvent.getActionString();
Simple portlet actions are not available in the Portlet API prior to WebSphere Portal Version 4.2. A portlet can determine if the portal server it is running on supports simple actions or not by checking the Portlet API version. The version of the Portlet API on servers that support simple actions has changed from 1.1 to 1.2. Here is example code which illustrates how to check for simple action support:
if ((portletContext.getMajorVersion() <= 1) && (portletContext.getMinorVersion() <= 1)) { // cannot use simple actions } else { // simple action support is present on this server }
PortletAction object
The PortletAction object has been deprecated in favor of simple portlet action strings. It is maintained in the Portlet API to support existing portlets that use PortletActions.
Window events
A WindowEvent is sent by the portlet container whenever a user clicks on one of the control buttons that change the window's state, such as maximize, minimize or restore. A WindowEvent can be used, for example, to display more information when the user maximizes the portlet than would be shown in its normal state. To receive window events, the WindowListener interface must be implemented at the portlet class.
The Portlet API provides a WindowAdapter class that implements empty methods of the WindowListener. By extending WindowAdapter, the portlet developer needs to implement only those callback methods needed by the portlet. Without the WindowAdapter, you must implement all callback methods, even if the method is empty.
Message events
Message events can be sent from one portlet to others if the recipient portlets are members of the same portlet application and are placed on the same page as the sending portlet. Additionally, a DefaultPortletMessage can cross portlet application boundaries and may be sent to all portlets on a page. A MessageEvent can be sent actively to other portlets only when the portlet is in the event processing cycle of the portlet container, otherwise an exception is thrown. There are two different types of messages:
-
Single addressed messages: Messages sent to a specific portlet by specifying the portlet name on the send() method
-
Broadcast messages: Messages sent to all portlets on the page
Message events are useful when changes in one portlet should be reflected in another one. An object with the type PortletMessage has to be implemented and is passed via the MessageEvent. The portlet receiving the message must implement the MessageListener interface and an object with the type PortletMessage.
| < Day Day Up > |
|