ONJava.com -- The Independent Source for Enterprise Java
oreilly.comSafari Books Online.Conferences.

advertisement

AddThis Social Bookmark Button

What Is a Portlet, Part 2
Pages: 1, 2, 3, 4, 5

The Portlet Tag Library

The portlet specification mandates that every portlet container should provide an implementation of the portlet tag library, portlet.tld. The portlet tag library enables JSPs that are included by portlets to have direct access to portlet-specific elements such as RenderRequest and RenderResponse. It also provides JSPs with access to portlet functionality such as the creation of portlet URLs. JSP pages using the tag library must declare this in a taglib declarative statement like this (using the suggested prefix value):

<%@ taglib uri="http://java.sun.com/portlet" prefix="portlet" %>

Available tags include the following:

  1. <portlet:defineObjects/>: This tag must appear to define the following variables in the JSP page: renderRequest, renderResponse, and portletConfig. A JSP using the defineObjects tag may use these variables from scriptlets throughout the page.

  2. <portlet:actionURL/>: The portlet actionURL tag creates a URL that must point to the current portlet and must trigger an action request with the supplied parameter. The parameters may be added to the URL by including the param tag between the actionURL start and end tags:

    <portlet:actionURL windowState="maximized" portletMode="edit">
            <portlet:param name="action" value="editStocks">
    </portlet:actionURL>

    The example creates a URL that brings the portlet into EDIT mode and MAXIMIZED windowState to edit the stock quote list.

  3. <portlet:renderURL/>: This tag creates a URL that must point to the current portlet and must trigger a render request with the supplied parameter. The renderURL tag also takes parameters using the param tag, and allows the attributes forwindowState and portletMode.

  4. <portlet:namespace/>: This tag produces a unique value for the current portlet. Namespacing ensures that the given name is uniquely associated with this portlet and avoids name conflicts with other elements on the portal page or with other portlets on the page.

    <A HREF="javascript:<portlet:namespace/>test()">Encoded name</a>

Portlet Preferences

One of the requirement for portlets is that the user should be able to customize their view or the behavior of the portlet. The portlet specification provides you with a PortletPreferences object that allows you to store configuration data as name-value pairs. The most valuable part is that configuration is persisted, so it will be available across server restarts. You don't have to worry about how the portlet container is storing or retrieving configuration data. Another important point in the specification is that preferences attributes are user-specific. This means that you cannot design a portlet where changes made by an administrator are stored in PortletPreferences object and made available to all users (actually, some portlet vendors provide way to achieve this in a container-specific way).

We will make one more change to our HelloWorld portlet so that it remembers the userName even after a restart. Change HelloWorld.java like this:

protected void doView(RenderRequest request, 
  RenderResponse response)
  throws PortletException, IOException {
    response.setContentType("text/html");
    String userName =
      (String)request.getPreferences()
      .getValue("userName",null);
    if (userName != null)
          response.getWriter().println("Hello " + userName);
    else
      response.getWriter().println
        ("Go to edit mode and set name");
}

public void processAction(
  ActionRequest actionRequest, 
  ActionResponse actionResponse) 
  throws PortletException, IOException {
    String userName =
      actionRequest.getParameter ("userName");
    PortletPreferences pref =
      actionRequest.getPreferences();
    pref.setValue("userName",userName);
    pref.store();
    actionResponse.setPortletMode(PortletMode.VIEW);
}

We are not using the PortletSession object to store the userName attribute anymore. Inside processAction(), we first get the value of the userName attribute submitted by user, and set it in the PortletPreferences object by calling the method pref.setValue("userName",userName). The next step is to call the store() method on PortletPreferences, which saves the changes made in PortletPreferences to the persistence store.

There are a couple of important points to remember. First, you can modify PortletPreferences only inside of the processAction() method. Trying to call it during render() will result in an IllegalStateException. Secondly, if you don't call the store() method after changing PortletPreferences and before exiting the processAction(), then those changes will be discarded. The PortletPreferences interface also defines a reset() method, which can be used to reset values of preferences attributes to default values.

Caching

The portlet specification defines an expiration-based caching mechanism. This caching mechanism is per-portlet and per-client, with a restriction that cached content must not be shared across different user clients displaying the same portlet.

The way it works is that a portlet that wants its content to be cached using the content cache must define the duration of the expiration cache in a deployment descriptor, like this:

<portlet>
  <expiration-cache>300</expiration-cache>
</portlet>

Now suppose Portlet A has defined that it wants it content to be cached for 300 seconds and it is placed on a page along with Portlet B. If the user performs some action on Portlet B, the portlet container can choose to use cached content generated by Portlet A instead of calling its render() method again. But if the user performs some action on Portlet A, the container should invalidate the cached content of Portlet A and call its render() method once again.

Please note that it is not necessary for a portlet container to implement caching, and it can choose to disable caching any time it wants. But if the container does implement this feature, it helps improve portlet response time and reduce load on the server.

Conclusion

Portals strive to be the next-generation desktops for users. They will provide you with one desktop with different windows for all of the applications that you might need. It will be very easy for an administrator to apply policy on what you can or can not see. The administrator can also install or update new applications on the server and make those applications available to all users.

With JSR-168, one major hurdle of portlet technology advancement has been removed. Now if your portlet application is JSR-168-compliant, it can be deployed on any compliant server and it will appear as one window on the user's desktop.

Resources

Sunil Patil has worked on J2EE technologies for more than five years. His areas of interest include object relational mapping tools, UI frameworks, and portals.


Return to ONJava.com.