Spring Webflow Reference

106
Reference Documentation Version 1.0.5 October 2007 Copyright © 2004-2007 Keith Donald, Erwin Vervaet, Ross Stoyanchev Copies of this document may be made for your own use and for distribution to others, provided that you do not charge any fee for such copies and further provided that each copy contains this Copyright Notice, whether distributed in print or electronically.

Transcript of Spring Webflow Reference

Page 1: Spring Webflow Reference

Reference Documentation

Version 1.0.5

October 2007

Copyright © 2004-2007 Keith Donald, Erwin Vervaet, Ross Stoyanchev

Copies of this document may be made for your own use and for distribution to others, provided that you do notcharge any fee for such copies and further provided that each copy contains this Copyright Notice, whether

distributed in print or electronically.

Page 2: Spring Webflow Reference
Page 3: Spring Webflow Reference

SponsorsSpring Web Flow would not be possible without the investment of its sponsors: Interface21 and Ervacon.

Spring Web Flow Version 1.0.5 i

Page 4: Spring Webflow Reference

Table of ContentsPreface ................................................................................................................................................1. Introduction ..................................................................................................................................

1.1. Overview ............................................................................................................................. 71.2. Architecture overview .......................................................................................................... 71.3. Architectural layers .............................................................................................................. 71.4. Layer descriptions ................................................................................................................ 8

1.4.1. The Execution Core Layer (Bottom Layer) .................................................................. 81.4.2. The Execution Engine Layer ...................................................................................... 101.4.3. The Test Layer .......................................................................................................... 101.4.4. The Executor Layer ................................................................................................... 101.4.5. The System Configuration Layer (Top Layer) ............................................................. 11

1.5. Support ................................................................................................................................ 122. Flow definition ..............................................................................................................................

2.1. Introduction ......................................................................................................................... 132.2. FlowDefinition ..................................................................................................................... 13

2.2.1. XML-based Flow template ......................................................................................... 142.2.2. Java Flow API example ............................................................................................. 15

2.3. StateDefinition ..................................................................................................................... 152.4. Transitionable State .............................................................................................................. 16

2.4.1. XML-based state template .......................................................................................... 162.4.2. Java state API example .............................................................................................. 17

2.5. TransitionDefinition ............................................................................................................. 172.5.1. Transition XML template ........................................................................................... 182.5.2. Transition Java API example ...................................................................................... 182.5.3. Action transition execution criteria ............................................................................. 182.5.4. Dynamic transitions ................................................................................................... 182.5.5. Global transitions ...................................................................................................... 192.5.6. Transition executing exception handlers ...................................................................... 202.5.7. Custom exception handlers ......................................................................................... 21

2.6. Concrete state types .............................................................................................................. 222.6.1. ViewState ................................................................................................................. 232.6.2. ActionState ............................................................................................................... 282.6.3. DecisionState ............................................................................................................ 372.6.4. SubflowState ............................................................................................................. 382.6.5. EndState ................................................................................................................... 41

3. Flow execution ..............................................................................................................................3.1. Introduction ......................................................................................................................... 453.2. FlowExecution ..................................................................................................................... 45

3.2.1. Flow execution creation ............................................................................................. 453.2.2. Flow execution startup ............................................................................................... 453.2.3. Flow execution resume .............................................................................................. 463.2.4. Flow execution lifecycle ............................................................................................ 463.2.5. Flow execution properties .......................................................................................... 473.2.6. Flow execution impl creation ..................................................................................... 47

3.3. Flow execution context ......................................................................................................... 483.4. Flow execution scopes .......................................................................................................... 503.5. Flow execution testing .......................................................................................................... 51

3.5.1. Flow execution test example ...................................................................................... 51

Spring Web Flow Version 1.0.5 ii

Page 5: Spring Webflow Reference

3.5.2. Execution unit testing vs. full-blown system testing ..................................................... 544. Flow execution repositories ...........................................................................................................

4.1. Introduction ......................................................................................................................... 564.2. Repository architecture overview .......................................................................................... 564.3. Flow execution identity ........................................................................................................ 57

4.3.1. Conversation identifier ............................................................................................... 574.3.2. Continuation identifier ............................................................................................... 584.3.3. Flow execution key .................................................................................................... 58

4.4. Conversation ending ............................................................................................................. 584.5. Flow execution repository implementations ........................................................................... 58

4.5.1. Simple flow execution repository ................................................................................ 584.5.2. Continuation flow execution repository ....................................................................... 594.5.3. Client continuation flow execution repository .............................................................. 59

5. Flow executors ..............................................................................................................................5.1. Introduction ......................................................................................................................... 605.2. FlowExecutor ...................................................................................................................... 60

5.2.1. FlowExecutorImpl ..................................................................................................... 615.2.2. A typical flow executor configuration with Spring 2.0 ................................................. 615.2.3. A flow executor using a simple execution repository .................................................... 625.2.4. A flow executor using a client-side continuation-based execution repository ................. 625.2.5. A flow executor using a single key execution repository .............................................. 625.2.6. A flow executor setting custom conversation management attributes ............................. 625.2.7. A flow executor setting system execution attributes ..................................................... 635.2.8. A flow executor setting custom execution listeners ...................................................... 635.2.9. A Spring 1.2 compatible flow executor configuration ................................................... 63

5.3. Spring MVC integration ....................................................................................................... 645.3.1. A single flow controller executing all flows in a Servlet MVC environment .................. 645.3.2. A single portlet flow controller executing a flow within a Portlet .................................. 64

5.4. Flow executor parameterization ............................................................................................. 655.4.1. Request parameter-based flow executor argument extraction ........................................ 655.4.2. Request path based flow executor argument extraction ................................................. 66

5.5. Struts integration .................................................................................................................. 675.5.1. A single flow action executing all flows ...................................................................... 67

5.6. Java Server Faces (JSF) integration ....................................................................................... 675.6.1. Adding Spring Web Flow extensions to faces-config.xml ............................................. 675.6.2. Configuring the Web Flow system .............................................................................. 685.6.3. Launching a flow execution - JSF command link component ........................................ 695.6.4. Launching a flow execution - normal HTML anchor .................................................... 695.6.5. Flow definitions in a JSF environment ........................................................................ 695.6.6. Resuming a flow execution - form bound to flow execution variables ........................... 705.6.7. Spring Web Flow JSF Integration Samples .................................................................. 705.6.8. A pre Spring Web Flow 1.0.2 faces-config.xml file ...................................................... 705.6.9. A pre Spring Web Flow 1.0.2 Web Flow system configuration ..................................... 715.6.10. Resuming a flow execution - pre Spring Web Flow 1.0.2 ........................................... 71

6. Practical Use of Spring Web Flow .................................................................................................6.1. Sample applications .............................................................................................................. 726.2. Running the Web Flow sample applications ........................................................................... 72

6.2.1. Building from the Command Line .............................................................................. 726.2.2. Importing Projects into Eclipse ................................................................................... 736.2.3. Deploying projects inside Eclipse using Eclipse Web Tools (WTP) .............................. 736.2.4. Other IDE's ............................................................................................................... 73

6.3. Sellitem Example ................................................................................................................. 73

Spring Web Flow

Spring Web Flow Version 1.0.5 iii

Page 6: Spring Webflow Reference

6.3.1. Overview .................................................................................................................. 746.3.2. Web.xml ................................................................................................................... 746.3.3. Services-config.xml ................................................................................................... 756.3.4. Spring MVC Context ................................................................................................. 766.3.5. Sellitem-beans.xml .................................................................................................... 776.3.6. Sellitem-flow Flow Definition .................................................................................... 786.3.7. Sellitem-simple-flow Flow Definition ......................................................................... 796.3.8. Sellitem-conversation-scope-flow Flow Definition ...................................................... 79

6.4. Sellitem-JSF Example .......................................................................................................... 806.4.1. Overview .................................................................................................................. 806.4.2. Web.xml ................................................................................................................... 806.4.3. Web Flow JSF Setup in faces-config.xml .................................................................... 816.4.4. Web Flow System Setup in webflow-config.xml ......................................................... 816.4.5. Launching the sellitem-flow ....................................................................................... 82

6.5. Shippingrate Example ........................................................................................................... 826.5.1. Overview .................................................................................................................. 826.5.2. Web.xml ................................................................................................................... 836.5.3. Spring MVC Context ................................................................................................. 836.5.4. Ajax Requests ........................................................................................................... 846.5.5. getRate Web Flow ..................................................................................................... 85

6.6. Numberguess Example ......................................................................................................... 866.6.1. Overview .................................................................................................................. 866.6.2. Web.xml ................................................................................................................... 866.6.3. Spring MVC Context ................................................................................................. 876.6.4. Higherlower Flow ...................................................................................................... 876.6.5. Mastermind Flow ...................................................................................................... 88

6.7. Flowlauncher Example ......................................................................................................... 896.7.1. Overview .................................................................................................................. 896.7.2. Web.xml ................................................................................................................... 896.7.3. Spring MVC Context ................................................................................................. 896.7.4. Sample A Web Flow .................................................................................................. 906.7.5. Sample B Web Flow .................................................................................................. 91

6.8. Itemlist Example .................................................................................................................. 916.8.1. Overview .................................................................................................................. 916.8.2. Web.xml ................................................................................................................... 916.8.3. Spring MVC Context ................................................................................................. 926.8.4. Itemlist Web Flow ..................................................................................................... 936.8.5. Itemlist-alternate Web Flow ....................................................................................... 94

6.9. Fileupload Example .............................................................................................................. 946.9.1. Overview .................................................................................................................. 946.9.2. Web.xml ................................................................................................................... 946.9.3. Spring MVC Context ................................................................................................. 956.9.4. Fileupload Web Flow ................................................................................................. 95

6.10. Birthdate Example .............................................................................................................. 966.10.1. Overview ................................................................................................................ 966.10.2. Web.xml ................................................................................................................. 976.10.3. Struts Configuration ................................................................................................. 976.10.4. Birthdate Web Flow ................................................................................................. 986.10.5. Birthdate-alternate Web Flow ................................................................................... 100

6.11. Phonebook-Portlet Example ................................................................................................ 1006.11.1. Overview ................................................................................................................ 1006.11.2. Portal/Portlet Related Software Used in the Sample ................................................... 101

Spring Web Flow

Spring Web Flow Version 1.0.5 iv

Page 7: Spring Webflow Reference

6.11.3. Portlet.xml Configuration ......................................................................................... 1026.11.4. Web.xml Configuration ............................................................................................ 1026.11.5. Portlet MVC Configuration ...................................................................................... 103

Spring Web Flow

Spring Web Flow Version 1.0.5 v

Page 8: Spring Webflow Reference

PrefaceMany web applications consist of a mix of free browsing, where the user is allowed to navigate a web site asthey please, and controlled navigations where the user is guided through a series of steps towards completion ofa business goal.

Consider the typical shopping cart application. While a user is shopping, she is freely browsing availableproducts, adding her favorites to her cart while skipping over others. This is a good "free browsing" use case.However, when the user decides to checkout, a controlled workflow begins--the checkout process. Such aprocess represents a single user conversation that takes place over a series of steps, and navigation fromstep-to-step is controlled. The entire process represents an discrete application transaction that must completeexactly once or not at all.

Consider some other good examples of "controlled navigations": applying for a loan, paying your taxes on-line,booking a trip reservation, registering an account, or updating a warehouse inventory.

Traditional approaches to modeling and enforcing such controlled navigations or "flows" fall flat, and fail toexpress the Flow as a first class concept. Spring Web Flow (SWF) is a component of the Spring Framework'sweb stack focused on solving this problem in a productive and powerful manner.

Spring Web Flow Version 1.0.5 vi

Page 9: Spring Webflow Reference

Chapter 1. Introduction

1.1. Overview

Spring Web Flow (SWF) is a component of the Spring Framework's web stack focused on the definition andexecution of UI flow within a web application.

The system allows you to capture a logical flow of your web application as a self-contained module that can bereused in different situations. Such a flow guides a single user through the implementation of a business task,and represents a single user conversation. Flows often execute across HTTP requests, have state, exhibittransactional characteristics, and may be dynamic and/or long-running in nature.

Spring Web Flow exists at a higher level of abstraction, integrating as a self-contained flow engine within baseframeworks such as Struts, Spring MVC, Portlet MVC, and JSF. SWF provides you the capability to captureyour application's UI flow explicitly in a declarative, portable, and manageable fashion. SWF is a powerfulcontroller framework based on a finite-state machine, fully addressing the "C" in MVC.

1.2. Architecture overview

Spring Web Flow has been architected as a self-contained flow engine with few required dependencies onthird-party APIs. All dependencies are carefully managed.

At a minimum, to use Spring Web Flow you need:

• spring-webflow (the framework)• spring-core (miscellaneous utility classes used internally by the framework)• spring-binding (the Spring data binding framework, used internally)• commons-logging (a simple logging facade, used internally)• OGNL (the default expression language)

Most users will embed SWF as a component within a larger web application development framework, as SWFis a focused controller technology that expects a calling system to care for request mapping and responserendering. In this case, those users will depend on a thin integration piece for their environment. For example,those executing flows within a Servlet environment might use the Spring MVC integration to care fordispatching requests to SWF and rendering responses for SWF view selections. Spring Web Flow shipsconvenient Spring MVC, Struts Classic, and JSF integration out of the box.

Note

Spring Web Flow, like Spring, is a layered framework, packaged in a manner that allows teams touse the parts they need and nothing else. For example, one team might use Spring Web Flow in aServlet environment with Spring MVC and thus require the Spring MVC integration. Another teammight use SWF in a Portlet environment, and thus require the Portlet MVC integration. Anotherteam might mix and match. A major benefit of SWF is that it allows you to define reusable,self-contained controller modules that can execute in any environment.

1.3. Architectural layers

Spring Web Flow Version 1.0.5 7

Page 10: Spring Webflow Reference

Spring Web Flow is a layered framework. A diagram of Spring Web Flow's layered architecture is shownbelow:

Spring Web Flow layer diagram

1.4. Layer descriptions

Each layer is partitioned into one or more subsystems that together carry out the layer's role within the overallsystem. This section notes the purpose of each layer and describes each subsystem in the following format:

• Subsystem name - The name of a layer subsystem.• Description - The purpose of the subsystem.• Packages - The Java packages that contain the source code for the subsystem. The packages are rooted at

the org.springframework.webflow root package in the package hierarchy.• Subsystem interfaces - Central API elements exposed by the subsystem, typically through Java interfaces.• Internal dependencies - Dependencies of the subsystem. These could be other subsystems of the layer or

external libraries.

1.4.1. The Execution Core Layer (Bottom Layer)

Defines core flow definition and execution public APIs. As the "bottom layer", this layer is highly stable withno dependencies on any other layer.

Table 1.1. Execution Core Subsystems

Subsystemname

Description Packages Subsysteminterfaces

Internaldependencies

Core Foundational, generic types usableby all other subsystems. Containsthe default expression parser(OGNL-based) and core collectiontypes (AttributeMap andcompany).

core,core.collection

None None

Introduction

Spring Web Flow Version 1.0.5 8

Page 11: Spring Webflow Reference

Subsystemname

Description Packages Subsysteminterfaces

Internaldependencies

Util Low level utilities used by all otherparts of the system.

util None None

Flow Definition Central abstractions for modelingflow definitions. Theseabstractions includeFlowDefinition,StateDefinition, andTransitionDefinition that formthe domain language for describingflows.

definition FlowDefinition Core

Flow DefinitionRegistry

Support for working with registriesof flow definitions. Flowdefinitions eligible for executionare typically stored in a registrythat provides lookup services.

definition.registry FlowDefinitionRegistry,FlowDefinitionLocator

Core, FlowDefinition

ExternalContext

Provides normalized access to aclient environment that has calledinto Spring Web Flow.

context,context.servlet,context.portlet

ExternalContext Core,context.servletrequires ServletAPI 2.3,context.portletrequires PortletAPI 1.0 inaddition toServlet API 2.3

Conversation Manages the creation and cleanupof conversational state. Used bythe execution repository system tobegin new user conversations andtrack execution state.

conversation,conversation.impl

ConversationManagerCore, Util,ExternalContext

Flow Execution Stable runtime abstractions thatdefine the flow definitionexecution model. For executingflow definitions and representingexecution state.

execution,execution.support,execution.factory

FlowExecution Core, ExternalContext, FlowDefinition

Flow ExecutionRepository

For persisting paused flowexecutions beyond a single requestinto the server.

execution.repository,execution.repository.support,execution.repository.continuation

FlowExecutionRepositoryCore, Util, FlowDefinition,Conversation,Flow Execution

Action Reusable action implementations. action,action.portlet

None Core, Util, FlowDefinition,ExternalContext, FlowExecution

Introduction

Spring Web Flow Version 1.0.5 9

Page 12: Spring Webflow Reference

1.4.2. The Execution Engine Layer

Defines an implementation of the flow execution core API, forming the basis of the state machine or "engine"implementation. More volatile, as it contains specific implementations of stable execution abstractions.

Depends On: Execution Core

Table 1.2. Execution Engine Subsystems

Subsystemname

Description Packages Subsysteminterfaces

Internaldependencies

EngineImplementation

The implementation of the flowexecution engine based on a finitestate machine.

engine,engine.support,engine.impl

None None

Flow DefinitionBuilder

Abstractions used atconfiguration-time for building andassembling Flow definitionsexecutable by this engineimplementation. Flows aretypically defined in externalizedresources such as XML files.

engine.builder,engine.builder.xml

FlowBuilder EngineImplementation,Spring Beans1.2.7, SpringContext 1.2.7,builder.xml

requires JDK1.5 or Xercesfor XSD support

1.4.3. The Test Layer

Support for unit testing flow artifacts and system testing flow executions.

Depends On: Execution Engine, Execution Core

Table 1.3. Test Subsystems

Subsystemname

Description Packages Subsysteminterfaces

Internaldependencies

Engine ArtifactUnit TestSupport

Support for unit testingimplementations such as Actionsin isolation.

test None JUnit 3.8.1

Flow ExecutionTest Support

Support for testing FlowExecutions out-of-container.

test.execution None Spring Beans1.2.7, JUnit3.8.1

1.4.4. The Executor Layer

Stable higher-level layer for driving and coordinating the execution of flow definitions. This layer is decoupledfrom the more-volatile engine implementation.

Depends On: Execution Core

Introduction

Spring Web Flow Version 1.0.5 10

Page 13: Spring Webflow Reference

Table 1.4. Executor Subsystems

Subsystemname

Description Packages Subsysteminterfaces

Internaldependencies

Core Generic flow executor abstractionsand support.

executor,executor.support

FlowExecutor None

Spring MVC The integration between SpringWeb Flow and the Spring MVCframework.

executor.mvc None Core, SpringWeb MVC1.2.7, PortletMVC requiresSpring 2.0

Struts The integration between SpringWeb Flow and the Struts Classicframework.

executor.struts None Core, Struts 1.1

Java ServerFaces (JSF)

The integration between SpringWeb Flow and the Java ServerFaces framework.

executor.jsf None Core, JSF 1.0

1.4.5. The System Configuration Layer (Top Layer)

The top-most layer for configuring the overall Spring Web Flow system for use within an application. As thetop layer, this layer depends on the most.

Depends On: Executor, Execution Engine, Execution Core

Table 1.5. System Configuration Subsystems

Subsystemname

Description Packages Subsysteminterfaces

Internaldependencies

SpringConfigurationSupport

For configuring Spring Web Flowusing Spring 1.x and 2.x.

config None Spring Beans1.2.7,spring-webflow-config-1.0

XSD supportrequires Spring2.0

Note

As described above, some subsystem packages are optional depending on your use of thesubsystem. For example, use of Spring Web Flow in a Servlet environment entails use of theExternalContext context.servlet package which requires the Servlet API to be in the classpath. Inthis case, the context.portlet package is not used and the Portlet API is not required.

For the exact list of dependencies, as well as supported product usage configurations, see the Ivy dependencymanager descriptor located within the SWF distribution.

Introduction

Spring Web Flow Version 1.0.5 11

Page 14: Spring Webflow Reference

1.5. Support

Spring Web Flow 1.x is supported on Spring Framework 1.2.7 or > for the 1.x series, and supported on 2.0 or >for the 2.x series.

XML-based flow building requires Xerces 2 or JDK 5.0 (for XSD support).

The Spring Web Flow Portlet integration requires Spring Portlet MVC 2.0.

Our active community support forum is located at http://forum.springframework.org.

Introduction

Spring Web Flow Version 1.0.5 12

Page 15: Spring Webflow Reference

Chapter 2. Flow definition

2.1. Introduction

Spring Web Flow allows developers to build reusable, self-contained controller modules called flows. A flowdefines a user dialog that responds to user events to drive the execution of application code to complete abusiness goal.

Flows are defined declaratively using a rich domain-specific language (DSL) tailored to the problem domain ofUI flow. Currently, XML and Java-based forms of this language are provided.

This chapter documents Spring Web Flow's core flow definition language. You will learn the core domainconstructs of the system and how those constructs are representable in an externalized XML form.

2.2. FlowDefinition

A flow definition is a instance of org.springframework.webflow.definition.FlowDefinition. This is thecentral domain artifact representing the definition of a user dialog or task.

A flow definition consists of a set of one or more states, where each state defines a step in the flow that whenentered executes a behavior. What behavior is executed is a function of the state's type and configuration. Theoutcome of a state's execution, called an event, is used by the flow to drive a state transition.

Exactly one of a flow's states is the startState that defines the starting point of the flow. Optionally, a flowcan have one or more end states defining the ending points of the flow.

An example definition of a simple flow to carry out a search process is shown graphically below:

Search Flow

The default FlowDefinition implementation in Spring Web Flow isorg.springframework.webflow.engine.Flow. Its configurable properties are summarized below:

Spring Web Flow Version 1.0.5 13

Page 16: Spring Webflow Reference

Table 2.1. Flow properties

Property name Description Cardinality Default value

id The identifier of the flow definition,typically unique to all other flows of theapplication.

1

attributes Additional custom attributes about theflow.

0..* None

states The steps of the flow. 1..*

startState The starting point of the flow. 1

variables The set of flow instance variables to createeach time an execution of the flow isstarted.

0..* Empty

inputMapper The service responsible for mapping flowinput provided by the client each time anexecution of the flow is started.

0..1 Null

startActions The list of actions to execute each time anexecution of the flow is started.

0..* Empty

endActions The list of actions to execute each time anexecution of the flow ends.

0..* Empty

outputMapper The service responsible for mapping flowoutput to expose to the client each time anexecution of the flow ends.

0..1 Null

globalTransitions The set of transitions shared by all statesof the flow.

0..* Empty

exceptionHandlers An ordered set of handlers to be appliedwhen an exception is thrown within a stateof the flow.

0..* Empty

inlineFlows A set of inner flows that will be called assubflows; these flows are locally scoped tothe outer flow.

0..* Empty

Below is a high level example of how these properties can be configured in XML form or directly in Java code.

2.2.1. XML-based Flow template

<?xml version="1.0" encoding="UTF-8"?><flow xmlns="http://www.springframework.org/schema/webflow"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="

http://www.springframework.org/schema/webflowhttp://www.springframework.org/schema/webflow/spring-webflow-1.0.xsd">

<attribute .../>

<var .../>

Flow definition

Spring Web Flow Version 1.0.5 14

Page 17: Spring Webflow Reference

<input-mapper .../>

<start-actions>...

</start-actions>

<start-state idref="yourStartingStateId"/>

<-- your state definitions go here -->

<global-transitions>...

</global-transitions>

<end-actions>...

</end-actions>

<output-mapper .../>

<exception-handler .../>

<inline-flow>...

</inline-flow>

</flow>

2.2.2. Java Flow API example

Flow flow = new Flow("id");flow.getAttributeMap().put("name", "value");flow.addState(...);flow.setStartState("startingPoint");flow.addVariable(...);flow.setInputMapper(...);flow.getStartActionList().add(...);flow.getEndActionList().add(...);flow.setOutputMapper(...);flow.getGlobalTransitionSet().add(...);flow.getExceptionHandlerSet().add(...);flow.addInlineFlow(...);

A Flow is typically built by a FlowBuilder rather than assembled by hand. The flow building subsystem iscontained within the org.springframework.webflow.engine.builder package. The XML Flow Builder andspring-webflow.xsd schema are located within the org.springframework.webflow.engine.builder.xml

package. The XML-based format is currently the most popular way to define flows, though Groovy-based andJava-based formats are emerging.

2.3. StateDefinition

A StateDefinition defines the behavior for a step of a FlowDefinition. The base implementation class for allFlow state types is org.springframework.webflow.engine.State. This abstract class defines commonproperties applicable to all state types, which include:

Table 2.2. State properties

Flow definition

Spring Web Flow Version 1.0.5 15

Page 18: Spring Webflow Reference

Property name Description Cardinality Default value

id The id of the state, unique to its containingflow definition.

1

owner The owning flow definition. 1

attributes Additional custom attributes about thestate.

0..* None

entryActions The list of actions to execute each time thestate is entered.

0..* Empty

exceptionHandlers An ordered set of handlers to be invokedwhen an exception is thrown within thestate.

0..* Empty

2.4. Transitionable State

A central subclass of State is org.springframework.webflow.TransitionableState. This abstract classdefines common properties applicable to all state types that execute transitions to other states in response toevents. These properties include:

Table 2.3. TransitionableState properties

Property name Description Cardinality Default value

transitions The eligible paths out of this state. 1..*

exitActions The list of actions to execute each timethis state is exited.

0..* Empty

Below is a mock flow definition snippet showing how properties may be configured for a TransitionableState inXML and in Java code:

2.4.1. XML-based state template

<?xml version="1.0" encoding="UTF-8"?><flow xmlns="http://www.springframework.org/schema/webflow"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="

http://www.springframework.org/schema/webflowhttp://www.springframework.org/schema/webflow/spring-webflow-1.0.xsd">

<start-state idref="myStateId"/>

<xxx-state id="myStateId"><attribute name="..." value="..."/>

<entry-actions>...

</entry-actions>

<transition on="..." to="..."/><transition on-exception="..." to="..."/>

<exit-actions>...

Flow definition

Spring Web Flow Version 1.0.5 16

Page 19: Spring Webflow Reference

</exit-actions>

<exception-handler .../></xxx-state>

</flow>

2.4.2. Java state API example

Flow flow = new Flow("id");TransitionableState state = new XXXState(flow, "stateId");state.getAttributeMap().put("name", "value");state.getEntryActionList().add(...);state.getTransitionSet().add(...);state.getExitActionList().add(...);

A State is typically constructed by a FlowArtifactFactory, used by a FlowBuilder during flow assembly. Theflow building subsystem is contained within the org.springframework.webflow.engine.builder package.

2.5. TransitionDefinition

A transition takes a flow from one state to another, defining a path through the flow. This is modeled using aTransitionDefinition.

Recall that all TransitionableStates have a set of one or more transitions, each defining a path to another state inthe flow (or a recursive path back to the same state). When a transitionable state is entered, it executes abehavior. For example, a transitionable state called "Display Form" may display a form to the user and wait foruser input. The outcome of the state's execution, called an event, is used to drive execution of one of the state'stransitions. For example, the user may press the form submit button which signals a submit event that matchesthe transition to the "Process Submit" state.

This event-driven transition execution process is shown graphically below:

Transition execution

The transition definition implementation is defined by an instance oforg.springframework.webflow.engine.Transition. Its properties are summarized below:

Flow definition

Spring Web Flow Version 1.0.5 17

Page 20: Spring Webflow Reference

Table 2.4. Transition properties

Property name Description Cardinality Default value

attributes Additional attributes describing thetransition.

0..* None

matchingCriteria The strategy that determines if thetransition matches on an event occurrence.

1 Always matches

executionCriteria The strategy that determines if thetransition, once matched, is allowed toexecute.

1 Always allowed

targetStateResolver The strategy that resolves the target stateof the transition. Most transitions alwaysresolve to the same target state. Thisstrategy allows for dynamic resolution.

1

Below is a high-level example of how a Transition can be configured in XML form or directly in Java code.

2.5.1. Transition XML template

<transition on="event" to="targetState"><attribute ... /><action ... />

</transition>

2.5.2. Transition Java API example

Transition transition = new Transition("targetState");transition.getAttributeMap().put("name", "value");transition.setMatchingCriteria(new EventIdTransitionCriteria("event"));transition.setExecutionCriteria(...);

2.5.3. Action transition execution criteria

In the XML transition template above, note the support for the action element within the transition element.

A transition may be configured with one or more actions that execute before the transition itself executes. Ifone or more of these actions do not complete successfully, the transition will not be allowed. This executioncriteria makes it possible to execute arbitrary logic after a transition is matched but before it is executed. This isuseful when you want to execute event post-processing logic. A good example is executing form data bindingand validation behavior after a form submit event.

2.5.4. Dynamic transitions

A transition's target state resolver can be configured to dynamically calculate the target state. For example:

Flow definition

Spring Web Flow Version 1.0.5 18

Page 21: Spring Webflow Reference

<transition on="back" to="${flowScope.lastViewStateId}" />

This will transition the flow to the state resolved by evaluating the flowScope.lastViewStateId expression.

2.5.5. Global transitions

As outlined, one or more transitions are added to all TransitionableState types, attached at the state-level.Optionally, transitions may also be added at the flow-level where they are shared by all states. These sharedtransitions are called global transitions.

When an event is signaled in a transitionable state, the state will first try and match one of its own transitions. Ifthere is no match at the state level, the set of global transitions will be tested. If there still is no match, aNoMatchingTransitionException will be thrown.

Global transitions are useful in situations where many states of the flow share the same transitional criteria. Forexample, consider a navigation menu that displays alongside each view of a flow. Logic to process navigationmenu events is needed by all view states. This is the problem global transitions are designed to solve.

2.5.5.1. Global transitions - XML example

The following example shows transitions defined at the state level, as well as global transitions defined at theflow level.

<?xml version="1.0" encoding="UTF-8"?><flow xmlns="http://www.springframework.org/schema/webflow"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="

http://www.springframework.org/schema/webflowhttp://www.springframework.org/schema/webflow/spring-webflow-1.0.xsd">

<start-state idref="state1"/>

<xxx-state id="state1"><transition on="localEvent1" to="state2"/>

</xxx-state>

<xxx-state id="state2"><transition on="localEvent1" to="state1"/>

</xxx-state>

<global-transitions><transition on="globalEvent1" to="state1"/><transition on="globalEvent2" to="state2"/>

</global-transitions>

</flow>

In this mock example, state1 defines one transition and also inherits the two others defined within theglobal-transitions element. Any other states defined within this flow would also inherit those globaltransitions.

This example is shown graphically below:

Flow definition

Spring Web Flow Version 1.0.5 19

Page 22: Spring Webflow Reference

Global transitions

2.5.6. Transition executing exception handlers

The <transition/> element contains an exclusive on-exception attribute used to specify an exception-basedcriteria for transition execution. This allows you to transition the flow to another state on the occurrence of anexception. Transition executing exception handlers may be attached at the state and flow levels.

2.5.6.1. State exception handling - XML example

The following example illustrates a state-level transition executing exception handler:

<?xml version="1.0" encoding="UTF-8"?><flow xmlns="http://www.springframework.org/schema/webflow"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="

http://www.springframework.org/schema/webflowhttp://www.springframework.org/schema/webflow/spring-webflow-1.0.xsd">

<start-state idref="state1"/>

<xxx-state id="state1"><transition on="event1" to="state2"/><transition on-exception="example.MyBusinessException" to="state3"/>

</xxx-state>

...

</flow>

In this example, state1 defines one transition and an exception handler which executes a transition to state3 ifa MyBusinessException is thrown within the state. The handled exception will be put into flash scope under thekey stateException, where it will be automatically exposed to the next view (typically an error view).

2.5.6.2. Flow exception handling - XML example

The following example illustrates a flow-level transition executing exception handler:

Flow definition

Spring Web Flow Version 1.0.5 20

Page 23: Spring Webflow Reference

<?xml version="1.0" encoding="UTF-8"?><flow xmlns="http://www.springframework.org/schema/webflow"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="

http://www.springframework.org/schema/webflowhttp://www.springframework.org/schema/webflow/spring-webflow-1.0.xsd">

<start-state idref="state1"/>

<xxx-state id="state1"><transition on="event1" to="state2"/>

</xxx-state>

<xxx-state id="state2"/>

<global-transitions><transition on-exception="example.MyBusinessException" to="state3"/>

</global-transitions>

...

</flow>

In this example, the exception handler is defined as a global transition. This reads "any time aMyBusinessException occurs during flow execution, transition the flow to state3".

Exception handlers attached at the state level take precedence over those defined at the flow level. This isillustrated by the following example:

<?xml version="1.0" encoding="UTF-8"?><flow xmlns="http://www.springframework.org/schema/webflow"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="

http://www.springframework.org/schema/webflowhttp://www.springframework.org/schema/webflow/spring-webflow-1.0.xsd">

<start-state idref="state1"/>

<xxx-state id="state1"><transition on="event1" to="state2"/><transition on-exception="example.MyBusinessException" to="state4"/>

</xxx-state>

<xxx-state id="state2"/>

<global-transitions><transition on-exception="example.MyBusinessException" to="state3"/>

</global-transitions>

...

</flow>

In this example, if MyBusinessException is thrown in state1 the flow will transition to state4. For any otherstate, the flow will transition to state3.

2.5.7. Custom exception handlers

Custom, user-defined exception handlers may be attached at the flow and state levels by using theexception-handler element. This element delegates to Spring to locate the custom exception handler instancewith the specified bean name.

An example of attaching a custom exception handler is shown below:

Flow definition

Spring Web Flow Version 1.0.5 21

Page 24: Spring Webflow Reference

<?xml version="1.0" encoding="UTF-8"?><flow xmlns="http://www.springframework.org/schema/webflow"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="

http://www.springframework.org/schema/webflowhttp://www.springframework.org/schema/webflow/spring-webflow-1.0.xsd">

<start-state idref="state1"/>

<xxx-state id="state1"><transition on="event1" to="state2"/><exception-handler bean="myCustomStateExceptionHandler"/>

</xxx-state>

<xxx-state id="state2"/>

<global-transitions><exception-handler bean="myCustomFlowExceptionHandler"/>

</global-transitions>

<import resource="flow-beans.xml"/>

</flow>

2.5.7.1. flow-beans.xml

<bean id="myCustomStateExceptionHandler" class="example.CustomFlowExecutionExceptionHandler"/><bean id="myCustomFlowExceptionHandler" class="example.AnotherCustomFlowExecutionExceptionHandler"/>

Custom exception handlers must implement theorg.springframework.webflow.engine.FlowExecutionExceptionHandler interface.

2.6. Concrete state types

Spring Web Flow has five (5) built-in concrete state types, all contained within theorg.springframework.webflow.engine package. These states execute common controller behaviorsincluding:

1. allowing the user to participate in a flow (ViewState)

2. executing business application code (ActionState)

3. making a flow routing decision (DecisionState)

4. spawning another flow as a subflow (SubflowState)

5. terminating a flow (EndState)

Each of these state types, with the exception of EndState, is transitionable. This hierarchy is illustrated below:

Flow definition

Spring Web Flow Version 1.0.5 22

Page 25: Spring Webflow Reference

FlowDefinition class diagram

As you will see, with these five basic state types you can develop rich controller modules.

2.6.1. ViewState

When entered, a view state allows the user (or other external client) to participate in a flow. This participationprocess goes as follows:

1. The entered view state makes a org.springframework.webflow.execution.ViewSelection thatrepresents a logical response to issue to the caller.

2. The flow execution 'pauses' in this state, and control is returned to the calling system.

3. The calling system uses the returned ViewSelection to present a suitable interface (or other response) tothe user.

4. After some 'think time', the user signals an input event to resume the flow execution from the 'paused'point.

Spring Web Flow gives you full control over the view selection process and, on resume, how a view stateresponds to a user input event. Spring Web Flow is currently not concerned with rendering the actual response;as a controller, a flow makes a logical view selection when user input is required, where a view selection servesas a response instruction. It is up to the calling system to interpret that instruction to issue a response suitablefor the environment in which the flow is executing.

The properties of a org.springframework.webflow.engine.ViewState are summarized below:

Flow definition

Spring Web Flow Version 1.0.5 23

Page 26: Spring Webflow Reference

Table 2.5. ViewState properties

Property name Description Cardinality Default value

viewSelector The strategy that makes the view selectionwhen this state is entered.

0..1 Null

renderActions The list of actions to execute each time arenderable view selection is made. Allowsfor execution of pre-render logic.

0..* Empty

The org.springframework.webflow.execution.ViewSelection base class is abstract, acting as a markerindicating a response should be issued to the client interacting with the flow. Concrete subtypes exist for eachof the supported response types. These response types are summarized below:

Table 2.6. Concrete ViewSelection types

Type Description

ApplicationView Requests the rendering of a local, internal application view resourcesuch as a JSP, Velocity, or Freemarker template.

FlowExecutionRedirect Requests a redirect back to the ViewState at a unique flow executionURL. When this URL is accessed on subsequent requests, anApplicationView will be reconstituted and rendered. The URL isrefreshable while the flow execution remains active.

Note

Multiple flow execution URLs may be generated for asingle logical user conversation. In that case, each flowexecution URL provides access to the conversation from aprevious point (ViewState). Accessing the URL refreshesthe execution from that point.

FlowDefinitionRedirect Requests a redirect that launches an entirely new flow execution. Usedto support redirect to flow (flow chaining) and restart flow use cases.

ExternalRedirect Requests a redirect to an arbitrary external URL, typically used tointeface with an external system.

NullView Requests that no response be issued; for use in corner cases where theflow itself has already issued the response.

2.6.1.1. ViewSelector

The creational strategy responsible for making a ViewSelection when an ViewState is entered isorg.springframework.webflow.engine.ViewSelector. This provides a plugin-point for customizing how aresponse instruction is constructed.

Four ViewSelector implementations are provided with Spring Web Flow:

Flow definition

Spring Web Flow Version 1.0.5 24

Page 27: Spring Webflow Reference

Table 2.7. ViewSelector implementations

Implementation Description

ApplicationViewSelector Returns an ApplicationView referencing a logical viewName to renderand containing a modelMap with the application data needed by therendering process (by default, this map contains the union of the datascopes such flow, flash, and request scope). Supports setting a redirect

flag that triggers a browser redirect to the selected view using aFlowExecutionRedirect. The default implementation.

FlowDefinitionRedirectSelector Returns a FlowDefinitionRedirect with a flowId and executionInput

map requesting the launch of an entirely new flow execution (aninstance of the FlowDefinition identified by the flowId). Useful forredirect after flow completion, where one flow ending should trigger thestart of another flow independently.

ExternalRedirectSelector Returns an ExternalRedirect that triggers a browser redirect to anabitrary external URL. Mainly used by end states to redirect to externalsystems after flow completion, but can also be used by view states tointerface with an external system that may call back into the flowexecution at a later point.

NullViewSelector Returns an NullView indicating that no response should be issued.

2.6.1.2. ViewState class diagram

The class diagram below shows the ViewState and the associated types used to carry out the view selectionprocess:

ViewState class diagram

2.6.1.3. ViewState XML - application view selection

Flow definition

Spring Web Flow Version 1.0.5 25

Page 28: Spring Webflow Reference

The following example shows a view-state definition in XML that makes an application view selection whenentered, selecting the searchForm view for display and, on resume, responding to two possible user inputevents (submit and cancel) in different ways:

<?xml version="1.0" encoding="UTF-8"?><flow xmlns="http://www.springframework.org/schema/webflow"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="

http://www.springframework.org/schema/webflowhttp://www.springframework.org/schema/webflow/spring-webflow-1.0.xsd">

<start-state idref="displaySearchForm"/>

<view-state id="displaySearchForm" view="searchForm"><transition on="submit" to="processFormSubmission"/><transition on="cancel" to="processCancellation"/>

</view-state>

...

</flow>

View name expressions may also be specified for the view attribute to achieve runtime view name calculation.For example, view="${requestScope.calculatedViewName}".

2.6.1.4. ViewState API - application view selection

The following example shows the equivalent view state definition using the FlowBuilder API:

public class SearchFlowBuilder extends AbstractFlowBuilder {public void buildStates() {

addViewState("displaySearchForm", "searchForm",new Transition[] {

transition(on("submit"), to("processFormSubmission")),transition(on("cancel"), to("processFormCancellation"))

});

...}

}

2.6.1.5. ViewState XML - flow execution redirect

The following example illustrates a view-state definition in XML that makes an flow execution redirectselection when entered, redirecting to the yourList view for display.

<?xml version="1.0" encoding="UTF-8"?><flow xmlns="http://www.springframework.org/schema/webflow"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="

http://www.springframework.org/schema/webflowhttp://www.springframework.org/schema/webflow/spring-webflow-1.0.xsd">

<start-state idref="displayList"/>

<view-state id="displayList" view="redirect:yourList"><transition on="add" to="addListItem"/>

</view-state>

...

</flow>

Flow definition

Spring Web Flow Version 1.0.5 26

Page 29: Spring Webflow Reference

This example is called a flow execution redirect because the application view selected is rendered only after aredirect to the flow execution. The redirect request is sent to a URL that refreshes the flow execution paused inthe displayList view state. Refresh then triggers the rendering of the yourList application view on the nextrequest into the server.

2.6.1.5.1. POST+REDIRECT+GET in Spring Web Flow

The above example is one way to achieve the POST+REDIRECT+GET pattern in Spring Web Flow. When theredirect is performed, the GET request issued hits a stable flow execution URL which remains active for theduration of the conversation. This URL may be freely refreshed. Browser navigational buttons may be usedfreely without browser warnings.

The execution attribute alwaysRedirectOnPause, which enforces this pattern by default, is discussed later inthis document. In that case, each time a view state is entered a redirect is always performed.

2.6.1.6. ViewState API - flow execution redirect

The following example shows the equivalent view state definition using the FlowBuilder API:

public class SearchFlowBuilder extends AbstractFlowBuilder {public void buildStates() {

addViewState("displayList", viewSelector("redirect:yourView"),transition(on("add"), to("addListItem"))

);...

}}

2.6.1.7. ViewState XML - null view

The following example illustrates a view-state definition in XML that makes a null view selection whenentered. This causes no additional response to be issued.

<?xml version="1.0" encoding="UTF-8"?><flow xmlns="http://www.springframework.org/schema/webflow"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="

http://www.springframework.org/schema/webflowhttp://www.springframework.org/schema/webflow/spring-webflow-1.0.xsd">

<start-state idref="displayPdf"/>

<view-state id="displayPdf"><render-actions>

<action bean="pdfWriter" method="write"/></render-actions>

</view-state>

...

</flow>

2.6.1.8. FlowDefinitionRedirect and ExternalRedirect

The FlowDefinitionRedirect and ExternalRedirect are not generally used by a view state. They aretypically used by an end state, either to start a new independent flow or redirect to an arbitrary external URL.Examples are provided in the discussion of the end state.

Flow definition

Spring Web Flow Version 1.0.5 27

Page 30: Spring Webflow Reference

2.6.1.9. ViewState XML - form state behavior

The following example illustrates a view-state definition in XML that encapsulates typical "form state"behavior.

Consider the requirements of typical input forms. Most forms require pre-render or setup logic to executebefore the form is displayed. For example, such logic might load the backing form object from the database,install formatters for formatting form field values, and pull in supporting form data needed to populatedrop-down menus.

In addition, most forms require post-back or submission logic to execute when the form is submitted. This logictypically involves binding form input to the backing form object and performing type conversion and datavalidation.

This "form state" behavior of form setup, display, and post-back is handled elegantly in Spring Web Flow bythe capabilities of the view-state construct. See below:

<?xml version="1.0" encoding="UTF-8"?><flow xmlns="http://www.springframework.org/schema/webflow"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="

http://www.springframework.org/schema/webflowhttp://www.springframework.org/schema/webflow/spring-webflow-1.0.xsd">

<start-state idref="displayForm"/>

<view-state id="displayForm" view="form"><render-actions>

<action bean="formAction" method="setupForm"/><action bean="formAction" method="loadFormReferenceData"/>

</render-actions><transition on="submit" to="saveForm">

<action bean="formAction" method="bindAndValidate"/></transition>

</view-state>

...

</flow>

This reads "when this flow starts enter the displayForm state to execute the setupForm andloadFormReferenceData methods before rendering the form view. On submit, transition to the saveForm stateif the bindAndValidate method executes successfully."

2.6.2. ActionState

When entered, an action state executes business application code, then responds to the result of that executionby deciding what state in the flow to enter next. Specifically:

1. The entered action state executes an ordered list of one or moreorg.springframework.webflow.execution.Action instances. This Action interface is the centralabstraction that encapsulates the execution of a logical unit of application code.

2. The state determines if the outcome of the first action's execution matches a transition. If there is a match,the transition is executed. If there is no match, the next action in the list is executed. This processcontinues until a transition is matched or the list of actions is exhausted.

Spring Web Flow gives you full control over implementing your own actions and configuring when they should

Flow definition

Spring Web Flow Version 1.0.5 28

Page 31: Spring Webflow Reference

be invoked within the lifecycle of a flow. The system can also automatically adapt methods on your existingapplication objects (POJOs) to the Action interface in a non-invasive manner. This means in many cases youcan implement your flows without needing to develop custom glue code to bind SWF to your service layeroperations.

The properties of a org.springframework.webflow.engine.ActionState are summarized below:

Table 2.8. ActionState properties

Property name Description Cardinality Default value

actions The ordered list of actions to executewhen the state is entered.

1..*

2.6.2.1. Action execution points

As outlined, the ActionState is the dedicated state type for invoking one or more actions and responding totheir result to drive a state transition. There are also other points within the lifecycle of a flow where a chain ofactions can be executed. At all of these points, the only requirement is that these actions implement the centralorg.springframework.webflow.execution.Action interface.

Table 2.9. Other points in a Flow where an Action can be executed, and how those points can be definedin a XML-based Flow definition.

Point Description XML Configuration Element

on flow start Each time a new flow session starts. A flow's <start-actions/>

on state entry Each time a state enters. A state's <entry-actions/>

on transition Each time a state transition is matched butbefore it is executed.

A transition <action/>

on state exit Each time a transitionable state exits. A transitionable state's <exit-actions/>

before viewrendering

Each time a renderable view selection ismade.

A view state's <render-actions/>

on flow end Each time a flow session terminates. A flow's <end-actions/>

Note

The other points above where actions may be executed do not allow you to execute a statetransition in response to the action result event. If you need such flow control you must execute theaction from within an action state.

2.6.2.2. Action attributes

An Action may be annotated with attributes by wrapping the Action in a decorator, an instance oforg.springframework.webflow.engine.AnnotatedAction. These attributes may provide descriptivecharacteristics, or may be used to affect the action's execution in a specific usage context.

Flow definition

Spring Web Flow Version 1.0.5 29

Page 32: Spring Webflow Reference

Support for setting several common attributes is provided for convenience. These include:

Table 2.10. Common Action attributes

Attribute name Description

caption A short description about the action, suitable for display as a tool-tip.

description A long description about the action, suitable for display in a text box.

name The name of the action, used to qualify the action's result event. Forexample, an Action named placeOrder that returns success would beassigned a result event identified by placeOrder.success. This allowsyou to distinguish logical execution outcomes by action, useful wheninvoking multiple actions as part of a chain.

method The name of the target method on the Action instance to invoke to carryout execution. This facilitates multiple action methods per Actioninstance, supported by theorg.springframework.webflow.action.MultiAction.

2.6.2.3. ActionState class diagram

The class diagram below shows the ActionState and the associated types used to carry out the action executionprocess:

ActionState class diagram

2.6.2.4. ActionState XML - simple action execution

Flow definition

Spring Web Flow Version 1.0.5 30

Page 33: Spring Webflow Reference

The following example constructs an ActionState definition from XML that executes a single action whenentered and then responds to its result:

<?xml version="1.0" encoding="UTF-8"?><flow xmlns="http://www.springframework.org/schema/webflow"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="

http://www.springframework.org/schema/webflowhttp://www.springframework.org/schema/webflow/spring-webflow-1.0.xsd">

<start-state idref="executeSearch"/>

<action-state id="executeSearch"><action bean="searchAction"/><transition on="success" to="displayResults"/>

</action-state>

...

</flow>

This state definition reads "when the executeSearch state is entered, execute the searchAction. On successfulexecution, transition to the displayResults state."

The binding between the searchAction id and an Action implementation is made at Flow build time byquerying a service locator, typically a Spring BeanFactory. For example:

<beans><bean id="searchAction" class="example.webflow.SearchAction"/>

</beans>

... binds the searchAction action identifier to a singleton instance of the example.webflow.SearchAction

class.

A simple SearchAction implementation might look like this:

public class SearchAction implements Action {private SearchService searchService;

public SearchAction(SearchService searchService) {this.searchService = searchService;

}

public Event execute(RequestContext context) {// lookup the search criteria in "flow scope"SearchCriteria criteria =

(SearchCriteria)context.getFlowScope().get("criteria");

// execute the searchCollection results = searchService.executeSearch(criteria);

// set the results in "request scope"context.getRequestScope().put("results", results);

// return "success"return new Event(this, "success");

}}

2.6.2.5. ActionState API - standard action

The following example constructs the equivalent action state definition using the FlowBuilder API:

Flow definition

Spring Web Flow Version 1.0.5 31

Page 34: Spring Webflow Reference

public class SearchFlowBuilder extends AbstractFlowBuilder {public void buildStates() {...addActionState("executeSearch", action("searchAction"),

transition(on("success"), to("displayResults")));...

}}

2.6.2.6. ActionState XML - multi action

The next example constructs an ActionState definition from XML that executes a single action method on aorg.springframework.webflow.action.MultiAction and then responds to its result:

<?xml version="1.0" encoding="UTF-8"?><flow xmlns="http://www.springframework.org/schema/webflow"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="

http://www.springframework.org/schema/webflowhttp://www.springframework.org/schema/webflow/spring-webflow-1.0.xsd">

<start-state idref="executeSearch"/>

<action-state id="executeSearch"><action bean="searchAction" method="executeSearch"/><transition on="success" to="displayResults"/>

</action-state>

...

</flow>

This state definition reads "when the executeSearch state is entered, call the executeSearch method on thesearchFlowAction. On successful execution, transition to the displayResults state."

A SearchAction implementation containing multiple action methods might look like this:

public class SearchAction extends MultiAction {private SearchService searchService;

public SearchAction(SearchService searchService) {this.searchService = searchService;

}

public Event executeSearch(RequestContext context) {// lookup the search criteria in "flow scope"SearchCriteria criteria =

(SearchCriteria)context.getFlowScope().get("criteria");

// execute the searchCollection results = searchService.executeSearch(criteria);

// set the results in "request scope"context.getRequestScope().put("results", results);

// return "success"return success();

}

public Event someOtherRelatedActionMethod(RequestContext context) {...return success();

}

public Event yetAnotherRelatedActionMethod(RequestContext context) {...return success();

Flow definition

Spring Web Flow Version 1.0.5 32

Page 35: Spring Webflow Reference

}}

As you can see, this allows you to define one to many action methods per Action class. With this approach,there are two requirements:

1. Your Action class must extend from org.springframework.webflow.MultiAction, or another class thatextends from MultiAction. The multi action cares for the action method dispatch that is based on thevalue of the method property.

2. Each action method must conform to the signature illustrated above: public Event

${method}(RequestContext) { ... }

MultiActions are useful for centralizing command logic on a per-flow definition basis, as a flow definitiontypically carries out execution of a single application use case.

2.6.2.7. ActionState API - multi action

The following example constructs the equivalent action state definition using the FlowBuilder API:

public class SearchFlowBuilder extends AbstractFlowBuilder {public void buildStates() {...addActionState("executeSearch", invoke("executeSearch", action("searchAction")),

transition(on("success"), to("displayResults")));...

}}

2.6.2.8. ActionState XML - bean action

The next example constructs an ActionState definition from XML that executes a single method on a PlainOld Java Object (POJO) and then responds to the result:

<?xml version="1.0" encoding="UTF-8"?><flow xmlns="http://www.springframework.org/schema/webflow"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="

http://www.springframework.org/schema/webflowhttp://www.springframework.org/schema/webflow/spring-webflow-1.0.xsd">

<start-state idref="executeSearch"/>

<action-state id="executeSearch"><bean-action bean="searchService" method="executeSearch">

<method-arguments><argument expression="${flowScope.criteria}"/>

</method-arguments><method-result name="results"/>

</bean-action><transition on="success" to="displayResults"/>

</action-state>

...

</flow>

This state definition reads "when the executeSearch state is entered, call the executeSearch method on thesearchService passing it the object indexed by name criteria in flowScope. On successful execution, expose

Flow definition

Spring Web Flow Version 1.0.5 33

Page 36: Spring Webflow Reference

the method return value in the default scope (request) under the name results and transition to thedisplayResults state."

In this example the referenced bean searchService would be your application object, typically a transactionalbusiness service. Such a service implementation must have defined the the Collection

executeSearch(SearchCriteria) method, typically by implementing a service interface:

public interface SearchService {public Collection executeSearch(SearchCriteria criteria);

}

With this approach there are no requirements on the signature of the methods that carry out action execution,nor is there any requirement to extend from a Web Flow specific base class. Basically, you are not required towrite a custom Action implementation at all--you simply instruct Spring Web Flow to call your businessmethods directly. The need for custom "glue code" to bind your web-tier to your middle-tier is eliminated.

Spring Web Flow achieves this by automatically adapting the method on your existing application object to theAction interface and caring for exposing any return value in the correct scope.

This adaption process is shown graphically below:

Bean->Action adapter

2.6.2.9. ActionState XML - decision bean action

The following example constructs an ActionState from XML that executes an action whose execution resultforms the basis for the transition decision:

<?xml version="1.0" encoding="UTF-8"?><flow xmlns="http://www.springframework.org/schema/webflow"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="

http://www.springframework.org/schema/webflowhttp://www.springframework.org/schema/webflow/spring-webflow-1.0.xsd">

Flow definition

Spring Web Flow Version 1.0.5 34

Page 37: Spring Webflow Reference

...

<action-state id="shippingRequired"><bean-action bean="shippingService" method="isShippingRequired">

<method-arguments><argument expression="${flowScope.purchase}"/>

</method-arguments></bean-action><transition on="yes" to="enterShippingDetails"/><transition on="no" to="placeOrder"/>

</action-state>

...

</flow>

This state definition reads "if the isShippingRequired method on the shippingService returns true, transitionto the enterShippingDetails state, otherwise transition to the placeOrder state."

Note

Note how the boolean return value of the isShippingRequired method is converted to the eventidentifiers yes or no.

This conversion process is handled by the action adapter responsible for adapting the method on yourapplication object to the org.springframework.webflow.execution.Action interface. By default, this adapterapplies a number of rules for creating a result event from a method return value.

These conversion rules are:

Table 2.11. Default method return value to Event conversion rules

Return type Event identifier

boolean yes or no

java.lang.Enum this.name()

org.springframework.core.enum.LabeledEnum this.getLabel()

org.springframework.webflow.execution.Event this.getId()

java.lang.String the string

any other type success

You may customize these default conversion policies by setting a custom ResultEventFactory instance on thebean invoking action performing the adaption. Consult the JavaDoc documentation for more details on how todo this.

2.6.2.10. ActionState XML - decision bean action with enum return value

The following example constructs an ActionState from XML that executes a action that invokes a method onan application object that returns a java.lang.Enum:

<?xml version="1.0" encoding="UTF-8"?><flow xmlns="http://www.springframework.org/schema/webflow"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="

Flow definition

Spring Web Flow Version 1.0.5 35

Page 38: Spring Webflow Reference

http://www.springframework.org/schema/webflowhttp://www.springframework.org/schema/webflow/spring-webflow-1.0.xsd">

...

<action-state id="shippingRequired"><bean-action bean="shippingService" method="calculateShippingMethod"/>

<method-arguments><argument expression="${flowScope.order}"/>

</method-arguments></bean-action><transition on="BASIC" to="enterBasicShippingDetails"/><transition on="EXPRESS" to="enterExpressShippingDetails"/><transition on="NONE" to="placeOrder"/>

</action-state>

...

</flow>

This state definition reads "if the calculateShippingMethod method on the shippingService returns BASIC

for the current order, transition to the enterBasicShippingDetails state. If the return value is EXPRESS,transition to the enterExpressShippingDetails state. If the return value is NONE, transition to the placeOrder

state."

2.6.2.11. ActionState XML - evaluate action

The following example constructs an ActionState from XML that executes a action that evaluates anexpression against the flow request context and exposes the evaluation result:

<?xml version="1.0" encoding="UTF-8"?><flow xmlns="http://www.springframework.org/schema/webflow"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="

http://www.springframework.org/schema/webflowhttp://www.springframework.org/schema/webflow/spring-webflow-1.0.xsd">

<action-state id="getNextInterviewQuestion"><evaluate-action expression="flowScope.interview.nextQuestion()"/>

<evaluation-result name="question"/></evaluate-action><transition on="success" to="displayQuestion"/>

</action-state>

</flow>

This state definition reads "evaluate the flowScope.interview.nextQuestion() expression, and expose theresult under name question in the default scope."

The expression can evaluate any object traversable from the flow'sorg.springframework.webflow.execution.RequestContext. This example expression evaluates thenextQuestion method on the interview business object in flow scope.

2.6.2.12. ActionState XML - set action

The next example constructs an ActionState from XML that executes an action on a success transition thatsets an attribute in "flash scope":

<?xml version="1.0" encoding="UTF-8"?><flow xmlns="http://www.springframework.org/schema/webflow"

Flow definition

Spring Web Flow Version 1.0.5 36

Page 39: Spring Webflow Reference

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="

http://www.springframework.org/schema/webflowhttp://www.springframework.org/schema/webflow/spring-webflow-1.0.xsd">

<view-state id="selectFile" view="fileUploadForm"><transition on="submit" to="uploadFile"/>

</view-state>

<action-state id="uploadFile"><action bean="uploadAction" method="uploadFile"/><transition on="success" to="selectFile">

<set attribute="fileUploaded" scope="flash" value="true"/></transition>

</action-state>

</flow>

This flow definition reads "display the fileUploadForm. On form submit, invoke the uploadFile method onthe uploadAction. On success, allow the user to select another file to upload. Report that the last file wasuploaded successfully by setting the fileUploaded attribute in flash scope to true.

Note

Flash scoped attributes are preserved until the next user event is signaled into the flow execution.In this example, this means the fileUploaded attribute is preserved across a redirect to theselectFile view state and any subsequent browser refreshes. Only when the submit event issignaled will the flash scope be cleared.

2.6.2.13. When to use which kind of action?

Simple action, Multi action, bean action, evaluate action, set? When to use one or the other?

Table 2.12. Action implementation usage guidelines

Action type Usage scenario

Simple (extends AbstractAction) You have a specialized behavior that stands on its own; for creatinglightweight stubs or mocks for testing purposes.

MultiAction To group related command logic together. Particularly useful for whenthere are multiple related behaviors called by a flow.

Bean action When the logical behavior maps well to a method call on a service layerbean. When there is no "special" or exotic glue code required.

EvaluateAction When you need to invoke a bean in flow scope or evaluate any otherflow expression.

SetAction When you need to set an attribute in flow or other scope during thecourse of flow execution.

2.6.3. DecisionState

When entered, a decision state makes a flow routing decision. This process consists of:

Flow definition

Spring Web Flow Version 1.0.5 37

Page 40: Spring Webflow Reference

1. Evaluating one or more boolean expressions against the executing flow to decide what state to transition tonext.

The properties of a org.springframework.webflow.engine.DecisionState are summarized below:

Table 2.13. DecisionState properties

Property name Description Cardinality Default value

transitions(inherited fromTransitionableState)

The transitions that are evaluated on anevent occurrence that forms the basis forthe decision.

1..*

2.6.3.1. DecisionState XML - expression evaluation

The following example constructs a DecisionState from XML that evalutes a boolean expression to determinewhat transition to execute:

<?xml version="1.0" encoding="UTF-8"?><flow xmlns="http://www.springframework.org/schema/webflow"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="

http://www.springframework.org/schema/webflowhttp://www.springframework.org/schema/webflow/spring-webflow-1.0.xsd">

...

<decision-state id="shippingRequired"><if test="${flowScope.order.needsShipping}" then="enterShippingDetails" else="placeOrder"/>

</decision-state>

...

</flow>

This state definition reads "if the needsShipping property on the order object in flow scope is true, transitionto the enterShippingDetails state, otherwise transition to the placeOrder state."

Note

Caution: flow definitions should not be vehicles for business logic. In this case the decision madewas controller logic, reasoning on a pre-calculated value to decide what step of the flow totransition to next. That is the kind of logic that should be in a flow definition. In contrast, havingthe state itself embed the business rule defining how shipping status is calculated is a misuse.Instead, push such a calculation into business application code where it belongs and instruct theflow to invoke that code using an action.

2.6.4. SubflowState

When entered, a subflow state spawns another flow as a subflow.

Recall that a flow is a reusable, self-contained controller module. The ability for one flow to call another flowgives you the ability to compose independent modules together to create complex controller workflows. Anyflow can be used as subflow by any other flow, and there is a well-defined contract in play. Specifically:

Flow definition

Spring Web Flow Version 1.0.5 38

Page 41: Spring Webflow Reference

1. A Flow is an instance of org.springframework.webflow.engine.Flow.

2. A newly launched flow can be passed input attributes, which it may choose to map into its own localscope.

3. An ending flow can return output attributes. If the ended flow was launched as a subflow, the resumingparent flow may choose to map these output attributes into its own scope.

It is helpful to think of the process of calling a flow like calling a Java method. Flows can be passed inputarguments, and can produce return values just like methods can. Flows are more powerful because they arepotentially long-running, as they can span more than one request into the server.

The properties of a org.springframework.webflow.engine.SubflowState are summarized below:

Table 2.14. SubflowState properties

Property name Description Cardinality Default value

subflow The definition of the flow to be spawnedas a subflow.

1

attributeMapper The strategy responsible for mappinginput attributes to the subflow andmapping output attributes from thesubflow.

0..* Null

When a SubflowState is entered, the following behavior occurs:

1. The state first messages its attributeMapper, an instance oforg.springframework.webflow.engine.FlowAttributeMapper, to prepare a Map of input attributes topass to the subflow.

2. The subflow is spawned, passing the input attributes. When this happens, the parent flow suspends itself inthe subflow state until the subflow ends.

3. When the subflow ends, a result event is returned describing the flow outcome that occurred. The parentflow resumes back in the subflow state.

4. The resumed subflow state messages its attributeMapper to map any output attributes returned by thesubflow into flow scope, if necessary.

5. Finally, the resumed subflow state responds to the result event returned by the ended subflow by matchingand executing a state transition.

The constructs used in spawning a flow as a subflow are shown graphically below:

Flow definition

Spring Web Flow Version 1.0.5 39

Page 42: Spring Webflow Reference

SubflowState class diagram

2.6.4.1. SubflowState XML - with input attribute

The following example constructs an SubflowState from XML that spawns a shipping subflow:

<?xml version="1.0" encoding="UTF-8"?><flow xmlns="http://www.springframework.org/schema/webflow"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="

http://www.springframework.org/schema/webflowhttp://www.springframework.org/schema/webflow/spring-webflow-1.0.xsd">

...

<subflow-state id="enterShippingDetails" flow="shipping"><attribute-mapper>

<input-mapper><mapping source="flowScope.order.shipping" target="shipping"/>

</input-mapper></attribute-mapper><transition on="finish" to="placeOrder"/>

</subflow-state>

...

</flow>

This subflow state definition reads "spawn the shipping flow, passing it the value of the shipping property onthe order object in flow scope. When the shipping flow ends, respond to the finish result event bytransitioning to the placeOrder state."

Note

The inner structure and behavior of the shipping flow is fully encapsulated within its own flowdefinition. A flow calling another flow as a subflow can pass that flow input and capture its output,but it cannot see inside it. Flows are black boxes. Because any flow can be used as a subflow, it canbe reused in other contexts without change.

Flow definition

Spring Web Flow Version 1.0.5 40

Page 43: Spring Webflow Reference

2.6.4.2. SubflowState API - input attributes

The following illustrates the equivalent example using the FlowBuilder API:

public class OrderFlowBuilder extends AbstractFlowBuilder {public void buildStates() {

...addSubflowState("enterShippingDetails", flow("shipping"), shippingMapper(),

transition(on("finish"), to("placeOrder")));...

}

protected FlowAttributeMapper shippingMapper() {DefaultFlowAttributeMapper mapper = new DefaultFlowAttributeMapper();mapper.addInputMapping(mapping().source("flowScope.order.shipping").target("shipping").value());return mapper;

}}

2.6.4.3. Flow input mapping - input contract

Within a flow definition, input attributes can be obtained by configuring an input-mapper. Any input attributesmust be explictly mapped. The list of permitted input attributes defines the input contract for the flow.

Tip

If you think of calling a Flow as analogous to calling a Java method, it is helpful to think ofinput-attributes as analogous to method arguments.

<?xml version="1.0" encoding="UTF-8"?><flow xmlns="http://www.springframework.org/schema/webflow"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="

http://www.springframework.org/schema/webflowhttp://www.springframework.org/schema/webflow/spring-webflow-1.0.xsd">

<input-mapper><input-attribute name="shipping"/>

</input-mapper>

...

</flow>

This short-form input mapper declaration reads "when a new execution of this flow starts, map the providedshipping input attribute into flowScope under the name shipping."

Note

Had this input mapping not been defined the shipping attribute made available as input to this flowby a calling parent flow or external client would have been ignored.

2.6.5. EndState

When entered, an end state terminates a flow. A EndState represents exactly one logical flow outcome; forexample, "finish", or "cancel".

If the ended flow was acting as a top-level or root flow, the entire flow execution ends and cannot be resumed.

Flow definition

Spring Web Flow Version 1.0.5 41

Page 44: Spring Webflow Reference

In this case, the end state is responsible for making a ViewSelection that is the basis for the ending response(for example, a confirmation page, or a redirect request to another flow or an external URL).

If the ended flow was acting as a subflow, the spawned subflow session ends and the calling parent flowresumes by responding to the end result returned. In this case, the responsibility for any ViewSelection falls onthe parent flow.

Once a flow ends, any attributes in flow scope go out of scope immediately and become eligible for garbagecollection.

As outlined, an end state entered as part of a root flow messages its ViewSelector to make a ending viewselection. Typically this is a redirect-based ViewSelector, allowing for redirect after flow completion. An endstate entered as part of a subflow is not responsible for a view selection; this responsibility falls on the callingflow.

2.6.5.1. EndState result events

When a EndState is entered it terminates a flow and, if used as subflow, returns a result event the parent flowuses to drive a state transition from the calling subflow state. It is the end state's responsibility to create thisresult event which is the basis for communicating the logical flow outcome to callers.

By default, an EndState creates a result event with an identifier that matches the identifier of the end-state itself.For example, an end state with id finish returns a result event with id finish. Also, any attributes in flowscope that have been explicitly mapped as output attributes are returned as result event attributes. This allowsyou to return data along with the logical flow outcome.

Spring Web Flow gives you full control over the ending view selection strategy, as well as what flow attributesshould be exposed as output on a per EndState basis. These configurable properties are summarized below:

2.6.5.2. EndState Properties

Table 2.15. EndState properties

Property name Description Cardinality Default value

viewSelector The strategy that makes the ending viewselection when this state is entered and theflow is a root flow.

0..1 Null

outputMapper The service responsible for exposing flowoutput attributes, making those attributeseligible for output mapping by a callingflow.

0..1 None

2.6.5.3. EndState XML - redirect to flow after completion

The following example constructs an EndState from XML that terminates a shipping subflow and requests aredirect response to another flow:

<?xml version="1.0" encoding="UTF-8"?><flow xmlns="http://www.springframework.org/schema/webflow"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="

http://www.springframework.org/schema/webflowhttp://www.springframework.org/schema/webflow/spring-webflow-1.0.xsd">

Flow definition

Spring Web Flow Version 1.0.5 42

Page 45: Spring Webflow Reference

...

<end-state id="finish" view="flowRedirect:searchFlow"/>

</flow>

This end state definition reads "terminate the order flow, and redirect to a new execution of the searchFlow".

2.6.5.4. EndState XML - redirect after flow completion

The following example constructs an EndState from XML that terminates a shipping subflow and requests aredirect response to an external URL:

<?xml version="1.0" encoding="UTF-8"?><flow xmlns="http://www.springframework.org/schema/webflow"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="

http://www.springframework.org/schema/webflowhttp://www.springframework.org/schema/webflow/spring-webflow-1.0.xsd">

...

<end-state id="finish" view="externalRedirect:/orders/${flowScope.order.id}"/>

</flow>

This end state definition reads "terminate the order flow, and redirect to the URL returned by evaluating the/orders/${flowScope.order.id} expression."

This is an example of the familiar redirect after post pattern where after transaction completion a redirect isissued allowing the result of the transaction to be viewed (in this case using a REST-style URL).

2.6.5.5. EndState XML - flow output attribute

The following example constructs an EndState from XML that terminates a shipping subflow:

<?xml version="1.0" encoding="UTF-8"?><flow xmlns="http://www.springframework.org/schema/webflow"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="

http://www.springframework.org/schema/webflowhttp://www.springframework.org/schema/webflow/spring-webflow-1.0.xsd">

...

<end-state id="finish"><output-mapper>

<output-attribute name="shipping"/></output-mapper>

</end-state>

</flow>

This end state definition reads "terminate the shipping flow, and expose the shipping property in flow scopeas an output attribute with name shipping."

2.6.5.6. EndState API - flow output attribute

Flow definition

Spring Web Flow Version 1.0.5 43

Page 46: Spring Webflow Reference

The following illustrates the equivalent example using the FlowBuilder API:

public class ShippingFlowBuilder extends AbstractFlowBuilder {public void buildStates() {

...addEndState("finish",

new DefaultAttributeMapper().add(mapping().source("flowScope.shipping").target("shipping").value()

);}

}

Since this end-state does not make a view selection, it is expected this flow will be always used as a subflow.When this flow ends, the calling parent flow is expected to respond to the finish result, and may choose tomap the shipping output attribute into its own scope.

2.6.5.7. SubflowState XML - mapping an output attribute

The next example shows how a subflow-state can respond to the ending result of a subflow, and map subflowoutput attributes into its own scope:

<?xml version="1.0" encoding="UTF-8"?><flow xmlns="http://www.springframework.org/schema/webflow"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="

http://www.springframework.org/schema/webflowhttp://www.springframework.org/schema/webflow/spring-webflow-1.0.xsd">

...

<subflow-state id="enterShippingDetails" flow="shipping"><attribute-mapper>

<output-mapper><output-attribute name="shipping"/>

</output-mapper></attribute-mapper><transition on="finish" to="placeOrder"/>

</subflow-state>

...

</flow>

This subflow state definition reads "spawn the shipping flow as a subflow. When the shipping flow ends, mapthe shipping output attribute into flow scope under the name shipping, then respond to the finish resultevent by transitioning to the placeOrder state."

Note

Had this output mapping not been defined, the shipping attribute made available as output to thisflow by the ending subflow would have been ignored.

Flow definition

Spring Web Flow Version 1.0.5 44

Page 47: Spring Webflow Reference

Chapter 3. Flow execution

3.1. Introduction

Once a flow has been defined, any number of executions of it can be launched in parallel at runtime. Executionof a flow is carried out by a dedicated system that is based internally on a state machine that runs atop the JavaVM. As the life of a flow execution can span more than one request into the server, this system is alsoresponsible for persisting execution state across requests.

This chapter documents Spring Web Flow's flow execution system. You will learn the core constructs of thesystem and how to execute flows out-of-container within a JUnit test environment.

3.2. FlowExecution

A org.springframework.webflow.execution.FlowExecution is a runtime instantiation of a flow definition.Given a single FlowDefinition, any number of independent flow executions may be created. These executionsare typically created by a FlowExecutionFactory.

A flow execution carries out the execution of program instructions defined within its definition in response touser events.

It may be helpful to think of a flow definition as analagous to a Java Class, and a flow execution as analagousto an object instance of that Class. Signaling an execution event can be considered analagous to sending anobject a message.

3.2.1. Flow execution creation

FlowDefinition definition = ...FlowExecutionFactory factory = ...FlowExecution execution = factory.createFlowExecution(definition);

Once created, a new flow execution is initially inactive, waiting to be started. Once started, a flow executionbecomes active by entering its startState. From there, it continues executing until it enters a state where userinput is required to continue or it terminates.

3.2.2. Flow execution startup

MutableAttributeMap input = ...ExternalContext context = ...ViewSelection startingView = execution.start(input, context);

When a flow execution reaches a state where input is required to continue, it is said to have paused, where itwaits in that state for user input to be provided. After pausing, the ViewSelection returned is used to issue aresponse to the user that provides a vehicle for collecting the required user input.

User input is provided by signaling an event that resumes the flow execution by communicating what user

Spring Web Flow Version 1.0.5 45

Page 48: Spring Webflow Reference

action was taken. Attributes of the signal event request form the basis for user input. The flow executionresumes by consuming the event.

Once a flow execution has resumed, it continues executing until it again enters a state where more input isneeded or it terminates. Once a flow execution has terminated it becomes inactive and cannot be resumed.

3.2.3. Flow execution resume

ExternalContext context = ...ViewSelection nextView = execution.signalEvent("submit", context);if (execution.isActive()) {

// still active but paused} else {

// has ended}

3.2.4. Flow execution lifecycle

As outlined, a flow execution can go through a number of phases throughout its lifecycle; for example, created,active, paused, ended.

Spring Web Flow gives you the ability to observe the lifecycle of an executing flow by implementing aFlowExecutionListener.

The different phases of a flow execution are shown graphically below:

Flow execution lifecycle

Flow execution

Spring Web Flow Version 1.0.5 46

Page 49: Spring Webflow Reference

3.2.5. Flow execution properties

The Spring Web Flow flow execution implementation isorg.springframework.webflow.engine.impl.FlowExecutionImpl, typically created by aFlowExecutionImplFactory (a FlowExecutionFactory implementation). The configurable properties of thisflow execution implementation are summarized below:

Table 3.1. Flow Execution properties

Property name Description Cardinality Default value

definition The flow definition to be executed. 1

listeners The set of observers observing thelifecycle of this flow execution.

0..* Empty

attributes Global system attributes that can be usedto affect flow execution behavior

0..* Empty

The configurable constructs related to flow execution are shown graphically below:

Flow execution

3.2.6. Flow execution impl creation

FlowExecutionFactory factory = new FlowExecutionImplFactory();factory.setExecutionListeners(...);factory.setExecutionAttributes(...);FlowExecution execution = factory.createFlowExecution(definition);

Flow execution

Spring Web Flow Version 1.0.5 47

Page 50: Spring Webflow Reference

3.3. Flow execution context

Once created, a flow execution, representing the state of a flow at a point in time, maintains contextual stateabout itself that can be reasoned upon by clients. In addition, a flow execution exposes several data structures,called scopes, that allow clients to set arbitrary attributes that are managed by the execution.

The contextual properties associated with a flow execution are summarized below:

Table 3.2. Flow Execution Context properties

Property name Description Cardinality Default value

active A flag indicating if the flow execution isactive. An inactive flow execution haseither ended or has never been started.

1

definition The definition of the flow execution. Theflow definition serves as the blueprint forthe program. It may be helpful to think of aflow definition as like a Class and a flowexecution as like an instance of thatClass. This method may always be safelycalled.

1

activeSession The active flow session, tracking the flowthat is currently executing and what state itis in. The active session can change overthe life of the flow execution because aflow can spawn another flow as a subflow.This property can only be queried whilethe flow execution is active.

1

conversationScope A data map that forms the basis for"conversation scope". Arbitrary attributesplaced in this map will be retained for thelife of the flow execution and correspondto the length of the logical conversation.This map is shared by all flow sessions.

1

As a flow execution is manipulated by clients its contextual state changes. Consider how contextual state iseffected when the following events occur:

Table 3.3. An ordered set of events and their effects on flow execution context

Flow Execution Event Active? Value of the activeSession property

created false Throws an IllegalStateException

started true A FlowSession whose definition is the top-levelflow definition and whose state is the definition'sstart state.

state entered true A FlowSession whose definition is the top-level

Flow execution

Spring Web Flow Version 1.0.5 48

Page 51: Spring Webflow Reference

Flow Execution Event Active? Value of the activeSession property

flow definition and whose state is the newly enteredstate.

subflow spawned true A FlowSession whose definition is the subflowdefinition and whose state is the subflow's startstate.

subflow ended true A FlowSession whose definition is back to thetop-level flow definition and whose state is theresuming state.

ended false Throws an IllegalStateException

As you can see, the activeSession of a flow execution changes when a subflow is spawned. Each flowexecution maintains a stack of flow sessions, where each flow session represents a spawned instance of a flowdefinition. When a flow execution starts, the session stack initially consists of one (1) entry, an instance dubbedthe root session. When a subflow is spawned, the stack increases to two (2) entries. When the subflow ends, thestack decreases back to one (1) entry. The active session is always the session at the top of the stack.

The contextual properties associated with a FlowSession are summarized below:

Table 3.4. Flow Session properties

Property name Description Cardinality Default value

definition The definition of the flow the session is aninstance of.

1

state The current state of the session. 1

status A status indicator describing what thesession is currently doing.

1

scope A data map that forms the basis for flowscope. Arbitrary attributes placed in thismap will be retained for the scope of theflow session. This map is local to thesession.

1

flashMap A data map that forms the basis for flashscope. Attributes placed in this map willbe retained until the next external userevent is signaled in the session.

1

The following graphic illustrates an example flow execution context and flow session stack:

Flow execution

Spring Web Flow Version 1.0.5 49

Page 52: Spring Webflow Reference

Flow execution context

In this illustration, a flow execution has been created for the Book Flight flow. The execution is currentlyactive and the activeSession indicates it is in the Display Seating Chart state of the Assign Seats flow,which was spawned as a subflow from the Enter Seat Assignments state.

Note

Note how the active session status is paused, indicating the flow execution is currently waiting foruser input to be provided to continue. In this case, it is expected the user will choose a seat for theirflight.

3.4. Flow execution scopes

As alluded to, a flow execution manages several containers called scopes, which allow arbitrary attributes to bestored for a period of time. There are four scope types, each with different storage management semantics:

Table 3.5. Flow execution scope types

Scope type name Management Semantics

request Eligible for garbage collection when a single call into the flow executioncompletes.

flash Cleared when the next user event is signaled into the flow session;

Flow execution

Spring Web Flow Version 1.0.5 50

Page 53: Spring Webflow Reference

Scope type name Management Semantics

eligible for garbage collection when the flow session ends.

flow Eligible for garbage collection when the flow session ends.

conversation Eligible for garbage collection when the root session of the governingflow execution (logical conversation) ends.

3.5. Flow execution testing

Spring Web Flow provides support within the org.springframework.webflow.test package for testing flowexecutions with JUnit. This support is provided as convenience but is entirely optional, as a flow execution isinstantiable in any environment with the standard Java new operator.

The general strategy for testing flows follows:

1. Your own implementations of definitional artifacts used by a flow such as actions, attribute mappers, andexception handlers should be unit tested in isolation. Spring Web Flow ships convenient stubs to assistwith this, for instance MockRequestContext.

2. The execution of a flow should be tested as part of a system integration test. Such a test should exercise allpossible paths of the flow, asserting that the flow responds to events as expected.

Note

A flow execution integration test typically selects mock or stub implementations of applicationservices called by the flow, though it may also exercise production implementations. Both areuseful, supported system test configurations.

3.5.1. Flow execution test example

To help illustrate testing a flow execution, first consider the following flow definition to search a phonebookfor contacts:

Flow execution

Spring Web Flow Version 1.0.5 51

Page 54: Spring Webflow Reference

Phonebook Search Flow - State Diagram

The corresponding XML-based flow definition implementation:

<?xml version="1.0" encoding="UTF-8"?><flow xmlns="http://www.springframework.org/schema/webflow"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="

http://www.springframework.org/schema/webflowhttp://www.springframework.org/schema/webflow/spring-webflow-1.0.xsd">

<start-state idref="enterCriteria"/>

<view-state id="enterCriteria" view="searchCriteria"><render-actions>

<action bean="formAction" method="setupForm"/></render-actions><transition on="search" to="displayResults">

<action bean="formAction" method="bindAndValidate"/></transition>

</view-state>

<view-state id="displayResults" view="searchResults"><render-actions>

<bean-action bean="phonebook" method="search"><method-arguments>

<argument expression="flowScope.searchCriteria"/></method-arguments><method-result name="results"/>

</bean-action></render-actions><transition on="newSearch" to="enterCriteria"/><transition on="select" to="browseDetails"/>

</view-state>

<subflow-state id="browseDetails" flow="detail-flow"><attribute-mapper>

<input-mapper><mapping source="requestParameters.id" target="id" from="string" to="long"/>

</input-mapper></attribute-mapper><transition on="finish" to="displayResults"/>

</subflow-state>

</flow>

Flow execution

Spring Web Flow Version 1.0.5 52

Page 55: Spring Webflow Reference

Above you see a flow with three (3) states that execute these behaviors, respectively:

1. The first state enterCriteria displays a search criteria form so the user can enter who he or she wishes tosearch for.

2. On form submit and successful data binding and validation, the search is executed. After search executiona results view is displayed.

3. From the results view, the user may select a result they wish to browse additional details on or they mayrequest a new search. On select, the "detail" flow is spawned and when it finishes the search is re-executedand it's results redisplayed.

From this behavior narrative the following assertable test scenarios can be extracted:

1. That when a flow execution starts, it enters the enterCriteria state and makes a searchCriteria viewselection containing a form object to be used as the basis for form field population.

2. That on submit with valid input, the search is executed and a searchResults view selection is made.

3. That on submit with invalid input, the searchCriteria view is reselected.

4. That on newSearch, the searchCriteria view is selected.

5. That on select, the detail flow is spawned and passed the id of the selected result as expected.

To assist with writing these assertions, Spring Web Flow ships with JUnit-based flow execution test supportwithin the org.springframwork.webflow.test package. These base test classes are indicated below:

Table 3.6. Flow execution test support hierarchy

Class name Description

AbstractFlowExecutionTests The most generic base class for flow execution tests.

AbstractExternalizedFlowExecutionTests The base class for flow execution tests whose flow is definedwithin an externalized resource, such as a file.

AbstractXmlFlowExecutionTests The base class for flow execution tests whose flow is definedwithin an externalized XML resource.

The completed test for this example extending AbstractXmlFlowExecutionTests is shown below:

public class SearchFlowExecutionTests extends AbstractXmlFlowExecutionTests {

public void testStartFlow() {ApplicationView view = applicationView(startFlow());assertCurrentStateEquals("enterCriteria");assertViewNameEquals("searchCriteria", view);assertModelAttributeNotNull("searchCriteria", view);

}

public void testCriteriaSubmitSuccess() {startFlow();MockParameterMap parameters = new MockParameterMap();parameters.put("firstName", "Keith");parameters.put("lastName", "Donald");ApplicationView view = applicationView(signalEvent("search", parameters));

Flow execution

Spring Web Flow Version 1.0.5 53

Page 56: Spring Webflow Reference

assertCurrentStateEquals("displayResults");assertViewNameEquals("searchResults", view);assertModelAttributeCollectionSize(1, "results", view);

}

public void testCriteriaSubmitError() {startFlow();signalEvent("search");assertCurrentStateEquals("enterCriteria");

}

public void testNewSearch() {testCriteriaSubmitSuccess();ApplicationView view = applicationView(signalEvent("newSearch"));assertCurrentStateEquals("enterCriteria");assertViewNameEquals("searchCriteria", view);

}

public void testSelectValidResult() {testCriteriaSubmitSuccess();MockParameterMap parameters = new MockParameterMap();parameters.put("id", "1");ApplicationView view = applicationView(signalEvent("select", parameters));assertCurrentStateEquals("displayResults");assertViewNameEquals("searchResults", view);assertModelAttributeCollectionSize(1, "results", view);

}

@Overrideprotected FlowDefinitionResource getFlowDefinitionResource() {

return createFlowDefinitionResource("src/main/webapp/WEB-INF/flows/search-flow.xml");}

@Overrideprotected void registerMockServices(MockFlowServiceLocator serviceRegistry) {

Flow mockDetailFlow = new Flow("detail-flow");mockDetailFlow.setInputMapper(new AttributeMapper() {

public void map(Object source, Object target, Map context) {assertEquals("id of value 1 not provided as input by calling search flow", new Long(1), ((AttributeMap)source).get("id"));

}});// test responding to finish resultnew EndState(mockDetailFlow, "finish");

serviceRegistry.registerSubflow(mockDetailFlow);serviceRegistry.registerBean("phonebook", new ArrayListPhoneBook());

}}

With a well-written flow execution test passing that exercises the scenarios possible for your flow, you haveconcrete evidence the flow will execute as expected when deployed into a container.

Go for Green

3.5.2. Execution unit testing vs. full-blown system testing

The previous example shows how to test a flow execution in relative isolation with a mock service layer andmock subflows. Flow execution testing against a real service-layer and real subflows is also supported.

Flow execution

Spring Web Flow Version 1.0.5 54

Page 57: Spring Webflow Reference

The next example shows how the createFlowServiceLocator method can be overridden to create theservice-layer using a Spring application context:

public class SearchFlowExecutionTests extends AbstractXmlFlowExecutionTests {

...

@Overrideprotected FlowDefinitionResource getFlowDefinitionResource() {

return createFlowDefinitionResource("src/main/webapp/WEB-INF/flows/search-flow.xml");}

@Overrideprotected FlowServiceLocator createFlowServiceLocator() {

// create a context to host our middle tier servicesApplicationContext context =

new ClassPathXmlApplicationContext(new String[] {"classpath:service-layer-config.xml","classpath:data-access-layer-config.xml"

});

// create a registry for our flow definitions being testedFlowDefinitionRegistry registry = new FlowDefinitionRegistryImpl();

// initialize the service locatorDefaultFlowServiceLocator locator = new DefaultFlowServiceLocator(registry, context);

// perform subflow definition registration with the help of a registrarXmlFlowRegistrar registrar = new XmlFlowRegistrar(locator);registrar.addResource(createFlowDefinitionResource("/WEB-INF/flows/search-flow.xml"));registrar.addResource(createFlowDefinitionResource("/WEB-INF/flows/detail-flow.xml"));registrar.registerFlowDefinitions(registry);

return locator;}

}

Flow execution

Spring Web Flow Version 1.0.5 55

Page 58: Spring Webflow Reference

Chapter 4. Flow execution repositories

4.1. Introduction

A flow execution represents an executing flow at a point in time. At runtime there can be any number of flowexecutions active in parallel. A single user can even have multiple executions active at the same time (forexample, when a user is operating multiple windows or tabs within their browser).

Many of these flow executions span multiple requests into the server and therefore must be saved so they canbe resumed on subsequent requests. This presents technical challenges, as there must exist a stable mechanismfor a new request to be associated with an existing execution in the view state that matches what the userexpects. This problem is more difficult when you consider that many applications require use of browsernavigational buttons, and use of these buttons involves updating local history without notifying the server.

The problem of flow execution persistence is addressed by Spring Web Flow's flow execution repositorysubsystem. In this chapter, you will learn how to use the system to manage the storage of active webconversations in a stable manner.

4.2. Repository architecture overview

Recall the following bullet points noting what happens when a flow execution enters a ViewState:

1. When a flow execution reaches a ViewState it is said to have paused, where it waits in that state for userinput to be provided so it can continue. After pausing, the ViewSelection returned is used to issue aresponse to the user that provides a vehicle for collecting the required user input.

2. User input is provided by signaling an event that resumes the flow execution in the paused view state. Theinput event communicates what user action was taken.

Each time an active flow execution is paused, it is saved out to a repository. When the next request comes infor that flow execution, it is restored from the repository, resumed, and continued. This process continues untilthe flow execution reaches an end state, at which time it is removed from the repository.

This process is demonstrated over the next two graphics:

Spring Web Flow Version 1.0.5 56

Page 59: Spring Webflow Reference

Request one (1) - Paused flow execution persistence

Request two (2) - Paused flow execution restoration, removal on end

4.3. Flow execution identity

When a new flow execution is created, it marks the start of a new conversation between a browser and theserver. A new flow execution that is still active after startup processing indicates the start of a conversation thatwill span more than one request and needs to be persisted. When this is the case, that flow execution is assignedan persistent identifer by the repository. By default, the structure of this identifier consists of a two-partcomposite key. This key is used by clients to restore the flow execution on subsequent requests.

4.3.1. Conversation identifier

Flow execution repositories

Spring Web Flow Version 1.0.5 57

Page 60: Spring Webflow Reference

The first part of a flow execution's persistent identity is a unique conversation identifier. This serves as anindex into the logical conversation between the browser and the server that has just started.

4.3.2. Continuation identifier

The second part of a flow execution's persistent identity is a continuation identifier. This identifier serves as anindex into a flow execution representing the state of the conversation at this point in time.

4.3.3. Flow execution key

Together the conversation id plus the continuation id make up the unique two-part flow execution key thatidentifies a state of a conversation at a point in time. By submitting this key in a subsequent request, a browsercan restore the conversation at that point and continue from there.

So on a subsequent request, the conversation is resumed by restoring a flow execution from the repository usingthe two-part key. After event processing, if the flow execution is still active it is saved back out to therepository. At this time a new flow execution key is generated. By default, that key retains the sameconversation identifier, as the same logical conversation is in progress; however the continuation identifierchanges to provide an index into the state of the flow execution at this new point in time.

By submitting this new key in a subsequent request, a browser can restore the conversation at that point andcontinue from there. This process continues until a flow execution reaches an end state during event processingsignaling the end of the conversation.

4.4. Conversation ending

When a flow execution reaches an end state it terminates. If the flow execution was associated with a logicalconversation that spanned more than on request, it is removed from the repository. More specifically, the entireconversation is ended, resulting in any flow execution continuations associated with the conversation beingpurged.

Once a conversation has ended, the conversation identifier is no longer valid and can never be used again.

4.5. Flow execution repository implementations

The next section looks at the repository implementations that are available for use with Spring Web Flowout-of-the-box.

4.5.1. Simple flow execution repository

The simplest possible repository (SimpleFlowExecutionRepository). This repository stores exactly one flowexecution instance per conversation in the user's session, invalidating it when its end state is reached. Thisrepository implementation has been designed with minimal storage overhead in mind.

Note

It is important to understand that use of this repository consistently prevents duplicate submissionwhen using the back button. If you attempt to go back and resubmit, the continuation id stored inyour browser history will not match the current continuation id needed to access the flow execution

Flow execution repositories

Spring Web Flow Version 1.0.5 58

Page 61: Spring Webflow Reference

and access will be disallowed.

Note

This repository implementation should generally be used when you do not have to support browsernavigational button use; for example, when you lock down the browser and require that allnavigation events to be routed through Spring Web Flow.

4.5.2. Continuation flow execution repository

This repository (ContinuationFlowExecutionRepository) stores one to many flow execution instances perconversation in the user's session, where each flow execution represents a paused and restorable state of theconversation at a point in time. This repository implementation is considerably more flexible than the simpleone, but incurs more storage overhead.

Note

It is important to understand that use of this repository allows resubmission when using the backbutton. If you attempt to go back and resubmit while the conversation is active, the continuation idstored in your browser history will match the continuation id of a previous flow execution in therepository. Access to that flow execution representing the state of the conversation at that point intime will be granted.

Like the simple implementation, this repository implementation provides support for conversation invalidationafter completion where once a logical conversation completes (by one of its FlowExecutions reaching an endstate), the entire conversation is invalidated. This prevents the possibility of resubmission after completion.

This repository is more elaborate than the default repository, offering more power (by enabling multiplecontinuations to exist per conversation), but incurring more storage overhead. This repository implementationshould be considered when you do have to support browser navigational button use. This implementation is thedefault.

4.5.3. Client continuation flow execution repository

This repository is entirely stateless and its use entails no server-side state(ClientContinuationFlowExecutionRepository).

This is achieved by encoding a serialized flow execution directly into the flow execution continuation key thatis sent in the response.

When asked to load a flow execution by its key on a subsequent request, this repository decodes anddeserializes the flow execution, restoring it to the state it was in when it was serialized.

Note

This repository implementation does not currently support conversation invalidation aftercompletion, as this capability requires tracking active conversations using some form of centralizedstorage, like a database table.

Note

Storing state (a flow execution continuation) on the client entails a certain security risk that shouldbe evaluated. Furthermore, it puts practical constraints on the size of the flow execution.

Flow execution repositories

Spring Web Flow Version 1.0.5 59

Page 62: Spring Webflow Reference

Chapter 5. Flow executors

5.1. Introduction

Flow executors are the highest-level entry points into the Spring Web Flow system, responsible for driving theexecution of flows across a variety of environments.

In this chapter, you will learn how to execute flows within Spring MVC, Struts, and Java Server Faces (JSF)based applications.

5.2. FlowExecutor

org.springframework.webflow.executor.FlowExecutor is the central facade interface external systems useto drive the execution of flows. This facade acts as a simple, convenient service entry-point into the SpringWeb Flow system that is reusable across environments.

The FlowExecutor interface is shown below:

public interface FlowExecutor {ResponseInstruction launch(String flowDefinitionId, ExternalContext context);ResponseInstruction resume(String flowExecutionKey, String eventId, ExternalContext context);ResponseInstruction refresh(String flowExecutionKey, ExternalContext context);

}

As you can see there are three central use-cases fulfilled by this interface:

1. Launch (start) a new execution of a flow definition.

2. Resume a paused flow execution by signaling an event against its current state.

3. Request that the last response issued by a flow execution be re-issued. Unlike start and signalEvent, therefresh operation is an idempotent operation that does not change the state of a flow execution.

Each operation accepts an ExternalContext that provides normalized access to properties of an externalsystem that has called into Spring Web Flow. This context allows access to environment-specific requestparameters as well as externally-managed request, session, and application-level attributes.

Each operation returns a ResponseInstruction, which the calling system is expected to use to issue a suitableresponse.

These relationships are shown graphically below:

Spring Web Flow Version 1.0.5 60

Page 63: Spring Webflow Reference

Flow executor

As you can see, an ExternalContext implementation exists for each of the environments Spring Web Flowsupports. If a flow artifact such as an Action needs to access native constructs of the calling environment it candowncast a context to its specific implementation. The need for such downcasting is considered a corner case.

5.2.1. FlowExecutorImpl

The default executor implementation is org.springframework.webflow.executor.FlowExecutorImpl. Itallows for configuration of a FlowDefinitionLocator responsible for loading the flow definitions to execute,as well as the FlowExecutionRepository strategy responsible for persisting flow executions that remain activebeyond a single request into the server.

The configurable FlowExecutorImpl properties are shown below:

Table 5.1. FlowExecutorImpl properties

Property name Description Cardinality

definitionLocator The service for loading flow definitions to beexecuted, typically a FlowDefinitionRegistry

1

executionFactory The factory for creating new flow executions. 1

executionRepository The repository for saving and loading persistent(paused) flow executions

1

5.2.2. A typical flow executor configuration with Spring 2.0

Flow executors

Spring Web Flow Version 1.0.5 61

Page 64: Spring Webflow Reference

<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:flow="http://www.springframework.org/schema/webflow-config"xsi:schemaLocation="

http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans-2.0.xsdhttp://www.springframework.org/schema/webflow-confighttp://www.springframework.org/schema/webflow-config/spring-webflow-config-1.0.xsd">

<!-- Launches new flow executions and resumes existing executions. --><flow:executor id="flowExecutor" registry-ref="flowRegistry"/>

<!-- Creates the registry of flow definitions for this application --><flow:registry id="flowRegistry">

<flow:location path="/WEB-INF/flows/**/*-flow.xml"/></flow:registry>

</beans>

This instructs Spring to create a flow executor that can execute all XML-based flow definitions containedwithin the /WEB-INF/flows directory. The default flow execution repository, continuation, is used.

5.2.3. A flow executor using a simple execution repository

<flow:executor id="flowExecutor" registry-ref="flowRegistry" repository-type="simple"/>

This executor is configured with a simple repository that manages execution state in the user session.

5.2.4. A flow executor using a client-side continuation-based executionrepository

<flow:executor id="flowExecutor" registry-ref="flowRegistry" repository-type="client"/>

This executor is configured with a continuation-based repository that serializes continuation state to the clientusing no server-side state.

5.2.5. A flow executor using a single key execution repository

<flow:executor id="flowExecutor" registry-ref="flowRegistry" repository-type="singleKey"/>>

This executor is configured with a simple repository that assigns a single flow execution key per conversation.The key, once assigned, never changes for the duration of the conversation.

5.2.6. A flow executor setting custom conversation management attributes

<flow:executor id="flowExecutor" registry-ref="flowRegistry"><flow:repository type="continuation" max-conversations="5" max-continuations="30" conversation-manager-ref="conversationManager"/>

</flow:executor>

Flow executors

Spring Web Flow Version 1.0.5 62

Page 65: Spring Webflow Reference

<bean id="conversationManager" class="example.MyCustomConversationalStateManager"/>

This executor is configured with a continuation repository configured with custom settings for:

1. The maximum number of active conversations per user session (5)

2. The maximum number of restorable flow execution snapshots (continuations) per conversation (30)

3. Where conversational state will be stored (via a custom conversationManager)

The flow:repository child element is the more flexible form for configuring the flow execution repository.Use it or the convenient repository-type attribute, not both.

5.2.7. A flow executor setting system execution attributes

<flow:executor id="flowExecutor" registry-ref="flowRegistry" repository-type="continuation"><flow:execution-attributes>

<flow:alwaysRedirectOnPause value="false"/><flow:attribute name="foo" value="bar"/>

</flow:execution-attributes></flow-executor>

This executor is configured to set two flow execution system attributes alwaysRedirectOnPause=false andfoo=bar.

Note

The alwaysRedirectOnPause attribute determines if a flow execution redirect occurs automaticallyeach time an execution pauses (automated POST+REDIRECT+GET behavior). Setting this attribute tofalse will disable the default 'true' behavior.

5.2.8. A flow executor setting custom execution listeners

<flow:executor id="flowExecutor" registry-ref="flowRegistry" repository-type="continuation"><flow:execution-listeners>

<flow:listener ref="listener" criteria="order-flow"/></flow:execution-listeners>

</flow-executor>

<!-- A FlowExecutionListener to observe the lifecycle of order-flow executions --><bean id="listener" class="example.OrderFlowExecutionListener"/>

This executor is configured to apply the execution listener to the "order-flow".

5.2.9. A Spring 1.2 compatible flow executor configuration

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"

"http://www.springframework.org/dtd/spring-beans.dtd"><beans>

<!-- Launches new flow executions and resumes existing executions: Spring 1.2 config version -->

Flow executors

Spring Web Flow Version 1.0.5 63

Page 66: Spring Webflow Reference

<bean id="flowExecutor" class="org.springframework.webflow.config.FlowExecutorFactoryBean"><property name="definitionLocator" ref="flowRegistry"/><property name="executionAttributes">

<map><entry key="alwaysRedirectOnPause">

<value type="java.lang.Boolean">false</value></entry>

</map></property><property name="repositoryType" value="CONTINUATION"/>

</bean>

<!-- Creates the registry of flow definitions for this application: Spring 1.2 config version --><bean id="flowRegistry"

class="org.springframework.webflow.engine.builder.xml.XmlFlowRegistryFactoryBean"><property name="flowLocations">

<list><value>/WEB-INF/flows/**/*-flow.xml</value>

</list></property>

</bean>

</beans>

This achieves similar semantics as the Spring 2.0 version above. The 2.0 version is more concise, providesstronger validation, and encapsulates internal details such as FactoryBean class names. The 1.2 version isSpring 1.2 or > compatible and digestable by Spring IDE 1.3.

5.3. Spring MVC integration

Spring Web Flow integrates with both Servlet and Portlet MVC which ship with the core Spring Framework.Use of Portlet MVC requires Spring 2.0.

For both Servlet and Portlet MVC, a FlowController acts as an adapter between Spring MVC and Spring WebFlow. As an adapter, this controller has knowledge of both systems and delegates to a flow executor for drivingthe execution of flows. One controller typically executes all flows of an application, relying onparameterization to determine what flow to launch or what flow execution to resume.

5.3.1. A single flow controller executing all flows in a Servlet MVCenvironment

<bean name="/flowController.htm" class="org.springframework.webflow.executor.mvc.FlowController"><property name="flowExecutor" ref="flowExecutor"/>

</bean>

This controller, exported at the context-relative /flowController.htm URL, delegates to the configured flowexecutor for driving flow executions in a Spring Servlet MVC environment.

5.3.2. A single portlet flow controller executing a flow within a Portlet

<bean id="portletModeControllerMapping"class="org.springframework.web.portlet.handler.PortletModeHandlerMapping">

<property name="portletModeMap"><map>

<entry key="view" value-ref="flowController"/></map>

</property>

Flow executors

Spring Web Flow Version 1.0.5 64

Page 67: Spring Webflow Reference

</bean>

<bean id="flowController" class="org.springframework.webflow.executor.mvc.PortletFlowController"><property name="flowExecutor" ref="flowExecutor"/><property name="defaultFlowId" ref="search-flow"/>

</bean>

This controller, exported for access with the configured portlet mode, delegates to the configured flow executorfor driving flow executions in a Spring Portlet MVC environment (by default, an execution of the search-flow

will be launched).

5.4. Flow executor parameterization

Spring Web Flow allows for full control over how flow executor method arguments such as theflowDefinitionId, flowExecutionKey, and eventId are extracted from an incoming controller request withthe org.springframework.webflow.executor.support.FlowExecutorArgumentExtractor strategy.

The next several examples illustrate strategies for parameterizing flow controllers from the browser to launchand resume flow executions:

5.4.1. Request parameter-based flow executor argument extraction

The default executor argument extractor strategy is request-parameter based. The default request parametersare:

Table 5.2. Extractor request parameter names

Parameter name Description

_flowId The flow definition id, needed to launch a new flow execution.

_flowExecutionKey The flow execution key, needed to resume and refresh an existing flowexecution.

_eventId The id of an event that occured, needed to resume an existing flowexecution.

5.4.1.1. Launching a flow execution - parameter-style anchor

<a href="flowController.htm?_flowId=myflow">Launch My Flow</a>

5.4.1.2. Launching a flow execution - form

<form action="flowController.htm" method="post"><input type="submit" value="Launch My Flow"/><input type="hidden" name="_flowId" value="myflow">

</form>

Flow executors

Spring Web Flow Version 1.0.5 65

Page 68: Spring Webflow Reference

5.4.1.3. Resuming a flow execution - anchor

<a href="flowController.htm?_flowExecutionKey=${flowExecutionKey}&_eventId=submit">Submit

</a>

5.4.1.4. Resuming a flow execution - form

<form action="flowController.htm" method="post">...<input type="hidden" name="_flowExecutionKey" value="${flowExecutionKey}"><input type="hidden" name="_eventId" value="submit"/><input type="submit" class="button" value="Submit">

</form>

5.4.1.5. Resuming a flow execution - multiple form buttons

<form action="flowController.htm" method="post">...<input type="hidden" name="_flowExecutionKey" value="${flowExecutionKey}"><input type="submit" class="button" name="_eventId_submit" value="Submit"><input type="submit" class="button" name="_eventId_cancel" value="Cancel">

</form>

Note

In this case, the eventId is determined by parsing the name of the button that was pressed.

5.4.1.6. Refreshing a flow execution

<a href="flowController.htm?_flowExecutionKey=${flowExecutionKey}">Refresh</a>

5.4.2. Request path based flow executor argument extraction

The request-path based argument extractor strategy relies on executor arguments being path elements as muchas possible. This results in friendlier REST-style URLs such as http://host/app/myflow, instead ofhttp://host/app?_flowId=myflow.

5.4.2.1. A flow controller with a request-path based argument extractor

<bean name="/flowController.htm" class="org.springframework.webflow.executor.mvc.FlowController"><property name="flowExecutor" ref="flowExecutor"/><property name="argumentHandler">

<bean class="org.springframework.webflow.executor.support.RequestPathFlowExecutorArgumentHandler"/></property>

</bean>

5.4.2.2. Launching a flow execution - REST-style anchor

Flow executors

Spring Web Flow Version 1.0.5 66

Page 69: Spring Webflow Reference

<a href="flowController/myflow"/>Launch My Flow</a>

5.4.2.3. Resuming a flow execution - multiple form buttons

<form action="${flowExecutionKey}" method="post">...<input type="submit" class="button" name="_eventId_submit" value="Submit"><input type="submit" class="button" name="_eventId_cancel" value="Cancel">

</form>

5.4.2.4. Refreshing a flow execution

<a href="flowController/k/${flowExecutionKey}">Refresh</a>

5.5. Struts integration

Spring Web Flow integrates with Struts 1.x or >. The integration is very similiar to Spring MVC where a singlefront controller (FlowAction) drives the execution of all flows for the application by delegating to a configuredflow executor.

5.5.1. A single flow action executing all flows

<form-beans><form-bean name="actionForm" type="org.springframework.web.struts.SpringBindingActionForm"/>

</form-beans>

<action-mappings><action path="/flowAction" name="actionForm" scope="request"

type="org.springframework.webflow.executor.struts.FlowAction"/></action-mappings>

5.6. Java Server Faces (JSF) integration

Spring Web Flow provides strong integration with Java Server Faces (JSF). When used with JSF, Spring WebFlow takes responsibility for view navigation handling and managing model state, adding power and simplicityto JSF's default navigation system and object scopes. Plain JSF views and components continue to work just asbefore, and are able to participate in flows with full access to flow state. In addition, other view technologiessuch as Facelets continue to plug-in normally.

The JSF integration relies on custom implementations of core JSF artifacts such as the PhaseListener andNavigationHandler to drive the execution of flows. In addition, it relies on a custom VariableResolver to accessflow execution attributes from JSF components.

5.6.1. Adding Spring Web Flow extensions to faces-config.xml

Flow executors

Spring Web Flow Version 1.0.5 67

Page 70: Spring Webflow Reference

Using Spring Web Flow in a JSF environment requires adding these custom artifacts to the application'sfaces-config.xml file:

<faces-config><application>

<navigation-handler>org.springframework.webflow.executor.jsf.FlowNavigationHandler</navigation-handler><variable-resolver>org.springframework.webflow.executor.jsf.DelegatingFlowVariableResolver</variable-resolver>

</application>

<lifecycle><phase-listener>org.springframework.webflow.executor.jsf.FlowPhaseListener</phase-listener>

</lifecycle></faces-config>

The FlowPhaseListener is required to manage the overall flow execution lifecycle in a JSF environment. Ithandles launching new flows accessed by browsers via direct URLs, and also handles restoring flow executionson postback and browser refreshes.

The FlowNavigationHandler is required to continue a flow on an action outcome from a JSF viewparticipating in the flow. Outcome strings are treated as events signaled against the current view state of theflow execution automatically.

The DelegatingFlowVariableResolver resolves JSF a value binding expression like{#someBean.someProperty} to a flow execution attribute. This resolver searches flash, flow, and conversationscope in that order until it finds a match. If no match is found, this resolver delegates to the next resolver in thechain.

5.6.2. Configuring the Web Flow system

The artifacts defined in the faces-config.xml use Spring to access the Web Flow system configuration. Thisrequires a Spring Web Application Context to be bootstrapped using a ContextLoaderListener in the web.xmldeployment descriptor:

<context-param><param-name>contextConfigLocation</param-name><param-value>

/WEB-INF/webflow-config.xml</param-value>

</context-param>

<listener><listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>

</listener>

This context should contain the Web Flow system configuration. The example webflow-config.xml belowshows a typical Web Flow configuration for a JSF environment:

<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:flow="http://www.springframework.org/schema/webflow-config"xsi:schemaLocation="

http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans-2.0.xsdhttp://www.springframework.org/schema/webflow-confighttp://www.springframework.org/schema/webflow-config/spring-webflow-config-1.0.xsd">

<!-- Launches new flow executions and resumes existing executions. -->

Flow executors

Spring Web Flow Version 1.0.5 68

Page 71: Spring Webflow Reference

<flow:executor id="flowExecutor" registry-ref="flowRegistry"/>

<!-- Creates the registry of flow definitions for this application --><flow:registry id="flowRegistry">

<flow:location path="/WEB-INF/flows/**/*-flow.xml"/></flow:registry>

</beans>

A bean named flowExecutor must be configured and linked with a flow definition registry that contains theflows eligible for execution. Note the flowExecutor bean name is significant, as that is bean name the WebFlow JSF extensions will expect.

Any flow executor property such as the flow execution repository type is configurable here, consistent with theother environments Spring Web Flow supports.

5.6.3. Launching a flow execution - JSF command link component

Flows can be launched by firing JSF action outcomes that adhere to a special format:

<h:commandLink value="Go" action="flowId:myflow"/>

The command link above says launch 'myflow' when clicked. 'myflow' is expected to be a valid id of a flowdefinition registered in the configured registry.

Tip

By default, an action outcome prefixed with flowId: will be treated as a flow definition identifier.The flow id prefix respected by the FlowNavigationHandler is configurable. See the APIdocumentation for more information.

5.6.4. Launching a flow execution - normal HTML anchor

Flows can also be launched simply by accessing flow definition URLs directly using a bookmark or normalHTML link:

<a href="app.faces?_flowId=myflow">Go</a>

This example link assumes *.faces has been mapped to the FacesServlet defined within web.xml. The format ofa flow definition URL is configurable on the FlowPhaseListener.

5.6.5. Flow definitions in a JSF environment

Flow definitions in a JSF environment are just plain Spring Web Flow definitions:

<?xml version="1.0" encoding="UTF-8"?><flow xmlns="http://www.springframework.org/schema/webflow"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/webflow

http://www.springframework.org/schema/webflow/spring-webflow-1.0.xsd">

Flow executors

Spring Web Flow Version 1.0.5 69

Page 72: Spring Webflow Reference

<var name="myBean" class="example.ManagedBeanImpl" scope="conversation" />

<start-state idref="displayView" />

<view-state id="displayView" view="/myview.jsp"><transition on="submit" to="displayNextView"/>

</view-state>

<view-state id="displayNextView" view="/mynextview.jsp" />

</flow>

A primary benefit of using JSF is it a rich UI component framework, and UI components have both data andbehavior. As JSF components typically handle data binding and validation behaviors, the actual flow definitionlogic is often simpler and more focused as a result.

In general, it is recommended views selected by view states follow the standard JSF view identifier format,which requires a leading forward-slash and ends in a prefix. How Spring Web Flow view names are mapped toJSF view ids is configurable. See the FlowPhaseListener API documentation for more information.

5.6.6. Resuming a flow execution - form bound to flow execution variables

Views participating in flows are just plain JSF views. They may also incorporate other JSF view technologiessuch as Facelets and Ajax4JSF.

<f:view><h:form id="form">

...<h:inputText id="propertyName" value="#{someBean.someProperty}"/>...<h:commandButton type="submit" value="Next" action="submit"/>

</h:form></f:view>

As shown above, there is nothing Spring Web Flow specific here. The flow execution key is automaticallytracked by a special UI component in the view root, so there is no need to track it manually. Action outcomesare automatically mapped to Spring Web Flow event identifiers signaled against the current state.

5.6.7. Spring Web Flow JSF Integration Samples

See the sellitem-jsf sample that illustrates Spring Web Flow operating in a JSF environment.

5.6.8. A pre Spring Web Flow 1.0.2 faces-config.xml file

Note

The following three sections apply only to those using Spring Web Flow's JSF integration beforerelease 1.0.2.

Before release 1.0.2, Spring Web Flow only supported resolving variables in flow scope (and not the otherscopes such as flash and conversation shown above). This configuration is still supported for backwardscompatibility reasons:

<faces-config>

Flow executors

Spring Web Flow Version 1.0.5 70

Page 73: Spring Webflow Reference

<application><navigation-handler>org.springframework.webflow.executor.jsf.FlowNavigationHandler</navigation-handler><variable-resolver>org.springframework.webflow.executor.jsf.FlowVariableResolver</variable-resolver><property-resolver>org.springframework.webflow.executor.jsf.FlowPropertyResolver</property-resolver>

</application>

<lifecycle><phase-listener>org.springframework.webflow.executor.jsf.FlowPhaseListener</phase-listener>

</lifecycle></faces-config>

Note

With 1.0.2 DelegatingFlowVariableResolver is now the recommended default resolver, as itallows full access to all flow execution scopes transparently from the point of view of the JSF viewdeveloper.

5.6.9. A pre Spring Web Flow 1.0.2 Web Flow system configuration

Before release 1.0.2, Spring Web Flow did not support the configuration of a flowExecutor in a JSFenvironment. Those who needed to customize Web Flow services such as the flow execution repository orregistry deployed those beans individually with special bean names. This configuration is still supported forbackwards compatability reasons. However, it is recommended that existing users of Spring Web Flow's JSFintegration use the standard <flow:executor/> tag in the webflow-config namespace for consistency andsimplicity.

5.6.10. Resuming a flow execution - pre Spring Web Flow 1.0.2

Before release 1.0.2, the flow execution key had to be tracked manually in JSF views participating in a flowexecution. This configuration is still supported for backwards compatibility reasons. However, it is highlyrecommended that existing users of Spring Web Flow's JSF integration update their views to be just plain JSF.

<f:view><h:form id="form">

...<h:inputText id="propertyName" value="#{flowScope.aFlowScopeAttribute}"/>...<input type="hidden" name="_flowExecutionKey" value="${flowExecutionKey}"><h:commandButton type="submit" value="Next" action="submit"/>

</h:form></f:view>

The hidden form field above can now be safely removed. In addition, the new variable resolver can be pluggedin to gain access to other scopes such as flash and conversation.

Flow executors

Spring Web Flow Version 1.0.5 71

Page 74: Spring Webflow Reference

Chapter 6. Practical Use of Spring Web Flow

6.1. Sample applications

It is recommended that you review the Spring Web Flow sample applications included in the releasedistribution for best-practice illustrations of the features of this framework. A description of each sample isprovided below:

1. Phonebook - the original sample demonstrating most core features (including subflows).

2. Sellitem - demonstrates a wizard with conditional transitions, flow scope, flow execution redirects, andcontinuations.

3. Sellitem-JSF - The sellitem sample in a JSF environment (notice how the flow definition is more concisebecause JSF components care for data binding and validation).

4. Shippingrate - demonstrates Spring Web Flow together with the Prototype Javascript framework (forAjax-style flows).

5. NumberGuess - demonstrates use of stateful middle-tier components to carry out business logic.

6. Flowlauncher - demonstrates all the possible ways to launch and resume flows.

7. Itemlist - demonstrates REST-style URLs and inline flows.

8. Fileupload - demonstrates multipart file upload.

9. Birthdate - demonstrates Struts integration and the MultiAction.

10. Phonebook-Portlet - the phonebook sample in a Portlet environment (notice how the flow definitions donot change).

6.2. Running the Web Flow sample applications

The samples can be built from the command line and imported as Eclipse projects - all samples come withEclipse project settings. It is also possible to start by importing the samples into Eclipse first and then buildwith Ant within Eclipse.

6.2.1. Building from the Command Line

Java 1.5 (or greater) and Ant 1.6 (or greater) are prerequisites for building the sample applications. Ensurethose are present in the system path or are passed on the command line. To build Web Flow samples from thecommand line, open a prompt, cd to the directory where Spring Web Flow was unzipped, and run thefollowing:

cd projects/spring-webflow/build-spring-webflowant dist

This builds all samples preparing "target" areas within each sample project subdirectory containing webapp

Spring Web Flow Version 1.0.5 72

Page 75: Spring Webflow Reference

structures in both exploded and WAR archive forms. The build also provides basic helper targets for deployingto Tomcat from Ant; however these webapp structures can be copied to any servlet container, and each projectis also a Eclipse Dynamic Web Project (DWP) for easy deployment inside Eclipse with the Eclipse WebtoolsProject (WTP).

6.2.2. Importing Projects into Eclipse

Importing the sample projects into Eclipse is easy. With a new or an existing workspace select: File > Import >Existing Projects into Workspace. In the resulting dialog, browse to the project subdirectory where Spring WebFlow was unzipped and choose it as the root directory to import from. Select OK. Here Eclipse will list allprojects it found including the sample application projects. Select the projects you're interested in, and selectFinish.

If you previously built each project from the command line, Eclipse will compile with no errors. If not, you willneed to run the Ant build once for these errors to clear.

To build all projects inside Eclipse, import and expand the build-spring-webflow project, right-click onbuild.xml and select Run As > Ant Build. Doing this will run the default Ant target and will build all sampleprojects.

To build a single project inside Eclipse, simply select the project, right-click, and select Run As > Ant Build.You can also use the convenient shortcut ALT + SHIFT + X (Execute menu), then Q (Run Ant Build).

After Ant runs and the libraries needed to compile each project are downloaded, all errors in the Eclipseproblems view should go away. Try refreshing a project (F5) if you still have errors. In general, from this pointon you no longer need Ant: you can rely on Eclipse's incremental compile and Eclipse's web tools (WTP)built-in JEE support for deployment. (Ant is only needed in the system for command-line usage or when the listof jar dependencies for a project changes and new jars need to be downloaded).

6.2.3. Deploying projects inside Eclipse using Eclipse Web Tools (WTP)

Each Spring Web Flow sample application project is a Eclipse Dynamic Web Project (DWP), for easydeployment to a server running inside the Eclipse IDE. To take advantage of this, you must be running Eclipse3.2 with Web Tools 1.5.

To run a sample application as a webapp inside Eclipse, simply select the project, right-click, and select Run ->Run On Server. A convenient shortcut for this action is ALT + SHIFT + X (Execute menu), R (Run on Server).The first time you do this you will be asked to setup a Server, where you are expected to point Eclipse to alocation where you have a Servlet Container such as Apache Tomcat installed. Once your container has beensetup and you finish the deployment wizard, Eclipse will start the container and automatically publish yourwebapp to it. In addition, it will launch a embedded web browser allowing you to run the webapp fully insidethe IDE.

6.2.4. Other IDE's

Importing samples into other IDE's should be fairly straight-forward. If using another IDE, running the Antbuild from the command line first may help as it will populate the lib subdirectories of each sample project.Follow steps similar as those outlined for Eclipse above.

6.3. Sellitem Example

Practical Use of Spring Web Flow

Spring Web Flow Version 1.0.5 73

Page 76: Spring Webflow Reference

6.3.1. Overview

The Sellitem example demonstrates using Web Flow to build a shopping cart wizard with a shipping ratesubflow, decision states, service and data access Spring POJO beans, Spring 2.0 form tags, and a Web FlowFormAction bean for data binding, validation, and error reporting.

The Sellitem example breaks down its Spring application configuration into a number of files organizedaccording to purpose. Although the example itself uses a small number of beans you may consider organizing areal-world application (with many more beans) according to similar principles. Before going into the specificsof each individual context, use the diagram below to get a brief overview of all configuration files includinglocation and purpose.

Sellitem Spring & Web Flow Application Wiring

6.3.2. Web.xml

The web.xml configuration maps "*.htm" requests to the sellitem servlet - a Spring MVC DispatcherServlet:

<servlet><servlet-name>sellitem</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><init-param><param-name>contextConfigLocation</param-name>

<param-value>/WEB-INF/sellitem-servlet-config.xml/WEB-INF/sellitem-webflow-config.xml

</param-value></init-param>

</servlet>

<servlet-mapping><servlet-name>sellitem</servlet-name><url-pattern>*.htm</url-pattern>

</servlet-mapping>

Practical Use of Spring Web Flow

Spring Web Flow Version 1.0.5 74

Page 77: Spring Webflow Reference

The contextConifgLocation parameter for the DispatcherServlet indicates the Spring MVC web context for thesellitem servlet is spread over two xml files: sellitem-servlet-config.xml and sellitem-webflow-config.xml. Theweb.xml also requests an additional Spring context to be loaded from the classpath through theContextLoaderListener:

<context-param><param-name>contextConfigLocation</param-name><param-value>

classpath:org/springframework/webflow/samples/sellitem/services-config.xml</param-value>

</context-param>

<listener><listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>

</listener>

This service layer context defines beans to be referenced from web flow definitions. The next section discussesthe content of this context in more detail.

6.3.3. Services-config.xml

The services-config.xml loaded from the classpath through Spring MVC's ContextLoaderListener definesseveral beans for the service and data access layers of the application. For example, the service context definesa DAO bean ("saleProcessor") and injects it with a data source:

<bean id="saleProcessor" class="org.springframework.webflow.samples.sellitem.JdbcSaleProcessor"><property name="dataSource" ref="dataSource"/>

</bean>

<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"><property name="driverClassName" value="org.hsqldb.jdbcDriver"/><property name="url" value="jdbc:hsqldb:mem:sellItem"/><property name="username" value="sa"/>

</bean>

The services context also declares a bean of type InMemoryDatabaseCreator set to autowire by type meaningthat its fields will be compared against the types of beans available in the context and will be automatically setwhen a match is found. Hence the dataSource bean is used to set the dataSource property ofInMemoryDatabaseCreator:

<bean id="databaseCreator" class="org.springframework.webflow.samples.sellitem.InMemoryDatabaseCreator"autowire="byType"/>

Looking inside the InMemoryDatabaseCreator, its initDao() method invoked during context initializationcreates a table called T_SALES for use by the sample application. This table is created in an in-memory hsqldbdatabase called sellitem (based on the url property of the dataSource bean). It's also worth noting the beandeclarations related to declarative transaction management:

<tx:annotation-driven/>

<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><property name="dataSource" ref="dataSource"/>

</bean>

The "<tx:annotation-driven>"declaration indicates transaction configuration is governed by Java 5 annotationsused in bean classes such as this annotation in the SaleProcessor interface:

Practical Use of Spring Web Flow

Spring Web Flow Version 1.0.5 75

Page 78: Spring Webflow Reference

@Transactionalpublic interface SaleProcessor {

public void process(Sale sale);}

For annotated beans the Spring container automatically creates proxies according to the transaction semanticsin the annotation metadata. The "<tx:annotation-driven>" tag has a transaction-manager attribute but thisattribute is not required if the transaction manager bean is named "transactionManager".

6.3.4. Spring MVC Context

The Spring MVC web context is split over two files - sellitem-servlet-config.xml andsellitem-webflow-config.xml. The sellitem-servlet-config.xml defines a controller and a view resolver.

<bean name="/pos.htm" class="org.springframework.webflow.executor.mvc.FlowController"><property name="flowExecutor" ref="flowExecutor" />

</bean>

<!-- Maps flow view-state view names to JSP templates --><bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">

<property name="prefix" value="/WEB-INF/jsp/" /><property name="suffix" value=".jsp" />

</bean>

FlowController is a web flow controller extending Spring MVC's AbstractController delegating requests (inthis case for the "/pos.htm" servlet path) to the flowExecutor bean it is configured with. FlowController acts asgateway to Web Flow and a single controller instance can serve the application as most of the actual controllogic is encapsulated in web flow definitions.

The sellitem-webflow-config.xml defines web flow specific beans such as a flow executor, a flow registry anda flow listener beans:

<!-- Launches new flow executions and resumes existing executions --><flow:executor id="flowExecutor" registry-ref="flowRegistry">

<flow:execution-listeners><flow:listener ref="listener" criteria="sellitem-flow" />

</flow:execution-listeners></flow:executor>

<!-- Creates the registry of flow definitions for this application --><flow:registry id="flowRegistry">

<flow:location path="/WEB-INF/flows/**/*-flow.xml" /></flow:registry>

<!-- Observes the lifecycle of sellitem-flow executions --><bean id="listener"

class="org.springframework.webflow.samples.sellitem.SellItemFlowExecutionListener" />

The FlowExecutor is the central entry point into the Spring Web Flow system. It drives the execution of flowdefinitions configured through the flowRegistry. The flowRegistry bean is configured to load definitions fromfiles ending with "-flow.xml" in any subdirectory of /WEB-INF/flows. This matches to sellitem-flow.xml,shipping-flow.xml, sellitem-simple-flow.xml, sellitem-conversation-scope-flow.xml andshipping-conversation-scope-flow.xml.

As shown here the flow executor can also be configured with a flow listener, which is a callback mechanism forflow execution lifecycle events. The SellItemFlowExecutionListener extends FlowExecutionListenerAdapter -a default implementation of the FlowExecutionListener interface sparing the need to implement methods for alllifecycle events.

Practical Use of Spring Web Flow

Spring Web Flow Version 1.0.5 76

Page 79: Spring Webflow Reference

Looking inside SellItemFlowExecutionListener, it implements the stateEntering method executed for whenevera new state is about to be entered. The logic in this method checks if the current web flow state has an attributenamed "role" and if so it ensures the user has that role:

String role = nextState.getAttributes().getString("role");if (StringUtils.hasText(role)) {

HttpServletRequest request = ((ServletExternalContext)context.getExternalContext()).getRequest();if (!request.isUserInRole(role)) {

throw new EnterStateVetoException(context.getActiveFlow().getId(), context.getCurrentState().getId(),nextState.getId(), "State requires role '" + role

+ "', but the authenticated user doesn't have it!");}

}

Based on the above definitions - web.xml, Spring MVC controller bean, and web flow registry, thesellitem-flow can be initiated with the following URI:

/swf-sellitem/pos.htm?_flowId=sellitem-flow

Note: although it is possible to invoke the shipping-flow directly as well, it expects an input attribute and isintended to be invoked as a subflow.

6.3.5. Sellitem-beans.xml

Before tracing the sequence of states in sellitem-flow.xml notice the import declaration at the bottom of thatfile:

<import resource="sellitem-beans.xml"/>

The sellitem-beans.xml located in the same directory declares a web flow FormAction bean for use in the flowdefinition and configures it with a SaleValidator and a SellItemPropertyEditorRegistrar:

<!-- Manages setting up, binding input to, and validating a Sale "backing wizard form object" --><bean id="formAction" class="org.springframework.webflow.action.FormAction">

<property name="formObjectName" value="sale"/><property name="validator">

<bean class="org.springframework.webflow.samples.sellitem.SaleValidator"/></property><!-- Installs property editors used to format non-String fields like 'shipDate' --><property name="propertyEditorRegistrar">

<bean class="org.springframework.webflow.samples.sellitem.SellItemPropertyEditorRegistrar"/></property>

</bean>

The SellValidator will be used to validate form input data. The SellItemPropertyEditorRegistrar is responsiblefor registering custom property editors. Such editors are used to bind text data from HTML form fields toserver-side Objects. For example SellItemPropertyEditorRegistrar registers a custom date editor:

public void registerCustomEditors(PropertyEditorRegistry registry) {registry.registerCustomEditor(Date.class,

new CustomDateEditor(new SimpleDateFormat("MM/dd/yyyy"), true));}

This editor will bind the shipDate form field in shippingDetailsForm.jsp to the shipDate property of the Sale

Practical Use of Spring Web Flow

Spring Web Flow Version 1.0.5 77

Page 80: Spring Webflow Reference

object on the server side.

6.3.6. Sellitem-flow Flow Definition

The flow begins by declaring a "sale" variable - an object of type Sale:

<var name="sale" class="org.springframework.webflow.samples.sellitem.Sale"/>

The formAction bean will use the sale variable for form binding and validation (see sellitem-beans.xml).

The start state for the flow enterPriceAndItemCount is a view state, which resolves to the JSP page/WEB-INF/jsp/priceAndItemCountForm.jsp:

<view-state id="enterPriceAndItemCount" view="priceAndItemCountForm"><render-actions>

<!-- create the backing form object and initialize a empty errors collection --><action bean="formAction" method="setupForm"/>

</render-actions><transition on="submit" to="enterCategory">

<action bean="formAction" method="bindAndValidate"><attribute name="validatorMethod" value="validatePriceAndItemCount"/>

</action></transition>

</view-state>

The view state uses a render action to invoke the setupForm method of the formAction bean. The setupFormmethod prepares a form object based on the "sale" variable declared at the top of the flow definition.

The priceAndItemCountForm.jsp page collects a price and an itemCount using Spring 2.0 form input tagsbinding form fields to properties in the form backing object "sale". When pressed, the submit button"_eventId_submit" causes a web flow transition for an event with the id of "submit" to the view state"enterCategory". Prior to transitioning the formAction's bindAndValidate method is called to perform bindingand (partial) validation using the validatePriceAndItemCount method of the validator object.

The next view state enterCategory (based on categoryForm.jsp) collects inputs for sale category and whethershipping is required. On submit it transitions to the requiresShipping state:

<view-state id="enterCategory" view="categoryForm"><transition on="submit" to="requiresShipping">

<action bean="formAction" method="bind"/></transition>

</view-state>

The requiresShipping state is a decision state making flow routing decisions. It evaluates a boolean expressionagainst the executing flow and it decides where to transition to next. Here the shipping boolean property of the"sale" form backing object is checked to decide whether to go to the enterShippingDetails subflow state orproceed directly to processSale.

<decision-state id="requiresShipping"><if test="${flowScope.sale.shipping}" then="enterShippingDetails" else="processSale"/>

</decision-state>

The enterShippingDetails subflow state is based on shipping-flow.xml located in the same directory. The formbacking object "sale" is passed to it as an input attribute using an attribute mapper declaration:

Practical Use of Spring Web Flow

Spring Web Flow Version 1.0.5 78

Page 81: Spring Webflow Reference

<subflow-state id="enterShippingDetails" flow="shipping-flow"><attribute-mapper>

<input-mapper><input-attribute name="sale"/>

</input-mapper></attribute-mapper><transition on="finish" to="processSale"/>

</subflow-state>

The shipping-flow subflow is a simple flow with one view state. It collects the shipping details, binds the dataand returns to its parent flow. The id of the subflow end state "finish" is returned to the parent subflow statecausing a transition to the processSale action state.

<action-state id="processSale"><bean-action bean="saleProcessor" method="process">

<method-arguments><argument expression="flowScope.sale"/>

</method-arguments></bean-action><transition on="success" to="finish"/>

</action-state>

The saleProcessor bean, a POJO defined in services-config.xml is invoked using a "bean-action" declaration (asopposed to the "action" declation used to invoke a web flow Action such as FormAction). The saleProcessor(an instance of JdbcSaleProcessor) performs a database update using the values of the Sale object and uponsuccessful completion transitions to the end view state:

<end-state id="finish" view="costOverview"><entry-actions>

<action bean="formAction" method="setupForm"/></entry-actions>

</end-state>

Then end state calls FormAction's setupForm method again. This does not re-create the "sale" form object (stillin flow scope) but it does ensure any custom property editors are registered for use in rendering the JSP.

6.3.7. Sellitem-simple-flow Flow Definition

A simpler version of the sellitem-flow is available in the sellitem-simple-flow.xml file. This version uses aview state to gather shipping details instead of using a subflow. You can launch the sellitem-simple-flow usingthe following URI:

/swf-sellitem/pos.htm?_flowId=sellitem-simple-flow

6.3.8. Sellitem-conversation-scope-flow Flow Definition

This web flow is equivalent in functionality to the sellitem-flow definition described above. The maindifference is that it uses "conversation" scope to store the form backing object declared in/WEB-INF/flows/converstation-scope/sellitem-beans.xml.

<bean id="formAction" class="org.springframework.webflow.action.FormAction"><property name="formObjectName" value="sale"/><property name="formObjectScope" value="CONVERSATION"/><property name="formErrorsScope" value="CONVERSATION"/>

Practical Use of Spring Web Flow

Spring Web Flow Version 1.0.5 79

Page 82: Spring Webflow Reference

Conversation scope retains attributes stored in it for the life of the flow execution and is shared by all flowsessions. For example when invoking the shipping details subflow the parent flow does not need to pass the"sale" form backing object because it is now stored in conversation scope and is accessible to both flows:

<subflow-state id="enterShippingDetails" flow="shipping-conversation-scope-flow"><transition on="finish" to="processSale"/>

</subflow-state>

Also, when the "sale" object needs to be accessed it is done by referencing conversation cope:

<decision-state id="requiresShipping"><if test="${conversationScope.sale.shipping}" then="enterShippingDetails" else="processSale"/>

</decision-state>

You can launch the sellitem-conversation-scope-flow using the following URI:

/swf-sellitem/pos.htm?_flowId=sellitem-conversation-scope-flow

6.4. Sellitem-JSF Example

6.4.1. Overview

The Sellitem-JSF example uses Web Flow and JSF to build a shopping cart wizard. Navigation logic andsupporting managed beans are supplied by Spring Web Flow, while UI views and overall servlet processing isbased on JSF technology.

Note

The underlying Web Flow definitions for the Sellitem and the Sellitem-JSF examples are verysimilar. To avoid repetition the documentation for the Sellitem-JSF example focuses primarily onthe points of integration between Web Flow and JSF. For further general information on Web Flowdefinitions and supporting Java classes for the Sellitem example, please refer to the Sellitemexample documentation.

6.4.2. Web.xml

The web.xml contains standard JSF configuration including mappings for the JSF front servlet: it handles allrequests ending with "*.faces":

<!-- Faces Servlet --><servlet>

<servlet-name>Faces Servlet</servlet-name><servlet-class>javax.faces.webapp.FacesServlet</servlet-class><load-on-startup>1</load-on-startup>

</servlet>

<servlet-mapping><servlet-name>Faces Servlet</servlet-name><url-pattern>*.faces</url-pattern>

</servlet-mapping>

Practical Use of Spring Web Flow

Spring Web Flow Version 1.0.5 80

Page 83: Spring Webflow Reference

In addition, the web.xml loads a Spring root web application context containing the services used by theapplication:

<context-param><param-name>contextConfigLocation</param-name><param-value>

classpath:org/springframework/webflow/samples/sellitem/services-config.xml/WEB-INF/webflow-config.xml

</param-value></context-param>

<listener><listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>

</listener>

The services-config.xml contains POJO beans required for the services and data access layers of theapplication. These declarations are very similar to the Sellitem example (and explained in more detail there).The webflow-config.xml contains Web Flow related bean definitions. These definitions will be explained alittle bit further on in the context of how they fit into the JSF phases lifecycle.

6.4.3. Web Flow JSF Setup in faces-config.xml

To plug in Web Flow, a few things must be added once to faces-config.xml. This is demonstrated in thefaces-config.xml of Sellitem-JSF:

<application><navigation-handler>org.springframework.webflow.executor.jsf.FlowNavigationHandler</navigation-handler><variable-resolver>org.springframework.webflow.executor.jsf.DelegatingFlowVariableResolver</variable-resolver>

</application>

<lifecycle><phase-listener>org.springframework.webflow.executor.jsf.FlowPhaseListener</phase-listener>

</lifecycle>

The FlowNavigationHandler delegates view navigation handling to the the Web Flow system when a flow isinitiated or resumed.

The DelegatingFlowVariableResolver is suitable for use along side other variable resolvers to support ELbinding expressions like {#bean.property} where "bean" could be a property in any supported scope. Theresolver search algorithm looks in flash scope first, then flow scope, then conversation scope. If no variable isfound, this resolver delegates to the next resolver in the chain.

The FlowPhaseListener invoked during beforePhase and afterPhase JSF events is responsible for managing thelifecycle of a FlowExecution and making it available to other JSF artifacts during the lifecycle of a JSF request.

6.4.4. Web Flow System Setup in webflow-config.xml

Examining the definitions in faces-config.xml highlighted the ability to use plug Web Flow in as a navigationhandler and as a source for JSF managed beans. Now we can turn to the question of how to configure the webflow system itself in a JSF environment.

The Spring web context fragment /WEB-INF/webflow-config.xml contains the following configuration:

<!-- Launches new flow executions and resumes existing executions --><flow:executor id="flowExecutor" registry-ref="flowRegistry" />

Practical Use of Spring Web Flow

Spring Web Flow Version 1.0.5 81

Page 84: Spring Webflow Reference

<!-- Creates the registry of flow definitions for this application --><flow:registry id="flowRegistry">

<flow:location path="/WEB-INF/flows/sellitem-flow.xml" /></flow:registry>

Here the flow executor is configured to support execution of a single flow definition - sellitem-flow.xml. Theexecutor bean has been assigned the id "flowExecutor". This id is significant and is required for the JSFartifacts to detect the executor and its services.

6.4.5. Launching the sellitem-flow

The intro.jsp page shows how the configured web flow sellitem-flow.xml can be launched using a JSFcommand link component.

<h:form><h:commandLink value="Sell Item" action="flowId:sellitem-flow"/>

</h:form>

This causes the sellitem-flow to be initiated. Once a flow is initiated each subsequent JSP page can participatein the flow (the flow execution key is tracked for you).

A few notable differences between Sellitem and Sellitem-JSF to keep in mind:

1. The JSF version of the sellitem flow definition is simpler because JSF components care for data bindingand validation.

2. In its web flow definition Sellitem-JSF uses actual JSP names (instead of the logical view names used inSellitem) to be rendered by JSF. This is consistent with normal JSF-isms.

3. The JSP pages in Sellitem-JSF use unified EL to access the converastion scoped Sale object - e.g.#{sale.price}.

4. Sellitem-JSF uses JSF component tags for UI and Sellitem uses Spring form tags.

5. There is no need to manually track the flow execution key because it is tracked for you in the JSF viewroot.

The combination of delegating flow variable resolution plus automatic flow execution key management meansJSF views selected a flow look like standard JSF views to JSF developers. Also, JSF components help simplifyflow definition logic as the flow no longer has to worry about data binding and validation.

For more information and understanding on the Sellitem flow definition logic itself please refer to thedocumentation for the original Sellitem example.

6.5. Shippingrate Example

6.5.1. Overview

The Shippingrate sample demonstrates the use of Spring Web Flow in combination with Ajaxian techniques. Itconsists of several wizard-style steps executed with Ajax requests and refreshing a portion of the page. Theinput is collected from the user in incremental steps. It is stored in a flow-scoped object and is then used tocalcualte a shipping rate. The example also demonstrates invocation of a service-layer bean defined in a Spring

Practical Use of Spring Web Flow

Spring Web Flow Version 1.0.5 82

Page 85: Spring Webflow Reference

context to perform calculations and to provide reference data such as countries and package types.

6.5.2. Web.xml

The web.xml configuration maps requests for "*.htm" to the shippingrate servlet - a regular Spring MVCDispatcherServlet:

<servlet><servlet-name>shippingrate</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>

</servlet>

<servlet-mapping><servlet-name>shippingrate</servlet-name><url-pattern>*.htm</url-pattern>

</servlet-mapping>

The web.xml also ensures the following Spring context file is loaded at runtime from the web applicationclasspath:

<context-param><param-name>contextConfigLocation</param-name><param-value>

classpath:org/springframework/webflow/samples/shippingrate/domain/services.xml</param-value>

</context-param>

The services.xml Spring context defines a "rateService" bean providing operations for making shipping ratecalculations and for retrieving reference data required for display in the JSP pages of the application.

6.5.3. Spring MVC Context

The Spring MVC servlet context for the shippingrate servlet (WEB-INF/shippingrate-servlet.xml) defines onecontroller bean:

<bean name="/rates.htm" class="org.springframework.webflow.executor.mvc.FlowController"><property name="flowExecutor" ref="flowExecutor" />

</bean>

FlowController is a Web Flow controller. It is the main point of integration between Spring MVC and SpringWeb Flow routing requests to one or more managed web flow executions. The FlowController is injected withflowExecutor and flowRegistry beans:

<!-- Launches new flow executions and resumes existing executions. --><flow:executor id="flowExecutor" registry-ref="flowRegistry" repository-type="simple"/>

<!-- Creates the registry of flow definitions for this application --><flow:registry id="flowRegistry">

<flow:location path="/WEB-INF/flows/**/*-flow.xml" /></flow:registry>

The flowExecutor and the flowRegistry beans collectively configure the FlowController with one web flow -the getRate-flow defined in /WEB-INF/flows/getRate-flow.xml. The flowExecutor uses a "simple" repository,which manages execution state in the user session.

Practical Use of Spring Web Flow

Spring Web Flow Version 1.0.5 83

Page 86: Spring Webflow Reference

Given the above definitions the following URI can be used to initiate the getRate-flow:

/swf-shippingrate/rates.htm?_flowId=getRate-flow

6.5.4. Ajax Requests

The shippingrate example consists of several wizard-style steps. After the initial index.jsp subsequent pages areloaded in an Ajax manner without reloading the entire page.

The Ajax requests are done with the help of the Prototype framework and a thin JavaScript layer over itproviding convenient functions for processing Ajax form and get requests. The required Javascript libraries areincluded in index.jsp as follows:

<script src="prototype.js" type="text/javascript"></script><script src="swf_ajax.js" type="text/javascript"></script>

When index.jsp is loaded the following JavaScript invokes the getRate-flow and replaces the content of thegetRateWizard div tag with the response returned from the server:

<div id="getRateWizard"><script type="text/javascript">window.onload = function() {

new SimpleRequest('getRateWizard', 'rates.htm', 'get', '_flowId=getRate-flow');};</script>

</div>

Functions are first-class citizens and a type in JavaScript. The script above creates an instance of theSimpleRequest function defined in swf_ajax.js. This function invokes Prototype's Ajax.Updater with thespecified URL and request parameters. On success the content of the getRateWizard div is replaced with theresponse returned from the server. On failure such as an HTTP response code other 200 (OK) an error messageis displayed.

The next few pages are form-based JSP's - selectCustomer.jsp, selectReceiver.jsp, etc. Each of them containsthe following JavaScript call at the bottom:

<script type="text/javascript">formRequest('selectCustomerTypeForm');

</script>

The formRequest function is also defined in swf_ajax.js and it uses Prototype to register a handler for the formsubmit event:

function formRequest(formElementId) {Event.observe(formElementId, 'submit', handleSubmitEvent, true);

}

The handleSubmitEvent function extracts the form parameters, stops the submit event, and posts an AJAXrequest via XMLHttpRequest. On success the results returned form the server replace the content of the form.On failure such as an HTTP response code other 200 (OK) an error message is displayed.

Practical Use of Spring Web Flow

Spring Web Flow Version 1.0.5 84

Page 87: Spring Webflow Reference

Although not demonstrated in this example a back button can be implemented in parallel with the Next buttonused to advance from one screen to the next. This would be necessary because the browser back button - acommon issue in Ajax applications, contrary to user expectation returns to the page prior to the first Ajaxrequest.

As a result of the Ajax requests the entire wizard is able to function within a portion of the page withoutrefresing the remaining information on it.

6.5.5. getRate Web Flow

The getRate-flow (/WEB-INF/jsp/flows/getRate-flow.xml) defines the following start state:

<view-state id="selectCustomerType" view="selectCustomer"><transition on="submit" to="selectSender">

<action bean="formAction" method="bind" /></transition>

</view-state>

This is a view state, which will display the initial form using the JSP page /WEB-INF/jsp/selectCustomer.jsp.Notice, the use of a start action executed immediately before the JSP is displayed:

<start-actions><action bean="formAction" method="setupForm" />

</start-actions>

The "formAction" bean is defined in the Spring servlet context (/WEB-INF/shippingrate-servlet.xml). Itspecifies a form object and a validator to use for form data binding and validation:

<!-- Performs "form backing object" data binding and validation on input submit --><bean id="formAction" class="org.springframework.webflow.action.FormAction">

<property name="formObjectName" value="rateCriteria" /><property name="formObjectClass" value="org.springframework.webflow.samples.shippingrate.domain.RateCriteria" /><property name="formObjectScope" value="FLOW" /><property name="validator">

<bean class="org.springframework.webflow.samples.shippingrate.domain.RateCriteriaValidator" /></property>

</bean>

The form object of type RateCriteria will be used to collect data from the user in several steps. The form objectwill be stored in FLOW scope and will not be re-created with each request as long as the flow hasn't reached itsend state. The actual binding of html form fields to the RateCriteria object is based on Spring's data bindingmechanism. Html form fields are surrounded with the <spring:bind> tag containing the path nested propertyfield. FormAction's bindAndValidate method will initiate the actual binding on the server side between HTTPrequest parameters and RateCriteria data fields.

When the selectCustomer.jsp submits back to the FlowController via "/swf-shippingrate/rate.htm" it uses asubmit button named "_eventId_submit". This indicates to Web Flow a transition to the "selectSender" viewstate. This view state is defined as follows:

<view-state id="selectSender" view="selectSender"><render-actions>

<bean-action bean="rateService" method="getCountries"><method-result name="countries" />

</bean-action></render-actions><transition on="submit" to="selectReceiver">

<action bean="formAction" method="bindAndValidate">

Practical Use of Spring Web Flow

Spring Web Flow Version 1.0.5 85

Page 88: Spring Webflow Reference

<attribute name="validatorMethod" value="validateSender" /></action>

</transition></view-state>

The selectSender view state has a render action: the "rateService" bean that was loaded through theservices.xml context referenced in web.xml. The purpose of the render action is to load data required to renderthe JSP. In this case the rateService bean has a method called getCountries that returns a list of countries to bedisplayed in a drop-down by the JSP.

The "selectSender" view state also defines one transition: on event with id of "submit" a transition to the"selectReceiver" view state occurs. A pre-requisite for the transition to occur is the successful completion offormAction bean's bindAndValidate method. The attribute "validatorMethod" on the bean specifies the name ofthe method to invoke on the Validator object specifically for the fields of the current screen. If thebindAndValidate method does not succeed the transition does not take place and the flow remains in the"selectSender" view state where the user can review the errors and modify the selection.

The next two states in the flow - selectReceiver and selectPackageDetails use similar mechnisms. TherateSevice bean is used to retrieve countries and package types for use in the JSP. The form backing objectRateCriteria stored in FLOW scope is used to collect user input with each form submit.

The "findRate" action state occurs after all user input has been provided. It is defined as follows:

<action-state id="findRate"><bean-action bean="rateService" method="getRate">

<method-arguments><argument expression="flowScope.rateCriteria" />

</method-arguments><method-result name="rate" />

</bean-action><transition on="success" to="showRate" />

</action-state>

Logic for the action state is provided by the getRate method of the rateService bean. The RateCriteria objectstored in FLOW scope and containing the user input is passed to the rateService bean. The result of the methodis exposed in request scope under the name "rate".

The next and final state "showRate" is a JSP page, which accesses the calculated rate information and displaysit to the user.

6.6. Numberguess Example

6.6.1. Overview

Numberguess uses Web Flow to implement two number guessing games. For each game the user can entermultiple guesses and depending on the answer either transition back to the same screen or advance to the finalscreen. Logic for the guessing games is provided through FLOW-scoped beans, which also maintain state suchas the total number of guesses. The example defines transitions using event pattern matching and customexception handlers.

6.6.2. Web.xml

The web.xml configuration maps "*.htm" requests to the numberguess servlet - a regular Spring MVC

Practical Use of Spring Web Flow

Spring Web Flow Version 1.0.5 86

Page 89: Spring Webflow Reference

DispatcherServlet:

<servlet><servlet-name>numberguess</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><init-param>

<param-name>contextConfigLocation</param-name><param-value>/WEB-INF/dispatcher-servlet.xml</param-value>

</init-param></servlet>

<servlet-mapping><servlet-name>numberguess</servlet-name><url-pattern>*.htm</url-pattern>

</servlet-mapping>

The Spring web context is loaded from a file called /WEB-INF/dispatcher-servlet.xml.

6.6.3. Spring MVC Context

The Spring MVC web context (WEB-INF/dispatcher-servlet.xml) defines one controller bean:

<bean name="/play.htm" class="org.springframework.webflow.executor.mvc.FlowController"><property name="flowExecutor" ref="flowExecutor" />

</bean>

FlowController is a Web Flow controller. It is the main point of integration between Spring MVC and SpringWeb Flow routing requests to one or more managed web flow executions. The FlowController is injected withflowExecutor and flowRegistry beans:

<!-- Launches new flow executions and resumes existing executions. --><flow:executor id="flowExecutor" registry-ref="flowRegistry" repository-type="singlekey"/>

<!-- Creates the registry of flow definitions for this application --><flow:registry id="flowRegistry">

<flow:location path="/WEB-INF/higherlower.xml" /><flow:location path="/WEB-INF/mastermind.xml" />

</flow:registry>

The flowExecutor and the flowRegistry beans collectively configure the FlowController with two web flows -higherlower and mastermind. This flowExecutor is configured with a simple repository that assigns a singleflow execution key per conversation. The key, once assigned, never changes for the duration of theconversation.

Given the above definitions the following URI's can be used to initiate each of the two flows:

/swf-numberguess/play.htm?_flowId=higherlower/swf-numberguess/play.htm?_flowId=mastermind

The Spring MVC servlet context also defines a view resolver bean for resolving logical view names. In generalWeb Flow does not aim to replace the flexibility of Spring MVC for view resolution. It focuses on the C inMVC.

6.6.4. Higherlower Flow

Practical Use of Spring Web Flow

Spring Web Flow Version 1.0.5 87

Page 90: Spring Webflow Reference

The Higherlower flow (/WEB-INF/higherlower.xml) starts with the following flow variable declaration:

<var name="game" class="org.springframework.webflow.samples.numberguess.HigherLowerGame"/>

This variable is automatically created when an execution of the flow begins and will exist in FLOW scopethroughout its duration.

The start state for the flow is defined as follows:

<view-state id="enterGuess" view="higherlower.enterGuess"><transition on="submit" to="makeGuess"/>

</view-state>

The view resolver bean of Spring MVC will resolve "higherlower.enterGuess" to/WEB-INF/jsp/higherlower.enterGuess.jsp. This JSP has a form with one input field for the guess number. The"game" variable referenced throughout the JSP is the FLOW-scoped variable that was declared at the top of theflow definition.

The name of the form submit button "_eventId_submit" indicates the event id to use for deciding where totransition to next. Given an event with id of "submit" the "enterGuess" view state transitions to the"makeGuess" action state defined as follows:

<action-state id="makeGuess"><evaluate-action expression="flowScope.game.makeGuess(requestParameters.guess)">

<evaluation-result name="guessResult"/></evaluate-action><transition on="CORRECT" to="showAnswer"/><transition on="*" to="enterGuess"/><transition on-exception="java.lang.NumberFormatException" to="enterGuess"/>

</action-state>

The makeGuess action state consists of one evaluate action and three transitions. Evaluate actions are used toinvoke logic encapsulated in a FLOW-scoped object - in this case the game bean. The makeGuess method ofthe game bean returns one of several enum values it defines:

enum GuessResult {TOO_HIGH, TOO_LOW, CORRECT, INVALID

}

Web Flow detects the returned result from the makeGuess method is a JDK 1.5 enum type and creates an Eventwith a String id matching the enum value. If the makeGuess method returns CORRECT a transition to the finalshowAnswer state occurs. For any other event (defined with the event pattern on="*") Web Flow returns to theenterGuess state. The makeGuess state also defines one on-exception transition demonstrating how specificExceptions can be incorporated into flow transition logic.

The end-state showAnswer resolves to the JSP page /WEB-INF/jsp/higherlower.showAnswer.jsp, whichsimply shows the correct guess. At this point the flow has ended and the "game" bean is no longer in scope.

6.6.5. Mastermind Flow

The mastermind flow uses a similar flow definition to implement a 4-digit guessing game:

Practical Use of Spring Web Flow

Spring Web Flow Version 1.0.5 88

Page 91: Spring Webflow Reference

<var name="game" class="org.springframework.webflow.samples.numberguess.MastermindGame"/>

<start-state idref="enterGuess"/>

<view-state id="enterGuess" view="mastermind.enterGuess"><transition on="submit" to="makeGuess"/>

</view-state>

<action-state id="makeGuess"><evaluate-action expression="flowScope.game.makeGuess(requestParameters.guess)">

<evaluation-result name="guessResult"/></evaluate-action><transition on="CORRECT" to="showAnswer"/><transition on="*" to="enterGuess"/>

</action-state>

<end-state id="showAnswer" view="mastermind.showAnswer"/>

The MastermindGame class encapsulates the logic for the game and is stored as a FLOW-scoped bean. Itreturns one of three possible enum values - WRONG, CORRECT, or INVALID, which Web Flow converts toevents with id's matching the enum values. If the guess is INVALID the JSP page/WEB-INF/jsp/mastermind.enterGuess.jsp will print an error message. If the guess is CORRECT the flow willtransition to the showAnswer end state and complete the flow.

6.7. Flowlauncher Example

6.7.1. Overview

Flowlauncher demonstrates two different ways one web flow can launch another - by redirecting to it or bylaunching it as a subflow. Flowlauncher has two flows: Sample A and Sample B. As a root level flow Sample Aeither transitions to B through a subflow state or redirects to B in its end state.

6.7.2. Web.xml

The web.xml configuration maps "*.htm" requests to the flowlauncher servlet - a regular Spring MVCDispatcherServlet:

<servlet><servlet-name>flowlauncher</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>

</servlet>

<servlet-mapping><servlet-name>flowlauncher</servlet-name><url-pattern>*.htm</url-pattern>

</servlet-mapping>

6.7.3. Spring MVC Context

The Spring MVC web context (WEB-INF/flowlauncher-servlet.xml) defines one controller bean:

<bean name="/flowController.htm" class="org.springframework.webflow.executor.mvc.FlowController"><property name="flowExecutor" ref="flowExecutor" />

</bean>

Practical Use of Spring Web Flow

Spring Web Flow Version 1.0.5 89

Page 92: Spring Webflow Reference

FlowController is a Web Flow extension of Spring MVC's AbstractController. It contains a FlowExecutor anddirects incoming requests for one or more managed flow executions to it. The FlowExecutor bean is configuredin the same context:

<!-- Launches new flow executions and resumes existing executions. --><flow:executor id="flowExecutor" registry-ref="flowRegistry"/>

<!-- Creates the registry of flow definitions for this application --><flow:registry id="flowRegistry">

<flow:location path="/WEB-INF/sampleA.xml" /><flow:location path="/WEB-INF/sampleB.xml" />

</flow:registry>

A single FlowController may direct all flows for an application serving as a gateway to Web Flow. Based onthe above definitions the flows sampleA and sampleB can be invoked as follows:

/swf-flowlauncher/flowController.htm?_flowId=sampleA/swf-flowlauncher/flowController.htm?_flowId=sampleB

The welcome index.html file for the web application invokes the flows and passes additional input using eithera URL link or a form submit.

6.7.4. Sample A Web Flow

The Sample A web flow (/WEB-INF/sampleA.xml) begins with an input mapping declaration:

<input-mapper><mapping source="input" target="flowScope.input" />

</input-mapper>

This declaration reads "when a new execution of this flow starts map the input attribute named input into aflowScope attribute also named input". Spring Web Flow will automatically provide the request parameters asinput to the flow when launching a new flow execution. Following this declaration the input request parameterwill remain available for the duration of the flow.

There are 3 states in this flow: the start state, the end state, and a subflow state. The start state is a view state - itwill display a JSP page and allow the user to make a choice. The subflow state initiates Sample B as a subflowof the current flow - subflows give the ability to compose independent modules together to compose complexcontroller workflows. And the end state launches Sample B by redirecting to it.

The subflow state launches B with the following input attribute declaration. This declaration reads "pass thevalue of the flow-scoped attribute named input as an attribute also named input to subflow B.

<attribute-mapper><input-mapper>

<mapping source="flowScope.input" target="input" /></input-mapper>

</attribute-mapper>

The next line is a transition defining how to respond when the subflow ends: advance back to the start state forSample A.

<transition on="end" to="aPage" />

Practical Use of Spring Web Flow

Spring Web Flow Version 1.0.5 90

Page 93: Spring Webflow Reference

The end state demonstrates how to redirect to Sample B upon completion of the root level flow Sample A:

<end-state id="endAndLaunchB" view="flowRedirect:sampleB?input=${requestParameters.input}" />

This declaration causes A to be terminated and B to start with the given requst input parameter.

6.7.5. Sample B Web Flow

The flow Sample B (/WEB-INF/sampleB.xml) - used as a subflow in Sample A has two simple states: a viewstate and an end state. From the view state "bPage" the flow transitions to the end state:

<view-state id="bPage" view="bPage"><transition on="end" to="end" />

</view-state>

<end-state id="end" />

The "id" attribute of the end state matches the "on" attribute of the transition in the outer flow's subflow state,which the outer flow uses to resume itself.

Also notice how bPage.jsp makes a check to detect if Sample B is running as a subflow of Sample A or if it isrunning as a top-level flow:

<c:if test="${!flowExecutionContext.activeSession.root}">

The FlowExecutionContext object is exposed to the views (JSPs) to make information like this available duringresponse rendering.

6.8. Itemlist Example

6.8.1. Overview

Itemlist demonstrates how to configure a FlowExecutor with an argument handler enabling it to processREST-style requests where the name of the target flow is in the URL instead of a _flowId request parameter.The example also demonstrates inner flows as well as how an output parameter can be passed from a subflowto a parent flow. Finally, it serves as an illustration of how to configure Spring Web Flow using classic Spring1.x bean definitions.

6.8.2. Web.xml

The web.xml configuration maps "/app/*" requests to the itemlist servlet - a regular Spring MVCDispatcherServlet:

<servlet><servlet-name>itemlist</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>

</servlet>

<servlet-mapping><servlet-name>itemlist</servlet-name>

Practical Use of Spring Web Flow

Spring Web Flow Version 1.0.5 91

Page 94: Spring Webflow Reference

<url-pattern>/app/*</url-pattern></servlet-mapping>

6.8.3. Spring MVC Context

The Spring MVC web context (/WEB-INF/itemlist-serlvet.xml) defines one controller and one URL handlermapping:

<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping"><property name="alwaysUseFullPath" value="true" /><property name="mappings">

<value>/app/**/**=flowController</value></property>

</bean>

<bean id="flowController" class="org.springframework.webflow.executor.mvc.FlowController"><property name="flowExecutor" ref="flowExecutor" /><property name="argumentHandler">

<bean class="org.springframework.webflow.executor.support.RequestPathFlowExecutorArgumentHandler" /></property>

</bean>

All requests with a servlet path matching "/app/**/**" are mapped to the "flowController" bean. TheFlowController is a Web Flow extension of Spring MVC's AbstractController delegating requests to one ormore managed web flows. It acts as gateway to Web Flow defined control logic and a single instance can servethe application.

The usual way to launch a specific web flow is to pass the _flowId request parameter. However, this example isconfigured with a RequestPathFlowExecutorArgumentHandler for processing REST-style URL's. Requests forservices built around the REST concept are encoded in the URL and not as query string parameters. The way toinvoke a web flow with this argument handler is to follow:

http://${host}/${context path}/${dispatcher path}/${flowId}

The FlowController is configured with a flowExecutor and flowRegistry beans containing two web flows -itemlist and itemlist-alternate:

<!-- Launches new flow executions and resumes existing executions: Spring 1.2 config version --><bean id="flowExecutor" class="org.springframework.webflow.config.FlowExecutorFactoryBean">

<property name="definitionLocator" ref="flowRegistry"/></bean>

<!-- Creates the registry of flow definitions for this application: Spring 1.2 config version --><bean id="flowRegistry" class="org.springframework.webflow.engine.builder.xml.XmlFlowRegistryFactoryBean">

<property name="flowLocations"><list>

<value>/WEB-INF/itemlist.xml</value><value>/WEB-INF/itemlist-alternate.xml</value>

</list></property>

</bean>

The FlowRegistry and FlowExecutor are defined with Spring 1.2 compatible bean definitions. However,starting with Spring 2.0 Web Flow also offers the custom tags flow:registry and flow:executor, which are morereadable and less verbose.

Practical Use of Spring Web Flow

Spring Web Flow Version 1.0.5 92

Page 95: Spring Webflow Reference

Based on the above web context definition use the following URL's to invoke the itemlist or theitemlist-alternate web flows:

/swf-itemlist/app/itemlist/swf-itemlist/app/itemlist-alternate

Also defined in itemlist-servlet.xml are three "action" beans - createItemAction, addItemAction, andmapItemAction, which will be referenced from action states in the web flow definitions.

6.8.4. Itemlist Web Flow

The itemlist flow allows adding items to a list. There are two view states - displayItemList and displayItem, andtwo action states - createItem and addItem.

The displayItemList view state resolves to /WEB-INF/jsp/itemList.jsp, which lists all items on the list anddisplays an "Add" button with the name "_eventId_add". The name of the button indicates the event id to usefor deciding where to transition to next. Also, notice that instead of posting a "_flowId" parameter the JSP setsthe form action to the value of flowExecutionKey - a value automatically made available in the page context byWeb Flow:

<form action="${flowExecutionKey}" method="post"/>

When the form submits an event with the "_eventId_add" button the displayItemList view state transitions tothe createItem action state.

<view-state id="displayItemlist" view="itemlist"><transition on="add" to="createItem" />

</view-state>

<action-state id="createItem"><action bean="createItemAction" /><transition on="success" to="displayItem" />

</action-state>

The "createItemAction" bean is declared in the Spring MVC context (/WEB-INF/itemlist-servlet.xml). Itsimply returns "success", which causes a transition to the displayItem view state.

The next two states displayItem and addItem allow adding an item to the list variable declared at the top of theflow:

<var name="list" class="java.util.ArrayList" />

The "addItemAction" bean is also declared in the Spring MVC context. It performs the add by accessing the listin flow scope and the item to be added from the request parameters as follows:

Collection list = context.getFlowScope().getRequiredCollection("list");String data = context.getRequestParameters().get("data");if (data != null && data.length() > 0) {

list.add(data);}

Practical Use of Spring Web Flow

Spring Web Flow Version 1.0.5 93

Page 96: Spring Webflow Reference

For any outcome the addItem state transitions back to the initial displayItemList state using an event patternmatch:

<action-state id="addItem"><action bean="addItemAction" /><transition on="*" to="displayItemlist" />

</action-state>

6.8.5. Itemlist-alternate Web Flow

The Itemlist-alternate web flow (/WEB-INF/itemlist-alternate.xml) has functionality equivalent to that ofitemlist but instead uses a subflow for selecting individual items. The "addItem" state is a subflow stateinvoking an inline flow called "item" (also defined in itemlist-alternate.xml) accepting an output parameterfrom the subflow and adding the output parameter to a flow-scoped list variable:

<subflow-state id="addItem" flow="item"><attribute-mapper>

<output-mapper><mapping source="item" target-collection="flowScope.list" />

</output-mapper></attribute-mapper><transition on="finish" to="displayItemlist" />

</subflow-state>

An output-mapper is used to pass results from a subflow to a parent flow. The above declaration defines anexpectation on the subflow to return an output parameter called "item". Accordingly the end state for the inlineflow has this output mapping returning a parameter called "item":

<end-state id="finish"><output-mapper>

<mapping source="requestParameters.data" target="item" /></output-mapper>

</end-state>

With the above declarations we see how a subflow can pass output parameters back to its parent flow - in thiscase the 'data' request parameter is passed back as an output parameter.

Once the inner subflow flow has completed the item is passed to the parent flow as an output parameter, whichadds it to its flow-scoped list and transitions to the initial "displayItemList" state.

6.9. Fileupload Example

6.9.1. Overview

Fileupload is a simple one page web application for uploading files to a server. It is based on Spring MVC, usesa Web Flow controller and one web flow with two states: a view state for displaying the initial JSP page and anaction state for processing the submit.

6.9.2. Web.xml

The web.xml configuration maps requests for "*.htm" to the fileupload servlet - a regular Spring MVC

Practical Use of Spring Web Flow

Spring Web Flow Version 1.0.5 94

Page 97: Spring Webflow Reference

DispatcherServlet:

<servlet><servlet-name>fileupload</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>

</servlet>

<servlet-mapping><servlet-name>fileupload</servlet-name><url-pattern>*.htm</url-pattern>

</servlet-mapping>

6.9.3. Spring MVC Context

The Spring MVC servlet context for the fileupload servlet (WEB-INF/fileupload-servlet.xml) defines onecontroller bean:

<bean name="/admin.htm" class="org.springframework.webflow.executor.mvc.FlowController"><property name="flowExecutor" ref="flowExecutor" />

</bean>

FlowController is a Web Flow controller. It is the main point of integration between Spring MVC and SpringWeb Flow routing requests to one or more managed web flow executions. The FlowController is injected withflowExecutor and flowRegistry beans containing one web flow definition:

<!-- Launches new flow executions and resumes existing executions. --><flow:executor id="flowExecutor" registry-ref="flowRegistry" repository-type="singlekey"/>

<!-- Creates the registry of flow definitions for this application --><flow:registry id="flowRegistry">

<flow:location path="/WEB-INF/fileupload.xml" /></flow:registry>

Given the above definitions the following URI can be used to invoke the "fileupload" flow:

/swf-fileupload/admin.htm?_flowId=fileupload

Both flowExecutor and flowRegistry beans are defined with Spring custom tags schema available in Spring 2.0.The custom tags make configuration less verbose and more readable. Regular Spring bean definitions can beused as well with earlier versions of Spring.

The Spring MVC context also defines a view resolver bean for resolving logical view names and amultipartResolver bean for the upload component. In general Web Flow does not aim to replace the flexibilityof Spring MVC for view resolution. It focuses on the C in MVC.

6.9.4. Fileupload Web Flow

The start state for the fileupload flow (WEB-INF/fileupload.xml) is a view state:

<start-state idref="selectFile"/>

<view-state id="selectFile" view="fileForm"><transition on="submit" to="uploadFile"/>

Practical Use of Spring Web Flow

Spring Web Flow Version 1.0.5 95

Page 98: Spring Webflow Reference

</view-state>

View states allow a user to participate in a flow by presenting a suitable interface. The view attribute"fileForm" is a logical view name, which the Spring MVC view resolver bean will resolve to/WEB-INF/jsp/fileForm.jsp.

The fileForm.jsp has an html form that submits back to the same controller (/swf-fileupload/admin.htm) andpasses a "_flowExecutionKey" parameter. The value for _flowExecutionKey is provided by the FlowController- it identifies the current instance of the flow and allows Web Flow to resume flow execution, which is pausedeach time a view is displayed.

The name of the form submit button "_eventId_submit" indicates the event id to use for deciding where totransition to next. Given an event with id of "submit" the "selectFile" view transitions to the "uploadFile" state:

<action-state id="uploadFile"><action bean="uploadAction"/><transition on="success" to="selectFile">

<set attribute="fileUploaded" scope="flash" value="true"/></transition><transition on="error" to="selectFile"/>

</action-state>

The "uploadFile" state is an action state. Action states integrate with business application code and respond tothe execution of that code by deciding what state of the flow to enter next. The code for the uploadFile state isin the "uploadAction" bean declared in the Spring web context (/WEB-INF/fileupload-servlet.xml):

<bean id="uploadAction" class="org.springframework.webflow.samples.fileupload.FileUploadAction" />

FileUploadAction has simple logic. It picks one of two Web Flow defined events - success or error, dependingon whether the uploaded file size is greater than 0 or not. Both success and error transition back to the"selectFile" view state. However, a success event causes an attribute named "fileUploaded" to be set in flashscope

A flash-scoped attribute called "file" is also set programmatically in the FileUploadAction bean:

context.getFlashScope().put("file", new String(file.getBytes()));return success();

This illustrates the choice to save attributes in one of several scopes either programatically or declaratively.

6.10. Birthdate Example

6.10.1. Overview

Birthdate is a web application with 3 consequitive screens. The first two collect user input to populate a formobject. The third presents the results of business calculations based on input provided in the first two screens.

Birthdate demonstrates Spring Web Flow's Struts integration as well as the use of FormAction, a multi-actionused to do the processing required for all three screens. The sample also uses JSTL taglibs in conjunction withflows.

Practical Use of Spring Web Flow

Spring Web Flow Version 1.0.5 96

Page 99: Spring Webflow Reference

6.10.2. Web.xml

The web.xml configuration maps requests for "*.do" to a regular Struts ActionServlet:

<servlet><servlet-name>action</servlet-name><servlet-class>org.apache.struts.action.ActionServlet</servlet-class>

</servlet>

<servlet-mapping><servlet-name>action</servlet-name><url-pattern>*.do</url-pattern>

</servlet-mapping>

The web.xml also sets up the loading of a Spring context at web application startup:

<context-param><param-name>contextConfigLocation</param-name><param-value>

/WEB-INF/webflow-config.xml</param-value>

</context-param>

<listener><listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>

</listener>

The Spring web context contains beans to set up the Web Flow runtime environment. As will be shown in thenext section Struts is configured with a Web Flow action that relies on the presence of a flowExecutor and aflowRegistry beans in this context.

6.10.3. Struts Configuration

The Struts configuration (WEB-INF/struts-config.xml) defines the following action mapping:

<action-mappings><action path="/flowAction" name="actionForm" scope="request"

type="org.springframework.webflow.executor.struts.FlowAction"/></action-mappings>

FlowAction is a Struts action acting as a front controller to the Web Flow system routing Struts requests to oneor more managed web flow executions. To fully configure the FlowAction a Spring web context is required todefine flowExecutor and flowRegistry beans (named exactly so). This is an excerpt from the Spring webcontext (/WEB-INF/webflow-config.xml) defining these beans:

<!-- Launches new flow executions and resumes existing executions. --><flow:executor id="flowExecutor" registry-ref="flowRegistry"/>

<!-- Creates the registry of flow definitions for this application --><flow:registry id="flowRegistry">

<flow:location path="/WEB-INF/birthdate.xml"/><flow:location path="/WEB-INF/birthdate-alternate.xml"/>

</flow:registry>

Based on the above, Web Flow is configured with two flows - birthdate and birthdate-alternate, which can beinvoked as follows:

Practical Use of Spring Web Flow

Spring Web Flow Version 1.0.5 97

Page 100: Spring Webflow Reference

/swf-birthdate/flowAction.do?_flowId=birthdate/swf-birthdate/flowAction.do?_flowId=birthdate-alternate

The Struts configuration file also defines several global forwards: birthdateForm, cardForm, and yourAge,which will be referenced from Web Flow definitions as logical view names (and left to Struts to resolve toactual JSP pages). In general Web Flow does not aim to replace view resolution capabilities of web frameworkssuch as Struts or Spring MVC. It focuses on the C in MVC.

6.10.4. Birthdate Web Flow

The birthdate web flow (WEB-INF/birthdate.xml) defines the following start state:

<view-state id="enterBirthdate" view="birthdateForm"><render-actions>

<action bean="formAction" method="setupForm" /></render-actions><transition on="submit" to="processBirthdateFormSubmit" />

</view-state>

The setupForm action is called to perform initializations for the enterBirthdate view state. Its action bean isdefined the Spring web context WEB-INF/webflow-config.xml:

<bean id="formAction" class="org.springframework.webflow.samples.birthdate.BirthDateFormAction" />

BirthDateFormAction is a FormAction - it extends Web Flow's FormAction class, which serves a purposesimilar to that of Spring MVC's SimpleFormController providing common form functionality for data bindingand validation.

When the BirthDateFormAction bean is instantiated it sets the name, class and scope of the form object to usefor loading form data upon display and collecting form data upon submit:

public BirthDateFormAction() {// tell the superclass about the form object and validator we want to// use you could also do this in the application context XML ofcoursesetFormObjectName("birthDate");setFormObjectClass(BirthDate.class);setFormObjectScope(ScopeType.FLOW);setValidator(new BirthDateValidator());

}

The form object "birthDate" is placed in flow scope, which means it will not be re-created with each request butwill be obtained from flow scope instead as long as the request remains within the same flow.

Once setupForm is done, the "birthdateForm" view will be rendered. The logical view name "birthdateForm" isa global-forward in struts-config.xml resolving to /WEB-INF/jsp/birthdateForm.jsp. This JSP collects data forthe fields "name" and "date" bound to the birthDate form object and posts back to FlowAction with a submitimage named "_eventId_submit". An event with the id of "submit" causes a transition to theprocessBirthdateFormSubmit action state defined as follows:

<action-state id="processBirthdateFormSubmit"><action bean="formAction" method="bindAndValidate">

<attribute name="validatorMethod" value="validateBirthdateForm" /></action><transition on="success" to="enterCardInformation" /><transition on="error" to="enterBirthdate" />

Practical Use of Spring Web Flow

Spring Web Flow Version 1.0.5 98

Page 101: Spring Webflow Reference

</action-state>

The processBirthDateFormSubmit action state uses the same formAction bean as the one already used to setupthe form. This time its bindAndValidate method is used to populate and validate the html form values. Also,note the "validateMethod" attribute used to specify the name of the method to invoke on the Validator objectsetup in the constructor of the BirthDateFormAction. The use of this attribute allows partial validation ofcomplex objects populated over several consecutive screens.

On error the action returns to the view state it came from. On success it transitions to the enterCardInformationview state:

<view-state id="enterCardInformation" view="cardForm"><transition on="submit" to="processCardFormSubmit" />

</view-state>

The logical view name "cardForm" is a global-forward in struts-config.xml resolving to/WEB-INF/jsp/cardForm.jsp. This JSP collects data for the remaining fields of the birthDate form object -"sendCard" and "emailAddress", and posts back to FlowAction with a submit image named "_eventId_submit".An event with the id of "submit" causes a transition to the processCardFormSubmit action state defined asfollows:

<action-state id="processCardFormSubmit"><action bean="formAction" method="bindAndValidate">

<attribute name="validatorMethod" value="validateCardForm" /></action><transition on="success" to="calculateAge" /><transition on="error" to="enterCardInformation" />

</action-state>

For this action state the bindAndValidate method of the formAction bean is used to populate and validate theremaining html form values. The "validateMethod" attribute specifies the name of the method to invoke on theValidator object specific to the fields loaded on the current screen.

On error the action returns to the view state it came from. On success it transitions to another action state calledcalculateAge:

<action-state id="calculateAge"><action bean="formAction" method="calculateAge" /><transition on="success" to="displayAge" />

</action-state>

The logic for the calculateAge action state is in the calculateAge method of the same formAction bean used fordata binding and validation. This demonstrates the flexibility Web Flow allows in properly structuring controland business logic according to function.

The caculateAge method performs business calculations and adds a string in request scope with the calculatedage. Upon successful completion the calculateAge action state transitions to the end view state:

<end-state id="displayAge" view="yourAge" />

Once again the logical view name "yourAge" is a global-forward in struts-config.xml resolving to/WEB-INF/jsp/yourAge.jsp. This JSP page retrieves the calculated age from request scope and displays theresults for the user.

Practical Use of Spring Web Flow

Spring Web Flow Version 1.0.5 99

Page 102: Spring Webflow Reference

The transition to the end state indicates the end of the web flow. The flow execution is cleaned up. If the webflow is entered again a new flow execution will start, creating a new form object named "birthDate" and placingit in flow scope.

6.10.5. Birthdate-alternate Web Flow

The birthdate-alternate web flow (/WEB-INF/birthdate-alternate.xml) offers an alternative way and morecompact way of defining the same web flow. For example the birthdate web flow defines two independentstates for the first screen - a view state (enterBirthdate) and an action state (processBirthdateFormSubmit). Inbirthdate-alternate those are encapsulated in the view state enterBirthdate as follows:

<view-state id="enterBirthdate" view="birthdateForm"><render-actions>

<action bean="formAction" method="setupForm" /></render-actions><transition on="submit" to="enterCardInformation">

<action bean="formAction" method="bindAndValidate"><attribute name="validatorMethod" value="validateBirthdateForm" />

</action></transition>

</view-state>

Here the setupForm action state is defined as a render-action of the enterBirthdate view state while thetransition to the next screen uses a nested action bean invoked before the transition occurs. Notice that successis implicitly required for the transition to occur. Similarly on error the transition does not occur and the sameview state is displayed again.

The second screen is also defined with a nested transition and action bean:

<view-state id="enterCardInformation" view="cardForm"><transition on="submit" to="calculateAge">

<action bean="formAction" method="bindAndValidate"><attribute name="validatorMethod" value="validateCardForm" />

</action></transition>

</view-state>

The remaining two states - calculateAge and displayAge are identical.

6.11. Phonebook-Portlet Example

6.11.1. Overview

The Phonebook-Portlet demonstrates how to run the Phonebook sample as a JSR-168 portlet. The functionalityfor Phonebook and Phonebook-Portlet including web flow definitions, JSP pages, and Java classes is the sameand already well documented. The focus in Phonebook-Portlet is specifically on how to configure and runPhonebook in a Portal container.

Note

JSR-168 defines portlets but not how portlets integrate into a portal container. This process is leftopen to portal vendors who have their own individual mechanisms. The Phonebook-Portlet sampleis configured to run with Apache Pluto - a reference implementation of the Java PortletSpecification. However, its dependence on Pluto is limited to configuration in web.xml. Hence it

Practical Use of Spring Web Flow

Spring Web Flow Version 1.0.5 100

Page 103: Spring Webflow Reference

should be easy to adapt for use in other Portal/Portlet implementations after learning thedeployment steps specific for that implementation.

6.11.2. Portal/Portlet Related Software Used in the Sample

This section provides a very brief introduction to the portal related supporting software used in the sample -namely Apache Pluto and the Portlet MVC framework. If this is not new for you feel free to skip to the nextsection.

6.11.2.1. Apache Pluto

For those familiar with servlet applications the process of deploying and running a portlet application can beconfusing and requires some explanation. Typically an application with JSR-168 portlets runs in one webappwhile a portal/portlet container runs in a separate webapp making cross-context calls to portlets. How exactlythis is configured depends on each portal vendor.

Pluto is an open-source reference implementation of the Java Portlet specification. The following general stepsare required to run portlets with it. First the the portlet application's web.xml is "injected" with configurationrequired for Pluto. Secondly Pluto's Portal web application, usually set to run athttp://localhost:8080/pluto/portal is used to add or remove portlets to one or more portal container pages.

The web.xml for the Phonebook-Portlet sample has already been "injected" with the configuration required forPluto 1.1.0. Although this enables it for use with Pluto you must still use the admin pages of Pluto's Portal webapplication to add the Phonebook-Portlet to a test portal page. For more information on how to do this pleasefollow instructions from Apache Pluto.

6.11.2.2. Portlet MVC Framework

The Portlet MVC framework represents Spring's support for JSR-168. It has many parallels with the SpringMVC framework such as the DispatcherPortlet, the Controller interface, handler mappings, view resolvers, andexception handlers. The main differences between Portlet MVC and Spring MVC have to do with the lifecyclesof a portlet and its distinct phases as defined in the Porlet Specification: the action and the render phases. Formore information see Chapter 16 (Portlet MVC Framework) from the Spring reference documentation.

6.11.2.3. Getting Phonebook Portlet up and Runnign with Apache Pluto

Since the phonebook portlet was tested with Apache Pluto we've decided to documents the steps taken todeploy and run it

1. Download the Pluto 1.1 binary distribution named pluto-current-bundle fromhttp://portals.apache.org/pluto

2. Unzip the binary distribution to any directory.

3. Create the directory [pluto-home]/webapps/swf-phonebook-portlet

4. Copy the content of[webflow-release]/spring-webflow-samples/phonebook-portlet/target/artifacts/war-expanded to thedirectory created in the previous step

5. Start Pluto with [pluto-home]/bin/startup

6. Go to http://localhost:8080/pluto/portal

Practical Use of Spring Web Flow

Spring Web Flow Version 1.0.5 101

Page 104: Spring Webflow Reference

7. Login as tomcat/tomcat (or any other user but see note below)

8. After logging in you will be taken to the Portal Test page.

9. Here you will see a Navigation pull-down menu at the top. Select 'Pluto Admin' from it to go to the PlutoAdmin page.

10. On the Pluto Admin page under Portlet Applications you will see a drop-down with available portletapplications

11. Select '/swf-phonebook-portlet' from it, then phonebook from the drop-down next to it, and then press the'Add Portlet' button

12. Use the Navigation menu at the top to go back to the Test Page. The Phonebook portlet should be present.

Note

The tomcat user must have the 'pluto' role. Open [pluto-home]/conf/tomcat-users.xml and ensurethe following lines are there:

<role rolename="pluto"/><user username="tomcat" password="tomcat" roles="tomcat,pluto"/>

6.11.3. Portlet.xml Configuration

Portlet.xml is a standard deployment descriptor where portlet resources are defined. The Phonebook-Portlet isbased the Portlet MVC DispatcherPorlet:

<portlet-class>org.springframework.web.portlet.DispatcherPortlet

</portlet-class>

The DispatcherPortlet is Spring's implementation of the Portlet interface dispatching requests for a portlet toregistered Portlet MVC handlers. The phonebook portlet is configured with the following Spring contextscontaining Portlet MVC handler, controller and view resolver beans:

<init-param><name>contextConfigLocation</name><value>

/WEB-INF/phonebook-portlet-config.xml /WEB-INF/phonebook-webflow-config.xml</value>

</init-param>

The above configuration defines phonebook as a portlet resource. In order to use it in a portal/portlet containeradditional web.xml configuration is required.

6.11.4. Web.xml Configuration

The Java Portlet Specification is defined as a layer over existing Servlet infrastructure. Therefore some sort of aservlet is required to accept servlet requests and expose portlet resources. Portal vendors provide such servletsand specific configuration varies by vendor. The Phonebook-Portlet has the following Apache Pluto servletdefinition and servlet mapping:

Practical Use of Spring Web Flow

Spring Web Flow Version 1.0.5 102

Page 105: Spring Webflow Reference

<!-- Generated Portlet Wrapper Servlet for Apache Pluto deployment --><servlet>

<servlet-name>phonebook</servlet-name><servlet-class>org.apache.pluto.core.PortletServlet</servlet-class><init-param>

<param-name>portlet-name</param-name><param-value>phonebook</param-value>

</init-param><load-on-startup>1</load-on-startup>

</servlet><servlet-mapping>

<servlet-name>phonebook</servlet-name><url-pattern>/PlutoInvoker/phonebook</url-pattern>

</servlet-mapping>

Note

The above configuration was auto generated using ant tasks from Apache Pluto 1.1.0. Thisconfiguration is included in web.xml for convenience and also as an example. For the mostup-to-date information on required configuration please check Pluto's documentation.

The web.xml configuration also contains the following servlet definition:

<servlet><servlet-name>viewRendererServlet</servlet-name><servlet-class>

org.springframework.web.servlet.ViewRendererServlet</servlet-class>

</servlet><servlet-mapping>

<servlet-name>viewRendererServlet</servlet-name><url-pattern>/WEB-INF/servlet/view</url-pattern>

</servlet-mapping>

The main purpose of this servlet is to allow reuse of Spring MVC's flexible view resolution and renderingcapabilities in a Portlet application. The DispatcherPortlet converts a PortletRequest/PortletResponse to anHttpServletRequest/HttpServletResponse and then performs an include of this servlet.

6.11.5. Portlet MVC Configuration

The phonebook-portlet-config.xml is very similar to the Spring MVC equivalent phonebook-servlet.xml fromthe Phonebook sample. The main difference is in the use of a PortletModeHandlerMapping:

<bean id="portletModeControllerMapping"class="org.springframework.web.portlet.handler.PortletModeHandlerMapping">

<property name="portletModeMap"><map>

<entry key="view" value-ref="flowController"/></map>

</property></bean>

and a PortletFlowController:

<bean id="flowController" class="org.springframework.webflow.executor.mvc.PortletFlowController"><property name="flowExecutor" ref="flowExecutor"/><property name="defaultFlowId" value="search-flow"/>

</bean>

Practical Use of Spring Web Flow

Spring Web Flow Version 1.0.5 103

Page 106: Spring Webflow Reference

A PortletModeHandlerMapping allows mapping specific to each portlet mode. The VIEW mode in this case ismapped to the flowController bean, which delegates the request to Web Flow's executor for launching orresuming a flow from a flow definition. For more information on Phonebook flow definitions please refer to thePhonebook sample documentation.

One last thing to observe is the following configuration in /WEB-INF/phonebook-webflow-config.xml:

<!-- Launches new flow executions and resumes existing executions. --><flow:executor id="flowExecutor" registry-ref="flowRegistry">

<flow:execution-attributes><!-- execution redirects don't apply in a Portlet environment --><flow:alwaysRedirectOnPause value="false"/>

</flow:execution-attributes></flow:executor>

As the comment indicates the default behavior of redirect after submit must be turned off in a portletenvironment where there is no HTTP redirect. For more information on the alwaysRedirectOnPause refer to thefollowing article.

Practical Use of Spring Web Flow

Spring Web Flow Version 1.0.5 104