http://www.developer.com/

Back to article

An Introduction to Java Enterprise Portals and Portlet Development


November 2, 2009

This article covers the rudiments of developing Java Portlets (per the Java Portlet Specification), and portal run time containers for the Java Portlets including both enterprise portal servers and open source portals. Since the release of the original JSR 168: Portlet Specification, in 2003, portlet development popularity has risen steadily in both the enterprise world and in the open source communities.

The release of JSR 286: Portlet Specification 2.0, in June 2008, solidified Portlet technology as one of the most popular web development technologies currently available. Over 20 popular open source Portlet containers and portals are currently available, including the Sun Liferay portal, the eXo Platform, Jakarta Pluto, and so forth. In addition, there are numerous offerings from major software vendors, such as Vignette Portal, IBM WebSphere Portal, Sun OpenPortal, Oracle Portal (formerly BEA WebLogic Portal), etc.

Foundation of Web Portals


Figure 1. Yahoo Portal:
Portal customization causes sites to remember a user's preferences and display the content each user prefers.

So what is a portal? Since the early days of the world-wide web, most web destinations fall into one of three categories: web sites, search engines, and portals. A web site is a personal or corporate page; a search engine is a web crawler that indexes personal or corporate pages for easy searching; and a portal is a site that presents a smorgasbord of unrelated information in one place. (Currently, many search engines such as Yahoo.com or MSN also act as portals). As portals evolved, they offered new features, such as the ability to save user preferences and other customizations. Users could configure portals to "remember" their settings, the type of information a user wanted to see next time, or the background color a user liked. For content, customization meant that if Joe's preferences were news and stocks, but Sam's were entertainment and astronomy, then Joe and Sam might see entirely different pages of information (see Figure 1).

To customize a portal, various pieces of unrelated information had to be presented and placed in some organized fashion on the page. The most intuitive way to do that, which most modern portal seem to conform with, are to create rectangular shaped Portlets, arranged on one page. Wikipedia defines a web portal as a web application that "presents information from diverse sources in a unified way," and Portlets as "pluggable user interface software components."

The first portals had an underlying goal to appeal to users by providing information the user was interested in, wrapped in a customized interface. Improving user appeal served to increase the "stickiness" of portals, which increased their value because advertising was (and still is) the main business model of most of the web portals. Therefore, getting users to return to the site is highly desirable.

Author's Note: The term "stickiness" is used by online advertisers to define the popularity and return traffic to the site.


Figure 2. Yodlee MoneyCenter:
Here's an example of a financial information aggregator that uses portlets to display customized information.

These early "general purpose" portals later spawned specific purpose portals. Mostly in the enterprise space, these specific purpose portals included enterprise intranet sites, B2B sites, and sites that wanted to present a specific type of information, but from different sources. For example, financial information aggregators such as HSBC EasyView and others (see Figure 2), paint an entire financial picture for users. These sites present Portlets containing financial information sources such as investment portfolios, 401k plans, credit cards, and bank accounts.

Corporate intranet sites, which were originally built to show helpful links for employees, evolved to present RSS feeds, web services, and data from legacy systems, all in one place. According to Wikipedia, many modern enterprise portals allow "a way for enterprises to provide a consistent look and feel with access control and procedures for multiple applications and databases, which otherwise would have been different entities altogether."

Enterprise Portals and Portlet Containers

So how does a portal differ from a portlet container? The portal is the user-facing site or the interface for the portlet container. The portlet container is the platform that manages portlets through their complete lifecycle. A portlet container provides a runtime environment for portlets implemented according to the standard Portlet API. Using this platform, portlets can be instantiated, used and finally destroyed. The Java portlet container is not a stand-alone container like the servlet container; instead, it is implemented as a thin layer on top of the Java Servlet container and reuses its functionality. Architecturally, it provides an interface between the portal and portlets.

Early web portals were built on custom technology developed "in-house," which meant that portlets written for one platform or container were not compatible with another platform or container. Often developers had to duplicate or rewrite the supporting code for features such as adding new portlets, minimizing portlet windows, or dragging a portlet to a new location on the page. This situation changed in 2003, when Sun Microsystems released JSR 168. The original specification, although not perfect, provided a standardized portlet API that defined portlet lifecycle and a number of other features.

Today, most portlets and portlet containers adhere to either JSR 168 or the later JSR 286 specification, so portlets written for one Java container are compatible with other containers.

Author's Note: One exception was IBM's WebSphere portal, which developed its own IBM Portlet API, similar to the Sun Portlet API. However, the latest IBM WebSphere portal has dropped support for the IBM Portlet API and is now using and supporting the standard JSR 168/286 Java API.)

Modern portlet containers can be used for building intranet sites, commercial sites, or personal sites. Many provide out-of-the-box features such as internalization support, tools for content management, role-based authorization, Secure Single Sign On (SSO) support, search or tagging support, etc. Figure 3 and Figure 4 show examples of portlets in action.


Figure 3. Apache Jetspeed Portal:
Here, the calendar portlet appears in the second row of portlets.

Figure 4. Calendar Portlet Being Moved:
In this figure, a user is moving the calendar portlet to another position.

Developing a Portlet

To begin, create a standard Java project. The first step in making it a portlet project is to create a portlet.xml file, which is a deployment descriptor that specifies what portlets are available for the container and which class should be used to instantiate them. However, the specification does not define how a portal registers and recognizes portlets.

Author's Note: For the examples in this article, I used the Java Spring framework, which provides some helpful utilities and container beans, to simplify some of the Portlet API plumbing. I also used the Eclipse IDE to set up the portlet project. However, any portlet developed according to the JSR 168 or JSR 286 specifications should be able to run on any compliant container, so you don't have to use the same technology to code and build the examples.

Figure 5 shows the structure for the sample portlet project.



Figure 5. Portlet Project Structure:
The figure shows the structure of the sample portlet project.

The portlet.xml file for the sample project defines a single portlet:

<?xml version="1.0" encoding="UTF-8"?>
<portlet-app xmlns=
  "http://java.sun.com/xml/ns/portlet/portlet-app_1_0.xsd"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation=
    "http://java.sun.com/xml/ns/portlet/portlet-app_1_0.xsd"
    version="1.0">
    <portlet>
      <portlet-name>QuickSearch</portlet-name>
      <portlet-class>
        org.springframework.web.portlet.DispatcherPortlet
      </portlet-class>
      <init-param>
        <name>contextConfigLocation</name>
        <value>/WEB-INF/context/portlet/QuickSearchDefinition.xml</value>
      </init-param>
      <supports>
        <mime-type>text/html</mime-type>
        <portlet-mode>view</portlet-mode>
      </supports>
      <portlet-info>
        <title>Quick Search</title>
      </portlet-info>      
    </portlet>    
</portlet-app>

The preceding portlet.xml file specifies the contextConfigLocation as an initial parameter for the Spring class.

Listing 1 shows the sample Spring contextConfigLocation file:

The next step is to write some Java source to act as a controller, view, and handler for the portlet. The view is a JSP page, while the controller and handler are Java classes. For samples of these artifacts, please see the downloadable source, which contains a portlet skeleton project for this article.

The controller, with the handler class's help, fetches data from some data source, such as a web service, database, or feed. You can implement the mechanism to pass this data to the view via the command pattern, where commandObject is the carrier of information throughout the user portlet session.

For example, the following code is a skeleton that illustrates Portlet API methods to get data and return it to the view layer:

@Override
protected ModelAndView handleRenderRequestInternal(
   RenderRequest request, RenderResponse response) throws Exception 
{      
   logger.info ("Inside Controller handleRenderRequestInternal");      
   Map<String, CommandObject> model = new 
     HashMap<String, CommandObject>();   
   CommandObject commandObject = 
     (CommandObject)request.getPortletSession().getAttribute(
     CommandObject.COMMAND_NAME,PortletSession.APPLICATION_SCOPE);
   if (commandObject == null){
      commandObject = new CommandObject();
   }
            
   // logic to get the data and put it in the commandObject 
   // should be here...
            
   String view = getFormView();
   model.put("commandObject", commandObject);
   ModelAndView mav = new ModelAndView(view, model);
   return mav;  
}
@Override
public void onSubmitAction (final ActionRequest request, 
  final ActionResponse response, final Object command,
  final BindException bindException) throws Exception 
{
   logger.info ("Inside onSubmitAction");
   // Set the form bean into session so that it will be available 
   CommandObject commandObject = (CommandObject)command;
   logger.info("Command Object :"+ToStringBuilder.reflectionToString(
      commandObject));
   request.getPortletSession ().setAttribute ("command_obj", 
      command,PortletSession.APPLICATION_SCOPE);
}

From the JSP, you can retrieve the data as follows:

<form:form action="${formAction}" name="quickProcess" 
   method="post" commandName="commandObject">    
  <form:hidden path="p" id="p" />
  <c:if test="${commandObject.someList != null}">
    <c:forEach items="${commandObject.someList}" 
      var="listItem" varStatus="loop">              
      <c:out value="${listItem.name}"/><br>            
    </c:forEach>
  </c:if>
</form:form>

Figure 6. Adding a Portlet in Vignette:
In Vignette Portal Server, you can list portlets to add them.

Note that the portlet does not specify how it should be laid out on the screen, whether it can be resized, or what width and height it should have. The portlet container controls all these external properties.

To make the Portlet project work, you need to build and deploy it. In the build step, create a standard java war file (typically using Ant or Maven). In the deploy step place the war file on the application server that also hosts the portlet container application. When the portlet is configured and registered in the portlet container, the portlet.xml file is used to discover what portlets are available and what they are called. For example, in Vignette Portal server you can create a new portlet by searching for it and adding it to the site (see Figure 6 and Figure 7).



Figure 7. Searching for Portlets in Vignette:
You can also search for portlets you want to add to a site.


Figure 8. Setting Portlet Layout in Vignette:
Here's an administrative page that lets you configure portlet layout in Vignette.

After adding the portlets are to portlet container, you can (depending on the platform) set up their placement, layout, and properties. For instance, you can set a default width and location, and specify that the portlet cannot be minimized or moved, etc.

Figure 8 shows a Vignette example page with three configured portlets. When a user logs into the portal this is the default placement that will be used.

Figure 9 shows a few default layouts you can choose in the eXo JBoss portlet container. Of course, you are not required to use these, but it's convenient to have out-of-the-box page grid layouts that you can assign with just a few mouse clicks.



Figure 9. Default Layouts:
The eXo JBoss portlet container provides several default layouts that you can select.

The latest portlet containers make it easy to change the look and feel of a portal site by changing the layout, skins, or UI scheme of the portlets—all from a convenient administrative dashboard.

At this point, you've seen the rudiments of how web portals and portlet containers work as well as an example of developing a portlet using the latest Java specification and deployment techniques. The creation of the concrete specification facilitated proliferation of the portlet containers in the web development area, from both open source and commercial vendors. This in turn, made it easy for Java web developers to reuse portlet code, concentrate on business logic, and provide robust out or the box features for the end-users without writing much portal code. It will be interesting to see what new developments will appear in the Java portal space in coming years. To follow up, you may find these reference links useful:

References:

Listing 1. QuickSearchDefinition.xml: This is the Spring contextConfigLocation file.
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:aop="http://www.springframework.org/schema/aop"
  xsi:schemaLocation="
   http://www.springframework.org/schema/beans 
   http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
   http://www.springframework.org/schema/aop 
   http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
   
  <bean id="quickEntitySearchController" 
    class="com.portlet.controller.QuickSearchController" 
    parent="basePageController"> 
    <property name="sessionForm"><value>true</value></property> 

    <!-- Keep command object throughout session -->
    <property name="commandName" value="commandObject"/>
    <property name="commandClass" 
      value="com.portlet.command.commandObject"/>
    <property name="formView"><value>quick.search</value></property>
    <property name="successView"><value>quick.search</value></property>
    <property name="bindOnNewForm"><value>true</value></property>     
    <property name="quickServiceClient" ref="quickServiceClient"/>
  </bean>   
   
  <bean id="portletModeParameterHandlerMapping" class="
    org.springframework.web.portlet.handler.
    PortletModeParameterHandlerMapping">
    <property name="order" value="10"/>
    <property name="interceptors">
      <list>
        <ref bean="parameterMappingInterceptor" />
      </list>
    </property>

    <property name="portletModeParameterMap">
      <map>
        <entry key="view">
          <map>
            <entry key="basePageAction">
              <ref bean="quickSearchController"/>
            </entry>
          </map>
        </entry>
      </map>
    </property>
  </bean>
   
  <bean id="portletModeHandlerMapping" class=
    "org.springframework.web.portlet.handler.PortletModeHandlerMapping">
    <property name="interceptors">
      <list>
        <ref bean="parameterMappingInterceptor" />
      </list>
    </property>
    <property name="portletModeMap">
      <map>
        <entry key="view"><ref bean="quickSearchController"/></entry>
      </map>
    </property>
  </bean>
</beans>

About the Author

Vlad Kofman is currently working on enterprise-scale projects for major Wall Street firms. He has also worked on defense contracts for the U.S. government. His main interests are web-related programming methodologies, UI patterns, and SOA.

Sitemap | Contact Us

Thanks for your registration, follow us on our social networks to keep up-to-date