This document will explore how a Struts application can be modified to work as a JSR168 compliant portlet. It will hopefully serve as a useful reference guide for those planning to install the Struts Bridge into their existing Struts applications. As an example we'll use the iBATIS version of Petstore application, the Petstore is a commonly implemented demonstration of a fictitious e-commerce site. The iBATIS version of Petstore is built with the Struts framework and incidentally also provides an example of the iBATIS DAO framework and SQL Maps framework.
Struts Bridge: Background
The Struts Bridge is one of several software bridges from the Apache Portals Bridge project (at the time of writing the project also includes bridges for JSF, PHP, Velocity and Perl). The idea behind the Struts Bridge is that you can take an existing Struts application and make a couple of very minor modifications after which it will continue to work as a standalone Struts application but also work as a portlet.
The Portals Bridge project was initially developed within the Apache Jetspeed 2 portal platform project. Portals Bridge has now become a separate project; it was designed to run in any JSR168 compliant portal and contains nothing that should be specific to Jetspeed 2 portal.
iBATIS JPetstore is a relatively small demonstration Struts application. A portlet version of this application is distributed as an example with the Apache Jetspeed 2 portal platform. Attached to this page are two versions of the Jetspeed 2 portlet version of the JPetstore WAR file; one version is complied for use with J2SE 1.4.2 and one for J2SE 1.5. You will also find two zip files, one for each J2SE version, containing some source code and compiled versions of the libraries necessary to convert a Struts application into a portlet.
Changes that were necessary to convert the original iBATIS JPetstore into a portlet version
The iBATIS JPetstore portlet distributed with Jetspeed 2 is subtly different to the original iBATIS JPetstore example in a number of ways.
Struts upgrade, database configuration and general tidy up
The Struts Bridge code exists in two different versions, one for Struts 1.2.4 and one for Struts 1.2.7. The original JPetstore used Struts 1.1 and so it was necessary to update the Struts libraries.
In order to be easier to deploy and get the example up and running, the Jetspeed 2 JPetstore has been configured to use HSQLDB by default and includes the necessary HSQLDB library and database files.
The Struts bridge relies on the fact that all URLs used in the application are created via Struts HTML tags and this includes image file references. It also expects every page to be accessed via a Struts action. These are essentially Struts best practices but in order for this application to work as a portlet it becomes essential that these practices are followed. So in the Jetspeed2 version of JPetstore there has been a general tidy up of the JSP pages to ensure that these practices are followed.
Portlet related changes
Necessary Portlet Modifications
- Various minor changes to JSP files
Necessary Portlet Related Additions
The Jetspeed2 JPetstore includes additional configuration files and libraries that are necessary specifically to make it work as a portlet. Most importantly it include versions of portals-bridges-common and portals-bridges-struts jar files.
Modify web.xml to use PortletServletinstead of ActionServlet
The key to converting a Struts application to a portlet is that in web.xml the servlet used is modified so that instead of using org.apache.struts.action.ActionServlet it uses org.apache.portals.bridges.struts.PortletServlet. In the portlet version for the JPetstore web.xml we have:
Modify JSP pages to use a portlet aware Struts HTML taglib
JSP pages are modified to used a portlet aware version of the Struts HTML taglib. In the JSP pages references to:
are replaced with:
Modify struts-config.xml to override the default RequestProcessor
In struts-config.xml a new portlet aware controller is introduced. In WEB-INF/struts-config.xml add a <controller> element just above the <message-resources> element to override the RequestProcessor
Create a struts-portlet-config.xml file in the WEB-INF directory
A new configuration file called struts-portlet-config.xml has been added. The purpose of this file is to help the Struts portlet identify which URLs are portal actions and which are portal views, it also identifies which objects should be copied from a portal action to the subsequent portal rendering request. For JPetstore this file looks something like this:
Create a portlet.xml file in the WEB-INF directory
A portlet.xml file has been added containing something like this:
Create an instance of ServletContainerProvider for the portal platform
You'll notice that in the above portlet.xml file there is a reference to a ServletContainerProvider. To get the struts bridge working, Satish Sekharan of Memorial University of Newfoundland wrote an implementation of the interface org.apache.portals.bridges.common.ServletContextProvider. This implementation supplies access to the Servlet context of uPortal/Pluto portlet container.
Please note that there are some unresolved bugs with the current version of uPortal.
I have provided fixes for all these bugs. JPetstore and other portlets using the Apache Struts Bridge would work as expected with the next release of uPortal 2.5.2
Deploy the WAR file as a portlet
If you deploy the Jetspeed2 JPetstore WAR file using Pluto or uPortal an additional servlet entry and mapping will be automatically added to the web.xml.
Building Portal bridge components from source
Here are some brief pointers on how to obtain and build the Portal bridges source code manually. All over Apache land projects are migrating from CVS to Subversion, it seems that this is happening at much faster rate than the accompanying documentation is being produced! So for people without Subversion savvy this is how to download the Portals bridges source code. First obtain yourself a Subversion client and install it.
If you are using a command line version of subversion you will now have a executable called svn somewhere on your system. Create a new directory and checkout the Portal bridges project code using a command like:
This will checkout the "HEAD" of the project. Now you need to make use of the usual suspects for a Java project build (Ant and Maven). To make the portals-bridges-common and portals-bridges-struts jar files you just need to change into the appropriate directory, run maven and let it do it's build magic. To clean and build all projects at once, you can run maven allClean allBuild in the root directory of the project