Welcome!

Java Authors: James Carlini, Sebastian Kruk, Maureen O'Gara, Elizabeth White, Michael Kopp

Related Topics: Java

Java: Article

The Promise of Handling Complex Page Navigations in Any Web Application

The promise of handling complex page navigations in any Web application

Page navigation requirements become more demanding as Web applications get bigger and more complex. Hard-coded page flow rules make applications less resilient to changes. In this scenario, reusing business logic is one aspect and reusing page flow becomes another aspect. Especially in situations that demand a wizard-kind behavior, it's essential to capture application page flow logic in a declarative fashion.

Spring Web Flow (SWF) is a powerful framework for implementing page flows in a Web application. Even though SWF is part of the Spring Web application development suite that includes Spring MVC, its flexible architecture allows it to be used with any presentation tier Web framework including Apache Struts and JSF. SWF is now available as a development-ready PR 3.0 version and is expected to be part of Spring 1.3.

In this article, we'll explore the features of SWF and use it to build a sample page flow scenario.

Spring Web Flow in Action
In SWF, every flow is a Finite State Machine (FSM). It consists of states and transitions. A state represents the execution of some actions (business logic) or a view that's displayed to the user for user input.

When the FSM starts, the flow enters the start state (a state that's specially marked as start state). A state can be an action state or a view state (SWF has other state types too like decision state, sub-flow state, and end state). Both action states and view states can define one or more transitions from them to a target state. An event triggers a transition from one state and moves the flow to the new state.

When an action state is entered, the flow executes one or more configured action objects for that state. The execution of an action can produce a logical result in the form of an event and it's processed to select a suitable transition. This transition is applied (executed) and as a result the flow enters the next state as defined by this transition.

When a view state is entered, the flow is temporarily paused and a view, as configured for that state, is displayed to the user. When the flow receives an event (user input can be encapsulated as an event) from the user, it resumes execution and processes the event to transition to the next state.

This new state is then processed in the same way and so on. The flow continues to execute until it reaches the end state (specially marked as end state) where the flow is terminated and a view (as configured for the end state) is displayed to the user. Figure 1 depicts how states are processed in FSM.

Flow Builders
SWF can build a flow definition consisting of states and transitions from an XML configuration file. Since SWF implements the classic GoF Builder design pattern, it provides the flexibility to define and use custom flow building logic. Figure 2 shows the flow builder class diagram.

SWF has many FlowBuilder implementations. The XMLFlowBuilder is one of them that can build a flow from an XML configuration file.

The FlowFactoryBean class internally uses a FlowBuilder implementation and acts as an assembler for creating a Flow.

FlowBuilder builder = ...
Flow flow = new FlowFactoryBean(builder).getFlow();

The XMLFlowFactoryBean implementation uses the XMLFlowBuilder to create a flow. In a Spring container, you can configure an XMLFlowFactoryBean as shown below and use it to build a flow:

<bean id="aFlow" class="org.springframework.web.flow.config.XMLFlowFactoryBean">
   <property name="location" value="classpath:myflow.xml" />
</bean>
BeanFactory factory = ....
Flow flow = (Flow)factory.getBean("aFlow");

[Spring recognizes the defined bean as a 'factory bean' and invokes its getObject() method, which in turn invokes the getFlow() method to create and return a flow.]

You can also create a flow by sub-classing the AbstractFlowBuilder class as shown below. This class defines many helper methods like addViewState() and addActionState() to define the flow at runtime.

public class AFlowBuilder extends AbstractFlowBuilder {
   protected String flowId() {return "aFlow";}
   public void buildStates() {
    addViewState("stateId","viewName",transition);
    addActionState("stateId", targetAction, transition);
    ...
   }
}

A flow builder internally uses a FlowServiceLocator to create all flow elements including a Flow, a State, and a Transition. The BeanFactoryFlowServiceLocator implementation uses Spring's bean factory to look up and create flow elements. By default the XMLFlowBuilder uses the BeanFactoryFlowServiceLocator.

The XMLFlowBuilder allows a flow element (flow/state /transition, etc.) to have the common optional properties bean, classref, class, and autowire. If a 'bean' or 'classref' property is provided the XMLFlowBuilder uses this value for resolving the bean reference using Spring. Otherwise, if a "class" property is given, a new element of the given type is created using reflection. The 'autowire' property denotes whether to use Spring's autowire (the ability to automatically apply dependency injection) capability or not.

A Sample Scenario - Shopping Cart Checkout
Let's discuss a simple scenario where a user uses a Web wizard to check out items in his shopping cart that he wants to buy. Figure 3 shows this scenario.

Step 1: Create an XML Web flow definition (checkoutFlow.xml) as shown in Listing 1.

Step 2: Create an XML flow factory bean entry in Spring's context XML configuration file as shown in Listing 2.

Step 3: Execute the flow. See Listing 3.

More Stories By Kishore Kumar

Kishore Kumar works as a Java architect at U.S. Technology (www.ustri.com). He specializes in J2EE applications.

Comments (5) View Comments

Share your thoughts on this story.

Add your comment
You must be signed in to add a comment. Sign-in | Register

In accordance with our Comment Policy, we encourage comments that are on topic, relevant and to-the-point. We will remove comments that include profanity, personal attacks, racial slurs, threats of violence, or other inappropriate material that violates our Terms and Conditions, and will block users who make repeated violations. We ask all readers to expect diversity of opinion and to treat one another with dignity and respect.


Most Recent Comments
Eelco Hillenius 08/02/06 11:58:26 AM EDT

'Page navigation' is a knee-jerk reaction that doesn't solve any real problems. See http://chillenious.wordpress.com/2006/07/16/on-page-navigation/

JD 08/01/06 06:53:29 PM EDT

This article is really good. Two things missing in this article. The link or references to the actual JSPs and the link to the whole zipped source so people could run it and see for themselves.

news desk 12/04/05 04:18:34 AM EST

Java & SOA - The Promise of Handling Complex Page Navigations in Any Web Application. Page navigation requirements become more demanding as Web applications get bigger and more complex. Hard-coded page flow rules make applications less resilient to changes. In this scenario, reusing business logic is one aspect and reusing page flow becomes another aspect. Especially in situations that demand a wizard-kind behavior, it's essential to capture application page flow logic in a declarative fashion.

jdj news desk 12/04/05 03:29:55 AM EST

The Promise of Handling Complex Page Navigations in Any Web Application. Page navigation requirements become more demanding as Web applications get bigger and more complex. Hard-coded page flow rules make applications less resilient to changes. In this scenario, reusing business logic is one aspect and reusing page flow becomes another aspect. Especially in situations that demand a wizard-kind behavior, it's essential to capture application page flow logic in a declarative fashion.

Jeanne 09/29/05 12:36:59 PM EDT

Listings 2 and 3 are not linked in the article.