IBM WebSphere Developer Technical Journal: Implementing page navigation in portal applications using Struts portlets

Many portal applications have a requirement for portlets to work together cooperatively to allow portal user interaction with a portlet on a page to automatically navigate to another portlet perhaps on another page of the portal. Building "portlet application" behavior from multiple individual portlets enables more complex end user behavior to be built from portlet components. This article describes how to use the multiple module support built into the Struts portlet framework to organize Web navigation schema.

Zeynep Latif (zeynep@us.ibm.com), Software Engineer, IBM

Zeynep Latif is a software engineer currently working as an Application Developer in the Software Group System House at IBM in Research Triangle Park, NC. With her teammates, she is responsible for validating selected customer-based business scenarios to improve the customer experience with Software Group products, especially the integration of those products. Previously she was a developer of the VisualAge Generator project.



14 April 2004

Introduction

Struts is a popular open source foundation designed to make complex Web applications easier to create and maintain. The Struts framework supports the Model-View-Controller (MVC) pattern and addresses many important application design and implementation considerations. To carry out page navigation in portal applications, WebSphere® Portal V5 provides tags that can be used by JavaServer Pages (JSPs) in developing both typical portlets and Struts portlets. This article focuses on the Struts framework's capability to create multiple modules, and how to implement page navigation methodology from JSPs in a sample Struts portlet application.

Our focus will be on two complementary methodologies:

  • How to implement page navigation from a JSP using one of the JSP tags available in WebSphere Portal
    We will look at a sample application, including screen shots of the development environment and portal resources, as well as code samples for the page navigation methodology.
  • How to use the multiple module support built into the Struts portlet framework to organize Web navigation schema
    We will look at code samples that illustrate how to perform multiple Struts module switching in a portal environment using the page navigation feature.

This article assumes you have a basic understanding of Struts applications, including how to build a Struts application in WebSphere Studio Application Developer, how to deploy Struts as a portlet, and an understanding of portal resources within WebSphere Portal. (See Resources for more information in these areas.)

The following products are used in the development and deployment of our sample application:

  • WebSphere Portal V5.x
  • WebSphere Application Server v5.x
  • WebSphere Studio Application Developer v5.0.1 (hereafter called Application Developer) with Struts Version 1.1 support.

The development tasks explained in this article for implementing page navigation can be used for both standard portlets and Struts portlets.


Application overview

In our sample application, we will be working with three portlets located on three different pages. When a user selects a link in one of the portlets, the user will be directed to another page where another portlet resides. The example we develop and refer to throughout this article will take advantage of multiple Struts modules to incorporate WebSphere Portal page navigation tags into each module's own JSP files in the portal environment. Figure 1 shows a high level illustration of how the sample application will work; our sample application will be deliberately simple to maintain focus on understanding these methodologies. Application details will be provided later.

Figure 1. High level view of our sample application
Figure 1. High level view of our sample application

Building the navigation structure

WebSphere Portal provides its own JSP tags for use by portlet JSPs. One of these tags, <wps:URLGeneration attribute="value"/>, is used to create links to pages from anywhere in the portal. We use one of the attributes of this tag, contentNode="id|name", to create URLs to different pages for building the navigation structure. This attribute takes a unique identifier (name of the content node) to specify the page where the portlet can be found. (See Resources for more information about this tag.)

In WebSphere Portal, select Administration => Portal Settings => Custom Unique Names. We use the Custom Unique Names administrative portlet to obtain unique identifiers for our portal resources to be specified for the contentNode attribute. Administrators can use the Custom Unique Names portlet to view unique identifiers and assign custom (human readable) names to portal resources. Figure 2 shows unique identifiers and custom names for these configured sample pages:

  • Struts_Test
  • Struts_Receiver
  • Struts_Receiver_2
Figure 2. Custom Unique Names portlet
Figure 2. Custom Unique Names portlet

In this example, WebSphere Portal assigned these pages with the unique identifiers 6_0_LT, 6_0_P1 and 6_0_IP, respectively. (Your values will differ.) We also configured custom names for these sample pages to make them easier to read and work with, and used these custom names (rather than the unique identifiers) in our JSP files.

Inside the body of the <wps:URLGeneration attribute="value"/> portlet JSP tag, the <% wpsURL %> scripting variable can be used to write the URL directly to the output stream. In the example, we will use the following JSP code to create a link to our Struts Receiver pages from one of our JSPs:

<wps:urlGeneration contentNode="Struts_Receiver_Page">
         <A HREF="<%wpsURL.write(out);%>"style="text-decoration:none" >
         Any text</a>
</wps:urlGeneration>

The <wps:URLGeneration attribute="value"/> portlet JSP tag belongs to the engine.tld tag library, which is used by the portal server engine. To make this portal JSP tag available for our JSP we added the tag library directive, taglib, at the very beginning of our JSP page. As shown in the following code, all the engine.tld tags in our sample are now accessible through prefix wps:

<%@ taglib uri="/WEB-INF/tld/engine.tld" prefix="wps" %>

Sample page and portlet configuration

The page navigation piece of the sample application includes three portlets (the long names are provided to help emphasize the page navigation flow):

  • Overview Struts Portlet:
    Displays two links to direct the user request to pages containing either phone numbers or address information, and resides on the Struts_Test page (custom name: Struts_Test_Page), as shown in Figure 3:
    Figure 3. Overview Struts Portlet on Struts_Test page
    Figure 3. Overview Struts Portlet on Struts_Test page
  • Receive Phone Numbers Request Struts Portlet:
    Displays phone numbers of users, and resides on the Struts_Receiver_2 page (custom name: Struts_Receiver_2_Page), as shown in Figure 4:
    Figure 4. Receive Phone Numbers Request Struts Portlet on Struts_Receiver_2 page
    Figure 4. Receive Phone Numbers Request Struts Portlet on Struts_Receiver_2 page
  • Receive Address Request Struts Portlet:
    Displays user address information, and resides on the Struts_Receiver page (custom name: Struts_Receiver_Page), as shown in Figure 5:
    Figure 5. Receive Address Request Struts Portlet on Struts_Receiver page
    Figure 5. Receive Address Request Struts Portlet on Struts_Receiver page

Remember, all the tasks described so far can be used for both regular portlet or Struts portlet development. Next, we will implement page navigation using portal JSP tags in multiple Struts modules.


Using multiple module support in Struts

Struts Version 1.1 allows us to split a single Struts application into multiple modules, each with its own actions, JSP pages, and Struts configuration files (Figure 6). Implementing multiple Struts modules in a Struts application requires several steps:

  • Create separate Struts configuration files along with Struts actions and JSPs for each application module.
  • Configure the Web Deployment Descriptor (web.xml).
  • Switch from one module to another.

You will need to perform additional steps to run your Struts application in a portal environment, although the Struts application is easily adaptable. (See Resources).

Figure 6. Multiple module support in a Struts application
Multiple module support in a Struts application

Create separate Struts modules and files

For our sample application, we created four Struts modules along with their own Struts configuration files, actions, and JSPs. The Struts modules are:

  • address
  • phone-numbers
  • overview
  • default.

We also configured web.xml and portlet.xml files and performed the switching from one module to another using the default module.

Next, we will explain the modifications required to our files based on the needs of our implementation.

Develop page navigation within our Struts modules

We implemented page navigation in three of our modules:

  • overview
  • address
  • phone-numbers.

Except for slight differences, our development tasks for page navigation are nearly identical in each of these modules. Therefore, we will explain the tasks to accomplish page navigation for the overview module, then describe the differences with the others. We will also explain the development specifics of Struts module switching for the default module. In our implementation, the default module is used to forward control to the next appropriate module; page navigation is not required. However, since it performs module switching by launching other modules and is an integral part of the navigation structure, we include it here as well.

In Application Developer, we created a Web project with Struts Version 1.1 support, then created files for our development tasks, as shown in Table 1 below.

Table 1. List of developed artifacts
Table 1. List of developed artifacts

Below are brief descriptions of the artifacts shown in Table 1:

  1. JSP files:
    We developed five JSP files:
    • index.jsp and failure.jsp files for the default module.
    • address.jsp for the address module
    • phone-numbers.jsp for the phone-numbers module
    • overview.jsp for the overview module.
  2. Actions:
    We created four Struts actions in the com.test.strutstest.actions package. Their classes are:
    • DisplayAction
    • DisplayAddressInfoAction
    • DisplayPhoneInfoAction
    • OverviewAction.
  3. Form beans:
    We created two form beans in the com.test.strutstest.forms package. Their classes are:
    • UserFormBean
    • OverviewFormBean.
  4. Backend bean and Model class:
    We used a backend bean class, UserBean, and a model class, UserBeanHelper, in the com.test.strutstest.beans package. (The backend bean contains stub data, and does not communicate to an actual backend.)
  5. Struts configuration files:
    We developed four struts-config.xml files, one for each module:
    • WEB-INF/struts-config.xml for the default module
    • WEB-INF/address/struts-config.xml for the address module
    • WEB-INF/phone-numbers/struts-config.xml for the phone-numbers module
    • WEB-INF/overview/struts-config.xml for the overview module.
  6. Other configuration files:
    Modifications are required to web.xml and portlet.xml files when deploying a Struts application as a portlet.

Each of the above configuration files includes the following Request Processor:

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

Figure 7 shows the location of the developed artifacts within the Application Developer development environment:

Figure 7. Location of developed artifacts in Application Developer
Figure 7. Location of developed artifacts in WebSphere Studio Application Server

Configure the default module

To launch the default module and see how it performs switching between our Struts modules:

  1. The default module is launched when WebSphere Portal invokes the index.jsp file, specified in the web.xml file within the <welcome-file-list> tag:
    <welcome-file-list>
         <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>
  2. When index.jsp is invoked, the logical forward name, Display, is specified in the logic Struts tag:
    <logic:forward name="Display"/>
  3. The default module's struts-config.xml file, the logical forward name, which is Display, is defined as a global forward:
    <global-forwards>
         <forward name="Display"    path="/display.do"/>
    </global-forwards>
  4. Within the <global-forwards> section, the logical global forward context relative path, path="/ display.do", matches the context relative path, path="/display", of the action element in the <action-mappings> section. This matching path allows the action, DisplayAction, to be launched. The action mappings section, including the <action> element with path and type attributes, is shown below:
    <action-mappings>
        <action path="/display" 
        
               type="com.test.strutstest.actions.DisplayAction">
                   .................................................
        </action> 
    </action-mappings>

To enable module switching, configure the default module's struts-config.xml, portlet.xml and struts-config.xml files for the remaining modules:

  1. Configure struts-config.xml for the default module. We used DisplayAction as our action class, and four local logical forwards:
    <action-mappings>
         <action path="/display" 
              type="com.test.strutstest.actions.DisplayAction">
                   <forward name="failure" 
                        contextRelative="true" 
                        path="/failure.jsp"/>
                   <forward name="address" 
                        contextRelative="true"
                        path="/address/start.do"/>
                   <forward name="phone-numbers" 
                        contextRelative="true" 
                        path="/phone-numbers/start.do"/>
                   <forward name="overview" 
                        contextRelative="true"
                        path="/overview/start.do"/>
         </action>
    </action-mappings>
  2. Configure the portlet.xml file to comply with the configuration in the default module's struts-config.xml file. Specifically, each of the four logical forward names in the default module's struts-config.xml file needs to match the values of the view.forward configuration parameter settings in the portlet.xml file. (The view.forward parameter will be used in our module switching code to define the action mapping for the specific portlet instance.) The mapping to view.forward is shown in Table 2:
    Table 2. view.forward configuration values vs. forward name configuration values
    Table 2. view.forward configuration values vs. forward name configuration values
  3. Configure the web.xml file to define the different modules. We used the config initialization parameter to tell the action servlet about our default module; however, for each additional module, we list an initialization parameter named config/module, where module is our module name. For example:
    • To define the default module:
      <init-param>
           <param-name>config</param-name>
           <param-value>WEB-INF/struts-config.xml</param-value>
      </init-param>
    • To define the other modules:
      <init-param>
           <param-name>config/address</param-name>
           <param-value>WEB-INF/address/struts-config.xml
           </param-value>
      </init-param>
      <init-param>
           <param-name>config/phone-numbers</param-name>
           <param-value>WEB-INF/phone-numbers/struts-config.xml
           </param-value>
      </init-param>
      <init-param>
           <param-name>config/overview</param-name>
           <param-value>WEB-INF/overview/struts-config.xml
            </param-value>
      </init-param>

    (See Resources for other module configurations and required web.xml configuration settings.)

  4. Perfom the standard updates to the web.xml and portlet.xml files to deploy the Struts application as a portlet . (See Resources and the sample web.xml and portlet.xml files in the Download section for more information.)

Module switching will take place in the DisplayAction class, as configured in the <action-mapping> section of the default module's struts-config.xml file. To determine which module will be invoked by WebSphere Portal:

  1. When the execute() method of the DisplayAction class is invoked, the view.forward parameter set in the portlet.xml file is accessed:
    PortletSettings portletSettings = request.getPortletSettings();
    String viewForward = portletSettings.getAttribute("view.forward");
  2. For our portlets, the view.forward parameter will have the following values:
    Table 3. Values of view.forward configuration parameter for sample portlets
    Table 3. Values of view.forward configuration parameter for sample portlets
    • If viewForward is null, this variable is set to failure in the execute() method.
    • A forward mapping for the configured viewForward value is retrieved from the struts-config.xml file:
      ActionForward forward = new ActionForward();
      try
      {
           forward = mapping.findForward(forwardName);
      }
      catch (Exception e)
      {
            ...........................................
      }
    • The last step in the execute() method returns the instance of ActionForward, forward:
      return (forward);

Configure the other struts-config.xml files. Based on the result of module determination within the DisplayAction class, if the view.forward parameter value is:

  1. address:

    The matching start path in the <action-mappings> section of the default module's struts-config.xml file will let DisplayAddressInfoAction be invoked in the address module. This process requires using the address/struts-config.xml file, as configured in web.xml . The address/struts-config.xml file includes the following settings:

    <!-- ===== Global Forward Definitions ===== -->
    <global-forwards>
         <forward name="start" path="/start.do"/>        
    </global-forwards>
    <!-- ===== Action Mapping Definitions ===== -->
    <action-mappings>
         <action  path="/start"
                   type="com.test.strutstest.actions.DisplayAddressInfoAction"
                   name="userFormBean"
                   scope="request">
              <forward name="success" path="/address.jsp"/>
         </action
    </action-mappings>
  2. phone-numbers:

    The matching start path in the <action-mappings> section of the default module's struts-config.xml file will let DisplayPhoneInfoAction be invoked in the phone-numbers module. This process requires using the phone-numbers/struts-config.xml file, as configured in web.xml file. The phone-numbers/struts-config.xml file includes the following settings:

    <!-- ===== Global Forward Definitions ===== -->
    <global-forwards>
         <forward name="start" path="/start.do"/> 
    </global-forwards>
    <!-- ===== Action Mapping Definitions ===== -->
    <action-mappings>
         <action  path="/start"
              type="com.test.strutstest.actions.DisplayPhoneInfoAction"
             name="userFormBean"
             scope="request">
             <forward name="success" path="/phone-numbers.jsp"/>
         </action
    </action-mappings>
  3. overview:

    The matching start path in the <action-mappings> section of the default module's struts-config.xml file will let OverviewAction be invoked in the overview module. This process requires using the overview/struts-config.xml file, as configured in web.xml file. The overview/struts-config.xml file includes the following settings:

    <!-- ===== Global Forward Definitions ===== -->
    <global-forwards>
         <forward name="start" path="/start.do"/>        
    </global-forwards>
    <!-- ===== Action Mapping Definitions ===== -->
    <action-mappings>
         <action  path="/start"
              type="com.test.strutstest.actions.OverviewAction"
              name="overviewFormBean"
              scope="request">
              <forward name="success" path="/Overview.jsp"/>
         </action>
    </action-mappings>
  4. failure:

    failure.jsp will be launched, as configured in the default module's struts-config.xml file.

We have, so far, created the files listed in Table 1 and modified most of them as required by our example. Now we are ready to start writing the code to implement page navigation using the overview module. The next section guides you through the steps.

Develop the overview module

To create the Overview.jsp file, the OverviewAction class, the OverviewFormBean class and the overview/struts-config.xml file to develop the Overview Struts portlet, follow these development tasks in the action class and JSP file(s):

  1. Once the control comes to the Overview module from the default module, the execute() method of the OverviewAction class performs these tasks:
    • Access the OverviewFormBean form bean and set these attributes:
      try
      {
      String forwardName = null;
      if (form == null)
      {
           form = (ActionForm) request.getAttribute("overviewFormBean");
      }
      //Set-up form bean fields
      OverviewFormBean formBean = (OverviewFormBean) form;
      formBean.setPhoneNumbersLinkName("List Phone Numbers");
      formBean.setAddressLinkName("Address Information");
      ...................................................
    • Store the form bean in the correct scope:
      try
      {
           //Store the bean in the correct scope
           if ("request".equals(mapping.getScope()))
                   request.setAttribute(mapping.getName(), formBean);
           else
                   session.setAttribute(mapping.getName(), formBean);
      }
      catch (Exception e)
      {
                   ..................................
      }
    • Find a mapping from overview/struts-config.xml and return an ActionForward type of object:
      String forwardName = null;
      ActionForward forward = new ActionForward();
      .......................................
      //If no errors occur then look for "success"
      try
      {
           forward = mapping.findForward(forwardName);
           if (forward != null)
           {
           .....................................
           }
      else
           .....................................
      }
      catch(Exception e)
      {
           ...................................
      }
      return (forward);
    • If there are no errors in the action class processing, then the forward name success will allow Overview.jsp to be launched according to our configuration in the overview/struts-config.xml file.
  2. Overview.jsp displays two links to other developed portlets, Receive Phone Numbers Request Struts Portlet and Receive Address Request Struts Portlet. We use the page navigation methodology and Struts tags to implement this characteristic:
    • Use the taglib directive at the very beginning of the JSP page to make all of the engine.tld tags available to the rest of the JSP with the prefix.wps:
      <%@ taglib uri="/WEB-INF/tld/engine.tld" prefix="wps" %>
    • Use the contentNode parameter in the <wps:urlGeneration> portlet tag to specify the unique identifiers or custom names of pages where the other portlets reside. To launch the page navigation to Receive Address Request Struts Portlet, which resides in the Struts_Receiver page, we use the custom name, Struts_Receiver_Page:
      <wps:urlGeneration contentNode="Struts_Receiver_Page">
           <A HREF="<%wpsURL.write(out);%>"style="text-decoration:none" >
           <bean:write name="overviewFormBean" property="addressLinkName" /></a>
      </wps:urlGeneration>
    • To launch the page navigation to Receive Phone Numbers Request Struts Portlet, which resides in the Struts_Receiver_2 page, we use the custom name, Struts_Receiver_2_Page:
      <wps:urlGeneration contentNode="Struts_Receiver_2_Page">
           <A HREF="<%wpsURL.write(out);%>"style="text-decoration:none" >
           <bean:write name="overviewFormBean" 
           property="phoneNumbersLinkName" /></a>
      </wps:urlGeneration>
    • We obtained the custom names for our pages from the My Pages and unique names list, shown in Figure 2.
  3. In the overview module, we used <bean:write>, <html:html> and <html:form> Struts tags. Implementing these tags requires the following steps:
    • Declare the html and bean prefixes:
      <%@ taglib uri="/WEB-INF/tld/struts-html.tld" prefix="html" %>
      <%@ taglib uri="/WEB-INF/tld/struts-bean.tld" prefix="bean" %>
    • <html:html> Struts tag: Renders an HTML element with appropriate language attributes if there is a current locale available in the user's session.
    • <html:form> Struts tag: Used for all HTML form processing in Struts. A form element must always contain an action attribute. The action attribute must correspond to a valid action in struts-config.xml. In the Overview.jsp file, we used the form element and its action attribute:
      <html:form action="/start">

      The start attribute maps the following action in the overview/struts-config.xmlfile:

      <action-mappings>
           <action  path="/start"
                type="com.test.strutstest.actions.OverviewAction"
                name="overviewFormBean"
                scope="request">
           <forward name="success" path="/Overview.jsp"/>
           </action>
      </action-mappings>

      This Struts tag ties the form fields to properties in Struts form beans. The form bean is located (or created, if necessary) based on the form bean specification for the associated ActionMapping. Our form bean defined in overview/struts-config.xml file is UserFormBean:

      <form-beans>
           <form-bean  name="overviewFormBean" 
      		type="com.test.strutstest.forms.OverviewFormBean"/>
           </form-beans>
    • Use of the <bean:write> Struts tag:

      This general purpose tag is used to output property values from a bean. Within the Overview.jsp file it displays <bean:write> to display text data set in the UserFormBean form bean. We use this tag to display some of the properties of UserFormBean, as shown below:

      <bean:write name="overviewFormBean" property="addressLinkName" />
      <bean:write name="overviewFormBean" property="phoneNumbersLinkName" />

Developing the remaining modules

Developing the address and phone-numbers modules is very similar to the overview module, with the following exceptions:

  • The address module implements the Receive Address Request Struts Portlet using:
    • address.jsp
    • DisplayAddressInfoAction class
    • UserFormBean form bean class
    • UserBean backend bean class
    • UserBeanHelper model class
    • address/struts-config.xml file.
  • The phone-numbers module implements the Receive Phone Numbers Request Struts Portlet using:
    • phone-numbers.jsp
    • DisplayPhoneInfoAction class
    • UserFormBean form bean class
    • UserBean backend bean class
    • UserBeanHelper model class
    • phone-numbers/struts-config.xml.

We use the backend UserBean bean class and the UserBeanHelper model class for the address and phone-numbers modules, both of which need to mimic the user information using stub data set in the backend bean using our module class. Both of the modules use the same form bean.

To develop the address module within the DisplayAddressInfoAction class:

Once the control comes to the address module from the default module, the execute() method of the DisplayAddressInfoAction class performs the following tasks:

  1. Access the form bean, UserFormBean, and set the following attributes:
    try
    {
         String forwardName = null;
    if (form == null)
    {
              form = (ActionForm) request.getAttribute("userFormBean");
    }
         //Set-up form bean fields
         UserFormBean formBean = (UserFormBean) form;
         setFormBean(formBean);
         ...................................................
  2. Store the form bean in the correct scope:
    try
    {
         ........................................
         //Store the bean in the correct scope
         if ("request".equals(mapping.getScope()))
              request.setAttribute(mapping.getName(), formBean);
         else
              session.setAttribute(mapping.getName(), formBean);
    }
    catch (Exception e)
    {
         ..................................
    }
  3. Find a mapping from address/struts-config.xml and return an ActionForward type of object:
    String forwardName = null;
    ActionForward forward = new ActionForward();
    .......................................
    //If no errors occur then look for "success"
    try
    {
         forward = mapping.findForward(forwardName);
         if (forward != null)
              {
              .....................................
              }
         else
              .....................................
    }
    catch(Exception e)
    {
              ...................................
    }
    return (forward);
  4. Call setFormBean(UserFormBean formBean). This method gets the single instance of the model:
    UserBeanHelper userBeanHelper = UserBeanHelper.getInstance();

    This instance populates the backend data, sets an instance object of UserFormBean, and returns this object using this method call:

    UserFormBean userFormBean = userBeanHelper.getUserFormBean();

    This method sets the attributes of the formBean with the appropriate getter and setter methods, as shown below using the object instance returned from the model:

    public void setFormBean(UserFormBean formBean)
    {
         UserBeanHelper userBeanHelper = UserBeanHelper.getInstance();
         UserFormBean userFormBean = userBeanHelper.getUserFormBean();
    
         //These two parameters are just text values to be displayed on the browser
         formBean.setAddress("Address");
         formBean.setUserName("UserName");
    
         //Setting the formBean object attributes with data obtained from the backend
         formBean.setAddressValues(userFormBean.getAddressValues());
         formBean.setUserNameValues(userFormBean.getUserNameValues());
    }

If there are no errors in action class processing, then the forward name success will launch the address.jsp file to be launched according to our configuration in the address/struts-config.xml file for the address module.

The steps above are repeated for the phone-number module with appropriate changes.


Page navigation

Both the address.jsp and phone-numbers.jsp files for Receive Address Request Struts Portlet and Receive Phone Numbers Request Struts Portlet perform page navigation by using the Overview Struts Portlet and Struts tags:

  1. Use the taglib tag library directive at the very beginning of the JSP page to make all of the engine.tld tags available to the rest of the JSP with the prefix.wps.
    <%@ taglib uri="/WEB-INF/tld/engine.tld" prefix="wps" %>
  2. Invoke page navigation to the Overview Struts Portlet using the contentNode parameter in the <wps:urlGeneration> portlet tag. This requires specifying a custom name or a unique identifier of the page Struts_Test where Overview Struts Portlet resides. We use the custom name Struts_Test_Page, which was obtained from the My Pages and unique names list, shown in Figure 2.
    <wps:urlGeneration contentNode="Struts_Test_Page">
         <A href="<%wpsURL.write(out);%>" style="text-decoration: none">
         <B>Go to Overview Struts Portlet</B></A>
    </wps:urlGeneration></TD>
  3. In our implementation, we used the <logic:iterate> Struts tag on both address.jsp and phone-numbers.jsp. This tag iterates the elements of a collection, which can be either an attribute or the property of an attribute:
    • Declare the logic prefix:
      <%@ taglib uri="/WEB-INF/tld/struts-logic.tld" prefix="logic" %>
    • Use <logic:iterate> Struts tag; we use the userNameValues String array in UserFormBean action form. The following code displays user names set in the action form:
      <logic:iterate id="test" name="userFormBean"
           property="userNameValues" indexId="index">

Setting up the development environment and sample code installation

To create your development environment with Application Developer, use the formation provided in Developing a Struts Application for WebSphere Portal 4.2 and Writing a Simple Struts Application using WebSphere Studio V5. You will need to import the StrutsTest.war file from the Download section into Application Developer and use all of its JAR files. Installing the sample code on WebSphere Portal does not require any special setup; you can either use the included WAR file or a new WAR file, whichever you prefer.


Conclusion

This article described the page navigation feature provided by WebSphere Portal through the use of one of its portlet tags in combination with the multiple module support provided by the Struts Portal Framework. In our sample implementation, we built and configured an application using multiple module Struts support. To perform page navigation, we created portal pages where we locate our applications, then incorporated the portlet JSP tags into the appropriate JSPs . We used custom names for our pages rather than the unique identifiers assigned by the portal server in our JSPs, making our JSP deployment independent.

Although our example was not a complex application, the framework that Struts provides can elegantly handle large and complex application flows. The multiple module support, which provides an individual set of files for each module supporting parallel development and better file organization, worked in harmony with the page navigation methodology provided by WebSphere Portal JSP tags.


Acknowledgments

The author wishes to thank Tim Hanis and Jim Bonanno for their comments and contributions as technical reviewers.


Download

DescriptionNameSize
Code sampleStrutsTest.zip  ( HTTP | FTP )1.5 MB

Resources

Comments

developerWorks: Sign in

Required fields are indicated with an asterisk (*).


Need an IBM ID?
Forgot your IBM ID?


Forgot your password?
Change your password

By clicking Submit, you agree to the developerWorks terms of use.

 


The first time you sign into developerWorks, a profile is created for you. Information in your profile (your name, country/region, and company name) is displayed to the public and will accompany any content you post, unless you opt to hide your company name. You may update your IBM account at any time.

All information submitted is secure.

Choose your display name



The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerWorks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

Required fields are indicated with an asterisk (*).

(Must be between 3 – 31 characters.)

By clicking Submit, you agree to the developerWorks terms of use.

 


All information submitted is secure.

Dig deeper into WebSphere on developerWorks


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=WebSphere
ArticleID=14600
ArticleTitle=IBM WebSphere Developer Technical Journal: Implementing page navigation in portal applications using Struts portlets
publish-date=04142004