Readme for SPFLegacyMailReader sample

 

Introduction

The MailReader sample is an example of Jarkarta Struts which is shipped with Struts. This sample demonstrates how to write and package a Struts application, as well as many other features of Jakarta Struts. There were very few changes to the sample code and JSPs for the application to be packaged for Portal. The document will detail the required changes.

Sample details

This section will discuss the changes to the Jakarta Struts mail reader example.

Specifying the controller

 

The controller for servlet-based Jakarta Struts is the ActionServlet class. The Struts Portlet Framework provides a controller that extends a portlet, instead of a servlet. In the legacy container, this controller is specified as the servlet-class in the web deployment descriptor.

 

   <display-name>Struts Legacy MailReader</display-name>

   <servlet-class>com.ibm.wps.portlets.struts.WpsStrutsPortlet</servlet-class>

 

Specifying the Struts servlet mapping

 

Each portlet is deployed in the application server and therefore requires a servlet mapping. The Struts application itself also needs a servlet mapping so that the URLs for Struts Actions can be identified. The Struts actions are passed as a request parameter on the portlet URL, so a mapping needs to be specified to identify the Struts action. The Struts servlet mapping is specified as an init parameter.

 

      <init-param>

         <name>struts-servlet-mapping</name>

         <value>*.do</value>

      </init-param>

 

Specifying the Request Processor

 

The Struts Portlet Framework is implemented with a custom Request Processor. The WP Request Processor will split the processing between the two phases of Portal.  Typically, the Request Processor is executed in the action phase of Portal, and the page cannot be rendered. The WP Request Processor will save the information from the action phase until the render phase in the IViewCommand object. The WP Request Processor information is required in the Struts configuration file.

 

  <controller processorClass="com.ibm.wps.portlets.struts.WpsRequestProcessor">

    <!-- The "input" parameter on "action" elements is the name of a

         local or global "forward" rather than a module-relative path -->

    <set-property property="inputForward" value="true"/>

  </controller>

 

Changes to the Jakarta Struts classes

The Struts Portlet Framework requires that URLs which are created to be portlet URLs be instantiated using the PortletResponse object. The Struts Action (or forward path) is then passed to the controller as a request parameter. The URL creation is specific to the Struts Portlet Framework. The Struts Portlet Framework provides the PortletApiUtils impl classes to allow the creation of the required URLs. Several of the Jakarta Struts Mail Reader example tags require a change in how the URLs are created so that they can be executed in the Portal environment.

 

The LinkSubscriptionTag is modified to use the PortletApiUtils to create the portlet URL. Note: the PortletApiUtils.getUtilsInstance will return null when the application is running in the servlet environment. The tag can be written to support both the servlet and portlet environment.

 

      // WPS_MODIFICATION

    PortletApiUtils portletUtils = PortletApiUtils.getUtilsInstance();

    if (portletUtils != null)

    {

       Object portletURI =

          portletUtils.createPortletURIWithStrutsURL(request, url.toString() );

       // don't need to call response.encodeURL, the portletURI.toString takes care of

       // that.

       results.append(portletURI.toString() );

    }

    else

    {

      results.append(response.encodeURL(url.toString()));

    }

      // WPS_MODIFICATION

 

The change for LinkUserTag .java is the same change as the one to LinkSubscriptionTag.

 

   // WPS_MODIFICATION

   PortletApiUtils portletUtils = PortletApiUtils.getUtilsInstance();

   if (portletUtils != null) {

       Object portletURI =

          portletUtils.createPortletURIWithStrutsURL(request, url.toString() );

      

       // don't need to call response.encodeURL, the portletURI.toString takes care of

       // that.

       results.append(portletURI.toString() );

    }

    else {

      results.append(response.encodeURL(url.toString()));

    }

    // WPS_MODIFICATION end

 

The change to the CheckLogonTag.java is required to support the forward action. Portal does not allow a portlet to forward because the response object has already been committed. The change to the CheckLogonTag class allows the use of PortletApiUtils.forward, which will either include the file or directly call the RequestProcessor for a Struts Action.

 

   // WPS_MODIFICATION

   //                    pageContext.forward(config.getPrefix() + page);

   PortletApiUtils portletUtils = PortletApiUtils.getUtilsInstance();

   if (portletUtils != null) {

      HttpServletRequest request = (HttpServletRequest) pageContext.getRequest();

      portletUtils.forward( config.getPrefix() + page, request );      

   }

   else {

      pageContext.forward( config.getPrefix() + page );

   }

   // WPS_MODIFICATION end

Summary

The MailReader sample demonstrates many of the features of Struts. The Jakarta example has been modified to run in the Portal environment. This example demonstrates some of the migration steps an existing Struts application will require.