Now we have Spring MVC working, so it's time to expand on that and get Spring Web Flow working too. We'll start by creating a very simple flow—one that has only a single view state. First we'll look at the updated Spring application context configuration. After that we'll look at the flow definition itself.
To make it easier for you to follow along, here's the updated, one-state version of our shopping cart:
Because we're now using SWF, we have additional dependencies. Here's the full set so far:
These come from the Spring 2.5.4 distribution. [download]
spring.jar (located in /spring-framework-2.5.4/dist)spring-webmvc.jar (located in /spring-framework-2.5.4/dist/modules)commons-logging.jar (located in /spring-framework-2.5.4/jakarta-commons)You will need the following JARs from the Spring Web Flow 2.0 distribution. [download]
spring-webflow-2.0.0.jarspring-binding-2.0.0.jarspring-js-2.0.0.jarYou will need the following JAR from the OGNL web site:
ognl-2.6.9.jarSpring Web Flow uses either OGNL or Unified EL for parsing
expressions. For this article I arbitrarily picked OGNL though you
can use jboss-el.jar (currently the only Unified EL
implementation that will work with SWF) too.
For now we aren't making any changes to either of these at all.

Before jumping into the code, let's do a quick overview of the various components involved. Please see Figure 2.
We already saw DispatcherServlet in
web.xml. (So it's not part of
mycart-servlet.xml; we're discussing it here just to show
the relationship between the servlet and the
FlowController.) DispatcherServlet is the
Spring MVC front controller and it receives any Spring MVC
requests—including SWF requests, as SWF is based on Spring
MVC—according to your web.xml configuration.
We're using SimpleUrlHandlerMapping to map flow
requests from DispatcherServlet to
FlowController.
So now FlowController has the request.
FlowController is just a Spring MVC controller that
receives flow requests and passes them to FlowExecutor
for actual processing.
FlowExecutor contains the actual logic for processing
Spring Web Flow requests. Among other things it determines for any
given request which flow is involved and figures out what state
transition to enact, based on the request.
When FlowExecutor needs a flow, it grabs the flow from
the FlowRegistry, which is responsible for loading the
flow from a flow configuration file and maintaining it on behalf of
the FlowExecutor.
FlowBuilderServices is just a container for various
services that FlowRegistry needs when constructing flows.
This includes, for example, a service to provide for the creation of
view factories. In our example, we will see that we're specifically
using a MvcViewFactoryCreator, which creates view
factories for Spring MVC views.
Finally, we define a ViewResolver, which is a Spring
MVC interface that carries logical view names to physical resources
(such as JSPs). For example, a ViewResolver might carry
the logical name checkout/viewcart to the physical
resource /WEB-INF/jsp/checkout/viewcart.jsp.
And finally here's the configuration file itself:
/WEB-INF/mycart-servlet.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:flow="http://www.springframework.org/schema/webflow-config"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/webflow-config
http://www.springframework.org/schema/webflow-config/spring-webflow-config-2.0.xsd">
<!-- SPRING MVC STUFF -->
<!-- This activates post-processors for annotation-based config -->
<!-- http://www.infoq.com/articles/spring-2.5-part-1 -->
<context:annotation-config/>
<context:component-scan base-package="mycart"/>
<!-- Enables POJO @Controllers (like CartController) -->
<bean class=
"org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping"/>
<!-- Maps flow requests from DispatcherServlet to flowController -->
<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<value>
/account/register.do=flowController
</value>
</property>
<property name="alwaysUseFullPath" value="true"/>
</bean>
<!-- Enables annotated methods on POJO @Controllers (like CartController) -->
<bean class=
"org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"/>
<!-- Enables plain Controllers (e.g. FlowController) -->
<bean class=
"org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/>
<!-- Maps a logical view name to a physical resource -->
<bean id="viewResolver" class=
"org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>
<!-- SPRING WEB FLOW STUFF -->
<bean id="flowController" class=
"org.springframework.webflow.mvc.servlet.FlowController">
<property name="flowExecutor" ref="flowExecutor"/>
</bean>
<flow:flow-executor id="flowExecutor" flow-registry="flowRegistry"/>
<!-- This creates an XmlFlowRegistryFactory bean -->
<flow:flow-registry id="flowRegistry"
flow-builder-services="flowBuilderServices">
<flow:flow-location path="/WEB-INF/flows/register.xml"/>
</flow:flow-registry>
<flow:flow-builder-services id="flowBuilderServices"
view-factory-creator="viewFactoryCreator"/>
<bean id="viewFactoryCreator" class=
"org.springframework.webflow.mvc.builder.MvcViewFactoryCreator">
<property name="viewResolvers">
<list>
<ref bean="viewResolver"/>
</list>
</property>
</bean>
</beans>
Now let's look at our basic flow definition, which will initially at least be much simpler than the application context file.