Level: Introductory David Lection (lection@us.ibm.com), Senior Programmer, IBM Varadarajan Ramamoorthy (varad@us.ibm.com), Programmer, IBM
01 Aug 2002 This is the second article in a series on developing portlets for WebSphere Portal. In this article, David and Varad introduce portlet to portlet collaboration using portlet messaging, then cover in depth some techniques to use messaging in your portlets. They also explain how WebSphere Portal supports and processes messages between portlets, and how to build the sample portlets that are included. You can use the sample portlets in this article as building blocks for highly functional messaging portlet applications.
Part 1 of this series provides an introduction to WebSphere Portal V4.1 portlet structure and programming.
Editor's Note: This article is an updated version of an article written by David Lection and Varad Ramamoorthy in March 2002. That article was about WebSphere Portal Versions 1.2 and 2.1. This updated version is about the most recent follow-on product, WebSphere Portal Version 4.1, and includes updated portlet source code that has been tested on Version 4.1. Introduction
Web site developers face an increasingly complex task of integrating all kinds of user-oriented content into a
seamless, well-designed interface. Portal servers provide the framework for you to build a superior experience that provides users with compelling integrated content. Portlets are the building blocks of a high quality portal. Dynamic and
reactive portlets provide users with a fresh experience every time they view the portal page. WebSphere Portal V4.1 is the latest release of IBM's flagship portal server software. Version 4.1 supports many new functions and capabilities:
- J2EE compliance
- Support for Web-services-based portlets
- A new, more powerful page customizer
- Page groups
- New portal look and feel, including more selectable themes and skins
- Portlet API enhancements
The portal server empowers portlet programmers to
provide compelling content for their users. WebSphere Portal has built-in support to allow portlets
in a portlet application to communicate by sending messages to peer portlets in the application. When portlets react and update to underlying messages, it gives the portal a
more live and reactive feel. For example, users see users see the price of IBM stock going down (remember, this is only an example) in one portlet, while another portlet informs them "buy IBM now."
Specifically, one portlet presents some data and the other portlet suggests an
action to the user. Portlets operating in this fashion give users a more
personal experience, and portlet messaging makes this possible.
Portlet messaging basics
Adding messaging to a set of cooperating portlets is a straightforward task.
One portlet typically is the message sender, while another portlet is the
message receiver. As the sender detects some condition it formats a message and
sends it to the receiver. The receiver portlet then receives the message from a
message event handler and processes the message. A single portlet can both send
and receive messages.
There are some basic rules for portlet messaging. First, the portlets must
belong to the same portlet application. A portlet application is a set of one or more portlets packaged together
in the same portlet archive, or PAR file. The message object sent between the portlets is typically a custom,
application-specific Java object. WebSphere Portal uses a unique class loader for each portlet application to provide
protection and security between the applications. Because the messaging portlets need to share the Java
message object they must be loaded by the same class loader, and therefore reside in the same portlet
application.
The second rule is that the portlets must be displayed on the same portal page, primarily for
performance reasons. Since only one portal page is visible at any moment, there is little need to send a
message to a portlet that is not on the same page.
Portal event and messaging process
When a portlet submits an event to the portal server, the portal
aggregation process begins. It is important to understand the underlying portal event
and message process; it lets you implement portlets that send messages at the right time, so the receiver portlets receive their messages at the appropriate time. The event handling and aggregation process has four steps:
- Process all action events
When the portal receives an event from a client, it decodes the action URI sent by the client and
propagates an action event to the appropriate portlet. Typically this is a single event to a single portlet. When a
portlet's action listener is called to process an action event, this is a good time to send a portlet message.
- Process all message events
Portlets can send multiple messages, so this process continues to loop until all message events have been processed. A portlet's message listener is called if a message is sent to the portlet. If a portlet sends a message as a result of receiving a message, the second message will also be sent to and processed by the
second target portlet. This continues until there are no more pending message events.
- Process all window events
Portlets can be minimized, maximized, or restored to normal size by users. A portlet may also request a particular size. Sizing operations result in a potential series of window events sent to portlets whose sizes
are changing. This process continues until all window events are processed.
- Portlet rendering process
Once all events have been processed in the above order, the portal aggregator begins calling each portlet on the display page to have it return the content contribution of the portlet to the page aggregation. When the aggregation process is complete, the finished page is returned to the browser.
Events are not processed in step 4 of the event and aggregation process above. If a portlet
sends a message during step 4 from a view method in the portlet, the
message will not be delivered or processed. So if a visible collaborative result is expected in the portal
display, then the portlet must send any messages during steps 1 and 2 of the
event and aggregation process.
Sample portlets
The sample portlets MessageSender and MessageReceiver show how to implement messaging between portlets. Figure 1 below is a sample screen showing the portlets. Figure 1. Messaging portlets

You begin by selecting a city from the map on the left. A pop-up menu prompts you to select the store location or the number of employees.
Once selected, a message is generated by the map (MessageSender) portlet and
sent to the target receiver (MessageReceiver) portlet instance. The receiving
portlet displays the data for the selected city. The two portlets on the right in Figure 1 are instances of the same MessageReceiver portlet. The top instance shows the city's
store location and the bottom instance shows the number of employees at the selected store. Next we'll discuss the sample portlets step by step.
The message sending portlet
The structure of our MessageSender portlet follows the standard model-view-controller (MVC) design pattern. JavaServer Pages (JSP) technology is used to display the content of the portlet. MessageSenderPortlet sample code
public class MessageSenderPortlet extends AbstractPortlet
{
protected final static String viewJSP
= "/PORTLET-INF/MessageSender/html/MessageSenderView.jsp";
public final static String DEFAULT_ACTION = "SendMessage";
public final static String CITYNAME = "cityName";
public final static String MESSAGE_ID = "MessageSender";
public final static String PORTLETNAME = "portletname";
public void doView ( PortletRequest request, PortletResponse response )
throws PortletException, IOException
{
// Format the default action event URI
PortletURI baseURI = response.createReturnURI();
DefaultPortletAction
action = new DefaultPortletAction(DEFAULT_ACTION);
baseURI.addAction(action);
request.setAttribute("BaseURI", baseURI.toString());
// Call the JSP to display the portlet output
getPortletConfig().getContext().include(viewJSP, request, response);
}
}
|
The portlet is small and straightforward. A portlet URI is constructed. This URI defines the action event that
propagates the submit action back to the portlet's action listener. Once the URI is constructed, the
portlet's content is rendered by delegating the rendering to the MessageSenderView JSP page. This
is accomplished in the call to the portlet context include method shown above. The portlet displays a map of
the state of North Carolina and some descriptive help text to guide users with the map.
When users click on a city, a snippet of JavaScript in the MessageSenderView JSP page displays a popup context menu from which they select either the store location or number of
employees. The JavaScript then saves both the city name and the data item requested, and submits them to
the portal server as an action event. The event is presented to the actionPeformed method in the same class. This is a slight change from the original version of the code. Event handling methods were placed in separate classes in previous versions of the portal. With WebSphere Portal V4.1, event handlers are added directly to the base portlet class. MessageSenderActionListener's actionPerformed Method
public void actionPerformed(ActionEvent event)
{
DefaultPortletAction action = (DefaultPortletAction)event.getAction();
if ( action != null )
{
AbstractPortlet portlet = (AbstractPortlet)event.getPortlet();
PortletRequest request = event.getRequest();
if(action.getName().equalsIgnoreCase
(MessageSenderPortlet.DEFAULT_ACTION))
{
String portletName
= (String) request.getParameter(MessageSenderPortlet.PORTLETNAME);
try
{
String cityName
= (String) request.getParameter(MessageSenderPortlet.CITYNAME);
// Create a portlet message and add message parameters.
DefaultPortletMessage dpm
= new DefaultPortletMessage(MessageSenderPortlet.MESSAGE_ID);
dpm.addParameter(MessageSenderPortlet.CITYNAME, cityName);
// Here you can specify the name of the portlet that you want to
// send the message to or you can specify "null", so
// that the message
// will be sent to all the portlets on that page.
portlet.getPortletConfig().getContext().send
(portletName, dpm, request);
}
catch( AccessDeniedException ade )
{
PortletLog pLog = portlet.getPortletLog();
pLog.error
( "MessageSenderActionListener: error sending message to: "
+ portletName );
}
}
}
}
|
Within the try block of code above, the portlet message is constructed as an
instance of the DefaultPortletMessage class and sent to the target portlet.
Both the target portlet name and the city name are extracted from attributes in
the portlet request. The city name is added to the portlet message as a
parameter using the addParameter method, and the portlet name is used in the send
method to determine which portlet is the target for the message. If an error
occurs during the message creation or sending, the catch block will be invoked
and an error message will be written to the portlet message log.
The message receiving portlet
The structure of our MessageReceiver portlet also follows the MVC design pattern. Because the portlet can display either the store location or number of employees, the portlet must select a particular JSP page for the portlet display. To do this, you specify the JSP page in a
configuration parameter in the portlet.xml file. The following is a fragment of XML from the portlet.xml
file showing the specification of the JSP page for the store location.
<config-param>
<param-name>viewJSP</param-name>
<param-value>/PORTLET-INF/MessageReceiver/html/AcmePartsLocationView.jsp
</param-value>
</config-param>
|
I have included the servlet definition of the
MessageReceiverPortlet class in the XML snippet to show you a declaration of
the portlet in the Web application descriptor XML document (web.xml).
Portlet applications in this version of the portal require both a
portlet application descriptor XML file (portlet.xml) and Web application descriptor. Samples of both descriptor documents are
included in the source code archive included with this article (see Resources). The MessageReceiver portlet contains two methods:
- init method - determines the JSP page to use for the portlet rendering.
- doView method - is responsible for rendering the portlet's content. The value of the selected city name is placed in the portlet request
object for subsequent use by the JSP page.
The portlet context include method is called to complete the portlet rendering process. MessageReceiverPortlet sample code
public class MessageReceiverPortlet extends AbstractPortlet
{
protected String viewJSP = null;
public final static String VIEW_JSP_ATTRIBUTE = "viewJSP";
public void init(PortletConfig pConfig) throws UnavailableException
{
super.init( pConfig );
viewJSP = pConfig.getAttribute( VIEW_JSP_ATTRIBUTE );
if ( viewJSP == null || viewJSP.trim().equals("") )
{
throw new
UnavailableException("MessageReceiver: Parm viewJSP not defined");
}
}
public void doView( PortletRequest request, PortletResponse response )
throws PortletException, IOException
{
PortletData portletPersistence = request.getData();
String cityName = (String)
portletPersistence.getAttribute(MessageSenderPortlet.CITYNAME);
if ( cityName == null )
{
cityName = "";
}
// Store the fieldname value in the portlet request for the JSP
request.setAttribute(MessageSenderPortlet.CITYNAME, cityName);
// Call the JSP to display the portlet output
getPortletConfig().getContext().include( viewJSP, request, response );
}
}
|
The two portlets, the portlet application descriptor portlet.xml, and the associated JSP pages are packaged into a PAR file for installation on the portal server.
Building the portlet application
If you make modifications or enhancements to the portlets, you should recompile the classes and package
the portlet application into a WAR file. The build process has been automated and the source archive contains
command files for compiling each portlet separately. The following command file compiles both portlets.
echo off
cls
set bd=C:/MessagingPortlets
javac -d %bd%/WEB-INF/classes
%bd%/WEB-INF/classes/com/ibm/wp/samples/messagingPortlets/Mes*.java
jar cvf0 MessagingPortlets.war images
jar uvf0 MessagingPortlets.war jsp
jar uvf0 MessagingPortlets.war WEB-INF
|
You'll need to modify the set statement so it specifies the proper directory where you've copied the portlet application source code. Before building the portlet ensure you have your Java class path set to include the
required portal JAR files:
- portlet-api.jar
- wpsportlets.jar
- j2ee.jar
- wps.jar
- jlog-2.2.jar
WebSphere Portal Version 4.1 also includes the Portal Toolkit, a powerful set of extensions that plug into WebSphere Studio Application Developer and extend Application Developer for building and debugging portlets. You can create a portlet application project in Application Developer and import these portlets into the project for
build and packaging. Application Developer also features a JSP editor, and the Portal Toolkit provides remote portlet debug facilities for portlet applications. Once you have successfully built and tested the portlet application, copy the WAR file to your portal server for installation.
Installing the messaging portlet application
To begin installing the messaging portlet application, proceed to your portal home page and log into the portal as an administrator. Click on the Administration tab to display the Portlet Administration page. You'll install the MessagePortlets.war
file using the Install Portlet Application page. Click Install and import the portlet
application. You'll be presented with a series of screens and confirmations. After you have installed the portlet application, you'll need to add the individual portlets to a portal
page using the portal page customizer. For the portlets to operate they must be installed on the same portal page.
To easily observe the interactions between the portlets, place the two receiver portlet instances to the immediate right or left of the map portlet instance on your portal page. When a receiver portlet instance changes based on
city selection, the selected city is persisted by the portlet so it is selected the next time the portlet is viewed.
The example portlets in this article have been tested to work on Internet Explorer Versions 5.50 and 6.00, and Netscape Navigator Version 4.72. If you test the portlets on other HTML browsers and find an incompatability, please send us an e-mail explaining the symptoms of the error.
Conclusion
We've only skimmed the surface of what can be accomplished when portlets collaborate using messaging. The messaging concept is easy and straightforward, but portlets that communicate with messaging achieve powerful and compelling results. So let your imagination guide you, and your programming skills drive you!
Download | Name | Size | Download method |
|---|
| i-portal2v4.zip | | HTTP |
Resources
About the authors  | 
|  |
David B. Lection is a Senior Programmer and chief tools architect for WebSphere Portal and related products. You can contact David at lection@us.ibm.com.
|
 | 
|  |
Varadarajan Ramamoorthy is a contract programmer working on WebSphere Portal and related service offerings. You can contact Varad at varad@us.ibm.com.
|
Rate this page
|