This article shows you how to get started with Spring Web Flow (SWF) 2.0 by building a simple shopping cart application. We'll do this as a series of steps:
SWF 2.0 is at the time of this writing very new, and there are several differences as compared to SWF 1.0.x. We will not however spend much time discussing those differences; instead we'll just focus on SWF 2.0.
To get the most out of this article, you should already be familiar with Spring in general and Spring MVC in particular.
Spring Web Flow builds upon Spring MVC to support user-level, application-directed control flows. For example, an e-commerce application may need to guide the end user through a checkout process that spans several web pages. The flow is not simply a multipage form (Spring MVC itself already supports that); rather it is a multistep process involving standard control flow constructions such as decisions ("please confirm or cancel your order"), loops ("we recommend products x, y, z... add as many as you like to your order") and subflows ("are you a new customer? please create an account"). In general, implementing such flows is not trivial. SWF is an elegant solution to just this sort of problem.
To understand better, contrast application-directed interactions with the user-directed interactions that typically constitute the main part of an application's functionality. In user-directed interactions, the end user picks some function from a set of available functions, provides some parameters around that function, and then asks the application to carry it out. For instance, the end user tells Photoshop to fill a selected region with "evil green" (RGB 00FF00). The app dutifully does just that, and control returns to the end user.
There are many cases, however, in which we want the application to drive a complex interaction between itself and the end user. Perhaps the most obvious example is the one I mentioned above: the e-commerce checkout process. See Figure 1 for one possible flow (and in fact this is the flow we're going to implement):

In the checkout flow above, we have a starting state, an end state, and several intermediate states. In the first state, we show the customer the contents of a shopping cart, along with some recommended products that the customer may want to buy. The customer can add any of those products to the shopping cart, or he might decide to move forward by indicating whether he is a new or returning customer. If he's a new customer, he'll need to create an account; otherwise he can just log in with his existing account. In either case, he'll need to select a payment method, provide shipping information, and so forth. At any step along the way he can cancel out of the checkout process.
While you can certainly implement that flow without SWF, there are some challenges involved if you're doing it from scratch. Let's take a look at some of those.
Understanding flow logic. For one, because the logic behind the flow itself is reasonably complex, it would be nice to be able to isolate the flow and its logic from the various pieces (like JSP pages, business logic, etc.) that make it up. But the most straightforward implementation of flow logic would most likely involve distributing the flow logic (such as state transitions) across lots of different files. So one challenge is that you either have to do a lot of extra work to externalize the flow logic, or else you have to live with that logic being distributed, which makes it much harder to understand.
Reusing flow logic. Another challenge is related to the fact that a flow has a logical structure that stands on its own, and in many cases you'd like to be able to reuse that—either across multiple apps, or else in multiple places within a single app. This is hard to accomplish without an easy way to isolate that flow.
Getting the implementation right. A third challenge is just that it's easy to get the technical details wrong. For instance, what happens if the end user hits the browser's back button in the middle of the flow? If the previous page had a form, we don't usually want the browser to confuse the user with a warning about resubmitting data or whatever. Coding up flows from scratch means that you have to handle this sort of thing explicitly. It would be nice not to have to mess around with this kind of thing—to have it handled automatically for you.
That's enough of an overview for us to get started. Let's now look at setting up our sample project.