Skip to main content

skip to main content

developerWorks  >  Sample IT projects  >

WebSphere Portal V4 programming, Part 2: Portlet application programming

Give and take -- portlet messaging techniques

developerWorks
Document options

Document options requiring JavaScript are not displayed

Discuss

Sample code


Rate this page

Help us improve this content


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.



Back to top


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.



Back to top


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:

  1. 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.
  2. 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.
  3. 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.
  4. 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.



Back to top


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



Back to top


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.



Back to top


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.



Back to top


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.



Back to top


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.



Back to top


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!




Back to top


Download

NameSizeDownload method
i-portal2v4.zipHTTP
Information about download methods


Resources



About the authors

David Lection

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.


Varad Ramamoorthy

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


Please take a moment to complete this form to help us better serve you.



YesNoDon't know
 


 


12345
Not
useful
Extremely
useful
 


Back to top