by Samuel S. Sharaf

Migrate your BEA Webflow applications to Struts

news
Mar 15, 200712 mins

Leverage the flexibility of Struts

BEA introduced the Webflow/Pipeline framework for developing Web applications as an alternative to Struts. Like Struts, the Webflow framework is based on the Model-View-Controller pattern and provides benefits similar to any other MVC-based framework. However, because Webflow uses BEA and WebLogic proprietary libraries, applications written using Webflow can run only on the WebLogic application server and provides limited flexibility for incorporating new features. Many IT organizations are realizing these drawbacks and are eager to migrate to open source frameworks such as Struts so they can leverage the flexibility and maintainability that comes with them.

This article — written for developers and architects who are planning or are migrating their Web applications — explains how to move applications developed with Webflow to Struts using Rational Application Developer (referred to as RAD in this article). Readers should have a good understanding of Java programming, and basic familiarity with the Struts framework and of the RAD test environment.

In this article, you will become familiar with the anatomy of a simple Web application written using the WebLogic framework, and you will see, step by step, how to effectively migrate different components to Struts.

Anatomy of a Webflow application

As described in “Go with the Flow” by Brian Pontarelli and Grant Zemont (JavaWorld, February 2003), a Webflow is composed entirely of nodes, abstract components that represent an object in a Web application. Nodes are interconnected by transitions or events: Origin JSP (JavaServer Pages) > Input Processor > Destination JSP. Each > symbol is an event processed by the Webflow system. Therefore, a Webflow is a string of connected nodes that outlines a logical flow of a part of a Web application.

A typical Web application written using the BEA Webflow/Pipeline architecture has the following components:

  1. BEA-provided tag libraries for view
  2. Pipeline components and Pipeline session
  3. Input processor
  4. Webflow API and properties file

At the heart of a Webflow application is a properties file called webflow.properties, which controls Web page display and initiates execution of the business logic associated with these pages. The Webflow properties file contains one section for each JSP page.

Generically, each transition in the webflow.properties file can be written as: <origin>.[<event>][(<eventName>)]=<target>

The table below describes the valid values for the different webflow.properties elements.

ElementValid values
Begin | . | |
Event = link() | button() | success | exception()
. | |
jsp | html | htm | inputprocessor | pipeline

For example, a typical entry in the webflow.properties file may look like login.jsp.button(createUser)=mypage.jsp. Here, the current state is login.jsp. The event is a button named createUser, and the result state is nextpage.jsp. Note that this does not include the input processor or Pipeline components. In the login JSP page, the form tag uses the WebFlowJSPHelper API to create the URL for the next page. Specifically, the URL contains the page name and the event that matches the current state in the webflow.properties file:

 FORM method="post" action="<%=WebflowJSPHelper.createWebflowURL(pageContext, 
 "login.jsp", button(createUser)", false)%>">

You would include the WebFlowJSPHelper class at the beginning of the JSP page as shown here: <%@ page import="com.beasys.commerce.webflow.WebflowJSPHelper" %>

The above example shows a simple scenario where the navigation occurred between one JSP page and another by clicking on a button (createUser). However, states in the webflow.properties file are not restricted to other Web pages. Normally, you would incorporate input processors (Webflow action classes) to direct flow to some class for business logic or validation.

Migrating a simple Webflow application to Struts

In this article, I use a simple application called ComputeDay to explain how to migrate a Webflow application to Struts (code snippets can be downloaded from Resources). The ComputeDay application consists of a simple Web page that accepts a year, month, and date as input and code that manipulates the data to compute the day of the week. If the input is valid, the computed value displays on an output Web page; if the input is not valid, an error message displays on the input page.

The webflow.properties file for such a simple application looks like this one:

 # Invoke the input processor
index.jsp.button(submit)= ComputeDay.inputprocessor

# Specify the fully qualified class name for the input processor
ComputeDay.inputprocessor=com.beasys.commerce.ebusiness.
customer.webflow.ComputeDay

# Specify the result state for successful execution
ComputeDay.inputprocessor.success = Output.jsp

# Specify the result state for unsuccessful execution
ComputeDay.inputprocessor.exception(ProcessingException)=
index.jsp

Note the chaining of the events from the index JSP page to the action handler, and from the action handler to either the output JSP or back to the index JSP, depending on whether the execution in the action handler was successful.

Migrating Webflow components to Struts

This section describes, step by step, using RAD, how to migrate the individual components of a simple Webflow application (ComputeDay) to their corresponding Struts components. To help ease migration, I have provided migration steps according to an application’s view, model and controller.

Step 1: Create an empty Struts project

Using Rational Application Developer, create an empty Struts project:

  1. From the menu bar, click File, then New, then Dynamic Web Project
  2. On the Dynamic Web Project page, type this text as the name of the project: ComputeDay
  3. Click Next
  4. On the Features page, make sure the Struts check box is selected
  5. Click Finish
  6. The resulting Struts project in RAD should look similar to Figure 1

Step 2: Identify the components of the application

Identifying application components is a simple, important migration step. Here, you must identify the packaging of your particular Webflow application. A typical Webflow application is packaged as follows:

  • Java code: containing the model and controller components
  • Web content: containing the JSP page, HTML, Cascading Style Sheets, tag libraries, WebLogic/Web XML files and images, etc.
  • Properties: containing webflow.properties and application-specific property files
  • JARs: Java archivies; these may be WebLogic-specific and application-related library files

Note that the above packaging structure is given as a guideline only. Generally, the packaging varies slightly for different organizations. You should properly analyze the migrated application to identify the above-mentioned components.

Step 3: Import the application components

Next, we import the Webflow artifacts identified in Step 2 to the Struts project structure we created in Step 1. RAD offers drag-and-drop functionality, so you can simply drag the appropriate components — e.g., Java code packages, JSP pages, HTML, images, etc. — and drop them in the corresponding project structure created in Step 1.

By default, the RAD auto-compile option is turned on, so it will try to compile and list any errors related to missing resources or unknown libraries. In my experience, it is best to start with missing resources and ensure that all the required application artifacts have successfully been imported in RAD.

Note that you do not need to import any WebLogic-specific library or XML files.

Step 4: Create the Web diagram

Creating the Web diagram is the most important step of the migration process. When you create a Struts-enabled dynamic Web project, a Web diagram is automatically created but not opened. This diagram forms the foundation of our Struts project; the first step is to analyze the webflow.properties file and understand the transitions from one node to the other node. Note that “node” in this context can be a JSP page or an InputProcessor class.

Analysis of the webflow.properties file reveals that the first node is the index.jsp page and the next node is either the computeDay action or index.jsp, depending on whether the validation was successful. From the computeDay node, the next node is output.jsp. This simple flow is captured in the Web diagram shown in Figure 2:

Figure 2. The sequence of the webflow.properties file: computeDay captures the computeDayIP, and dateData corresponds to PipelineSession. Click on thumbnail to view full-sized image.

I do not discuss how to draw a Web diagram here, as that discussion reaches beyond this article’s scope. Please refer to the tutorials specified in Resources.

The advantages of using a Web diagram are twofold. First, it provides you the graphical capability to capture the Webflow sequence of actions. Second, it generates all the artifacts you specify in the Web diagram in your project, including the JSP pages and the Java code files. During the migration process, you can use these generated files as templates. For example, you can copy appropriate contents of index.jsp from the Webflow application to the one generated by the Web diagram.

With the basic project structure in place, now we can discuss how to migrate the project’s model, view, and controller in the following steps.

Step 5: Migrating the view

Migrating a Webflow application’s view is quite straightforward. First, migrate BEA-specific tags and replace them with standard Struts library tags.

Listing 1. Migrating JSP tags

Webflow: <%@ taglib uri = "WebFlow.tld" prefix="wf" %>

Struts: <%@ taglib uri="/WEB-INF/struts.tld" prefix="struts" %>

Second, replace (if corresponding Struts class is available) or remove any BEA-specific import statements at the beginning of the JSP pages.

Listing 2. Migrating JSP include statements

Webflow: <%@ page import="com.beasys.commerce.webflow.WebflowJSPHelper" %>.

With Struts, no import statement is needed. The Struts form tag with action classes will replace the above import statement.

Third, replace the form tag in the Webflow JSP file with Struts’ standard form tag format. In the index JSP page, the form tag uses the WebFlowJSPHelper API to create the URL for the next page. Specifically, the URL contains the page name and the event that matches the current state in the webflow.properties file. This can be migrated to Struts as shown below:

Listing 3. Migrating JSP form tag

Webflow:

 FORM method="post" action="<%=WebflowJSPHelper.createWebflowURL
 (pageContext, "index.jsp", button(submit)", false)%>">

Struts:

 <html:form method="post" action="/computeDay"  >

The element in struts-config.xml must have this element as shown below:

 <action-mapping>
    <action path="/computeDay"
    <type="com.ibm.migration.struts.ComputeDay"
    name="dateData"
    scope="request"
    input="/index.jsp"
    <forward name="success" path="/output.jsp"/>
</action-mapping>

Next, input validation in the JSP pages and corresponding Java classes to standard Struts input validation and error handling. The Webflow framework uses the ValidatedForm API along with the Webflow tag library to validate user input. Struts provides a standard input validation and error-handling mechanism through the use of ActionErrors and the validate() method in the form bean. Consider this example:

Listing 4. Migrating JSP validation

WebFlow JSP code:

 <%@ taglib uri = "WebFlow.tld" prefix="wf" %>

The validated form within the JSP looks like:

 <wf:validatedForm event="submit" namespace="Example">
    Year <wf:text name="year"/><br>
    Month <wf:text name="month"/><br>
    Day<wf:text name="day"/>< br>
    <input type="submit" value="Submit" name="submit"/>
<wf:validatedForm>

Corresponding Java code:

ComputeRequest compRequest = new ComputeRequest();
Request.setAttribute("computeRequest", compRequest);
ValidatedForm vFrom = ValidatedFormFActory.getValidatedForm();
ValidatedValues vValus = ValidatedValuesFactory.getValidatedValues(request);
vForm.validate(vValues, compRequest);
vForm.validate(vValues, STRING_VALIDATOR, "year", newMaxExpression(4), 
"The Year must be four digit"

if(vValues.getInvalidFieldCount() > 0) {
    throw new InvalidFormDataException("Please correct the invalid fields");
}

Struts:

 public ActionErrors validate(ActionMapping mapping, HttpServletRequest request) {
    
    ActionErrors errors = new ActionErrors();
    
    If (!year.length() = 3) {
        errors.add ("year", new ActionError("year-format");
}

}

Struts provides the ApplicationResources.properties file under the JavaSource folder. This file is edited to provide the following error message:

Listing 5. Struts ApplicationResources.properties

 year-length=<li>Year is at least four digits e.g., 2006. Please enter it correctly</li>

Note how Struts uses the form bean and the externalized properties file to handle input validation and error handling, as compared to Webflow application error handling, which is tied in the application code.

Step 6: Migrating the controller

As discussed in the section describing a simple Webflow application, the input processors, or IPs, form a typical Webflow application’s controller. Struts provides the equivalent of input processors in the form of actions.

A simple migration is illustrated below:

Listing 6. Migrating InputProcessor

Webflow:

 public class ComputeDayIP extends InPutProcessorSupport

Struts:

 public class ComputeDay extends org.apache.strtus.action.Action

Note how simple it is to replace the input processor with the Struts Action class.

Step 7: Migrating the model

The Webflow application’s model basically consists of the PipelineSession object, which contains name-value pairs. Migrating the model is relatively easy once you understand how PipelineSession is being used in a particular file.

It is important to note that prior implementations of Webflow used to store the PipelineSession object in the HTTPSession, rather than the HTTPRequest. In Struts, the form bean provides the model equivalent to a Webflow PipelineSession.

Listing 7. Migrating the PipelineSession object

Webflow:

 PipelineSession pSession = null;
String namespace = null;
pSession = getPipelineSession(req);
   
String year = pSession.getYear();

Struts:

 DateData dateData = (DateData) form;
year = dateData.getYear();

Compiling and testing the application

Using RAD, you can now compile the application, create a WAR (Web archive) and deploy it on the test environment available within the tool. It usually takes iterative cycles of source code changes and compilation in a typical migration project.

RAD version 6 provides a built-in test environment with WebSphere Application Server 6. In a real migration project, once you have unit tested the application within RAD, you deploy it in the system integration test environment where you can integrate the application with external system components for end-to-end testing.

Conclusion

This article provided a step-by-step approach to migrating a BEA Webflow application to open source Struts using RAD. You learned which different components make up a Webflow application and how they map to corresponding Struts components. You also learned how to create a simple Web diagram (using RAD), which helps in mapping the application navigation in a Webflow application to Struts.

Samuel Sharaf is a member of Prolifics, a specialized team of IBM WebSphere migration experts. He specializes in migrating applications from competitive platforms to IBM WebSphere Application and Portal Servers v5 and v6. You can reach him at ssharaf@prolifics.com.