Matt RaibleMatt Raible is a Web Developer and Java Champion. Connect with him on LinkedIn.

The Angular Mini-Book The Angular Mini-Book is a guide to getting started with Angular. You'll learn how to develop a bare-bones application, test it, and deploy it. Then you'll move on to adding Bootstrap, Angular Material, continuous integration, and authentication.

Spring Boot is a popular framework for building REST APIs. You'll learn how to integrate Angular with Spring Boot and use security best practices like HTTPS and a content security policy.

For book updates, follow @angular_book on Twitter.

The JHipster Mini-Book The JHipster Mini-Book is a guide to getting started with hip technologies today: Angular, Bootstrap, and Spring Boot. All of these frameworks are wrapped up in an easy-to-use project called JHipster.

This book shows you how to build an app with JHipster, and guides you through the plethora of tools, techniques and options you can use. Furthermore, it explains the UI and API building blocks so you understand the underpinnings of your great application.

For book updates, follow @jhipster-book on Twitter.

10+ YEARS


Over 10 years ago, I wrote my first blog post. Since then, I've authored books, had kids, traveled the world, found Trish and blogged about it all.

[TSE] Designing Stateful Web Application Control Flow with Erwin Vervaet

Spring Web Flow (SWF) does not fit into an application or a feature where free-flow navigation is required. It works best where you need to lock down and control navigation. SWF is not designed to be a web framework, but rather to solve the specific problem of navigation and state management between many pages.

Erwin is a Senior consultant at Ervacon and has extensive experience using Java SE and Java EE. He is the inventor and co-lead of the Spring Web Flow project.

Core Functionality

  • Navigation is controlled by a flow (complete navigational control)
  • Automatic state management (scoping, cleanup)
  • A flow is a reusable application module (fully encapsulated: input/output contract, black box)

Spring Web Flow provides Navigational Control. A flow definition controls the entire conversation. The flow is the controller and drives all navigation. When user input is required, the flow pauses and a view is rendered. Clients signal events and are unaware of overall navigation rules. The flow reacts to user events and decides what to do next. A flow is a simple Finite State Machine (a set of states with transitions b/w them). SWF is not a general purpose workflow engine. It's simplified for use with web conversations and lacks features like split and join.

SWF provides state management with web continuations. What is a web continuation you ask?

A continuation is a saved snapshot of the executable state of a program at any given point in time. It is possible to restore this state and restart the execution of the program from that point onward.

The flow execution repository takes a snapshot of flow execution for each request. In a sense, the flow execution becomes a continuation.

Spring Web Flow is a very advanced state management mechanism. It has fully automatic state management with scopes (converstation, flow, flash, request), cleanup, compatible with browser buttons (back, forward, refresh, new window). Finally, flows are observable using FlowExecutionListener.

To link to services (or call service-level beans), you can simply use your normal bean ids. You can subclass SWF's Action and inject your services into it. However, in most cases, you can simply use SWF's FormAction class. SWF can bind to any POJO method. For example:

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

This might bind to the following interface, which is wired up as the "phonebook" bean.

public interface Phonebook 
    public List<Person> search(SearchCriteria criteria)
    public Person getPerson(Long id)
    public Person getPerson(String userId)
}

To deploy a flow definition, you first have to define your flows in a flow registry.

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

A flow id is assigned by convention. For example, /WEB-INF/flows/search-flow.xml becomes "search-flow".

To execute a flow, you need to define a flow executor that manages flow on behalf of the client. It loads flow definitions (from flowRegistry), drives flow executions (launch, resume, refresh) and saves/loads flow execution b/w requests (execution repository and state management).

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

Finally, you'll need to configure a "Flow Controller". This is specific to the web framework you're using. Below is an example for Spring MVC:

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

SWF exposes some variables to the view model, namely "flowExecutionContext" and "flowExecutionKey". To participate in a flow execution, you have to submit _flowExecutionKey and _eventId parameters in every request. For a form, these can be hidden fields:

<form:form action="phonebook.htm" commandName="searchCriteria" method="post"> 
    <input type="hidden" name="_flowExecutionKey" value="${flowExecutionKey}"> 
    <input type="submit" class="button" name="_eventId_search" value="Search"> 
    ... 
</form:form> 

For links, you'll need to include these parameters as well:

<a href="phonebook.htm?_flowExecutionKey=${flowExecutionKey}&amp;_eventId=select&amp;id=${colleague.id}"> 
${colleague.firstName} ${colleague.lastName}</a>
NOTE: This morning, I asked Rob Harrop if the _flowExecutionKey hidden field will ever be auto-generated by the <form:form> tag. His response was that they are doing something to make this more automatic, but it may not happen in the context of the <form:form> tag.

Best Practices

By default, SWF does redirect after POST. To change it, you can configure the flowExecutor bean a bit differently.

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

You can also explicitly use the "redirect:" prefix in the view name. In other words, the best practice of "Redirect after POST" has been built-in for you.

SWF comes with 4 repository (storage) implementations:

  • simple: single flow execution per converstation (flowExecutionKey changes on every request), low resource usage, no browser button support. Use when you can lock down the browser and resources (memory) are scarce. By default, displays a nice stack trace (PermissionDeniedFlowExecutionAccessException) when you click back. Use case: your company has removed the back and forward buttons from end-user's customized browsers.
  • singleKey: same as simple repository, but keeps same flowExecutionKey over the lifecycle of the flow. Tricks the browser into thinking it keeps refreshing the same exact page - there is no browser history. They do this by using the exact same URL for every page. The nice thing about using this repository is it really does disable the back and forward buttons. Use case: low memory available and want to block back/forward button usage.
  • continuation: the default implementation if you don't specify the "repository-type" attribute on your flowExecutor. Allows free browsing in a controlled way. The downside is high memory usage because many snapshots are taken. Snapshots contain all the data associated with the conversation; more than just request parameters. Use when you have enough resources available and browser buttons need to be supported. The flowExecutionKey is different for each and every request in order to record the unique id of the snapshot.
  • client: flow execution stored in the flowExecutionKey and on the client. It's nice because there's low resource usage on the server. However, it only supports POST (b/c of GET URL length limits). It also requires more bandwidth, has security concerns and has no support for double submit out-of-the-box.

Best practice? Use the correct repository for your situation! Somebody asked if SWF provides the information to build a "breadcrumbs" type of menu. Erwin says "yes", but there's no way to easily access that information (i.e. with JSP tags). Another audience member asks if it's possible to invalid snapshots? Erwin says "no", but it is possible to configure the maximum number of snapshots to store. They are considering adding support for invalidating certain snapshots after you pass a certain state in the flow.

Even though I knew a lot about SWF going into this talk, I was very impressed with Erwin's presentation. He did an excellent job at doing live demos that showed the different features of SWF. Even better, he did them with SWF's "phonebook" application, so it should be possible to reproduce many of his demos. At the end of his presentation, Erwin listed a number of resources for Spring Web Flow:

I recently updated Spring Live's Chapter 13 for SWF 1.0, but Erwin and Keith's Expert Spring MVC and Web Flow (by Seth Ladd, Darren Davison, Steven Devijver and Colin Yates) is much better than my 10-page example. My updated chapter is currently in tech edit, so you may have to wait another couple weeks before it's in a released version.

Posted in Java at Dec 08 2006, 03:47:49 PM MST 5 Comments
Comments:

[Trackback] [TSE] Designing Stateful Web Application Control Flow with Erwin VervaetSpring Web Flow (SWF) does not fit into an application or a feature where free-flow navigation is required. It works best where you need to lock down and control navigation.Spring ...

Posted by Younghoe.Info on December 09, 2006 at 02:39 AM MST #

Hi Matt,

When you mention Erwin and Keith's book, which book is that? If you are refering to Expert Spring MVC and Web Flow, you should give credit to Colin Yates for those chapters. If they are writing their own book, that's awesome because Web Flow deserves a dedicated book.

Posted by Seth Ladd on December 09, 2006 at 03:23 AM MST #

Seth - I was referring to Expert Spring MVC and Web Flow. I don't know why I thought they wrote it. My apologies to you, Darren Davison, Steven Devijver and Colin Yates. I'll update the post.

Posted by Matt Raible on December 09, 2006 at 03:55 AM MST #

Is the invalidation of continuations a fact at this point?

Posted by Daniela on June 02, 2007 at 11:47 PM MDT #

hey Matt, first of all , i would like to thanks for sharing all the information adn knowledge and wisdown with openheart to you , thanks for given me reference of erwin book , i will definately going to buy this book beacuse it is related to my field. I have read Colin Yates article , i like them and found helpfull too and i agree web flow deserves a dedicated book. I will apply there code too.

Posted by Steve M. on September 22, 2007 at 07:46 AM MDT #

Post a Comment:
  • HTML Syntax: Allowed