This forum is now a read-only archive. All commenting, posting, registration services have been turned off. Those needing community support and/or wanting to ask questions should refer to the Tag/Forum map, and to http://spring.io/questions for a curated list of stackoverflow tags that Pivotal engineers, and the community, monitor.
No announcement yet.
What is spring web flow techniqually?Page Title Module
You're asking about its purpose, and how and why you would use it in a web application?
Its purpose is to provide a more controlled and stateful means of defining and executing the navigation in your web application. This also includes intelligent handling of the browser back button and history, tighter scoping (and thus cleanup) of attributes, and also adds in some support for (usually) painless AJAX updating (for most simple cases).
SWF works best with Spring MVC or with JSF. It occupies the role of the Controller in the MVC pattern, and though it CAN be used for your entire application, it is probably best used for only the parts of your application where it is best suited.
SWF is best suited for tightly-defined interactions, such as wizard-like sequences of pages and actions. Many web apps fall into this category. Some web apps have only pieces of functionality which best fall into this category.
SWF is worst-suited for apps or use cases with more freestyle navigation. SWF also isn't really RESTful, as URLs used when executing SWF are only valid for the lifetime of the session, and often are invalidated sooner. This also means URLs of an executing webflow are not bookmarkable.
For a quick compare/contrast with other web frameworks, keep in mind that most web frameworks are stateless, with the exception of session-scoped attributes. This means forced-navigation (arbitrarily invoking a action) is easy to do either by typing in the URL to the action direction, or using the browser back button or history to invoke the action. It can be a headache to guard against executing actions when the state data isn't valid. In addition, forced navigation can circumvent attribute cleanup or initialization, increasing the chances for an error, and incorrect execution, or leaked memory. These problems are not trivial, and can require quite a bit of plumbing code which can be tricky to implement correctly. It also ups the complexity of refactoring and maintenance.
SWF keeps together information about the flow (kinda like a use case) you are executing within, the state that you are on, your state (flow and view scope), and the possible transitions you can make from the state you are on. All of this is serialized and mapped to a flow execution ID and snapshot ID, both of which show up in your URL. When you submit to that URL, you are not addressing an action, but the actual state you are in. That way only allowed transitions from that state are accepted and processed as you have defined them.
Flow definitions are easy-to-read XML files which define your flow, the states in your flow, and the transitions between your states. The XML is written as a DSL, a Domain-Specific Language, which makes it easy to read and write. Flows are defined and execute like state machines, and thus are nearly directly translatable to state diagrams. There are a few plugins already which can give you a visual means of interacting with your flow definitions. Flows can also be called from different contexts (at different times, with different data, in different parts of the application), which give them quite a bit of flexibility and give them excellent potential for reusability.
Using the browser back button or history jumps to previous URLs, each of which has in the URL the execution and snapshot IDs corresponding with your state at the point in time when you were last at that page. That means that when you use the back button, you are dealing with the exact state of the data (flow and view scope) when you were last at the page. It's like a jump back in time, which tends to avoid the complexities of rolling back state.
New attribute scopes (flow and view scope) more tightly scope your data to the sections of the application where it's used. When you leave a view, data scoped to that view is cleaned up for you. When a flow ends, attributes scoped to that flow are also cleaned up for you.
Now, all that said, there are going to be scenarios where SWF's implementation can cause headaches. As mentioned, RESTful and bookmarkable URLs are not possible (out-of-box, at least) for executions-in-progress. Likewise, state saving beyond the end of a user's session isn't possible out-of-box. SWF's snapshotting mechanism, while giving you good back-button support, is essentially saving serialized copies of your entire state with each view-render. While you can define limitations for how many executions to allow, and how many snapshots to save (letting the oldest get cleaned up automatically), this may have an impact on your memory footprint, especially if you have a ton of users. Also, the snapshotting mechanism serializes your flow and view-scoped data, which can lead to unexpected behavior if you're also referencing that data from other scopes, like session, or if you're adding singleton or controller/service objects to flow or view scope, or even if you're referencing these kinds of objects from a flow or view-scoped attribute. Some of these problems may not be immediately apparent if you're using autowiring or similar IOC mechanisms without being mindful of the effects of serialization on parts of your object graph.
SWF also locks upon an executing conversation, with a 30-second timeout. While this prevents race conditions and other state havoc that would normally occur when two threads of execution execute simultaneously on the same state data (most web app frameworks won't handle this for you), it DOES essentially freeze your application since it only handles one request at a time. This means, for long-running requests, that you often will not be able to press any button or any link (that would signal an event handled by SWF, that is) until the current request completes.
Hopefully that gives you a good overview of what SWF is, what it can do for you, and how and when you might use it in your web app. I've also given you some situations where you may NOT want to use it, as well as some less well-known (and not very well communicated) consequences of using SWF and how they might impact or complicate your web app.
InverseFalcon: Thanks for your detailed answer. Is really appreciated.
Just another question: Spring webflow permits to define flows and follow them but just for the current session. It's not possible, I think, to save the flow state in a more permanent way, is it?
In other words: SWF is *not* a workflow engine. I cannot assign work to other partecipants, save the state of the flow on a persistent layer and find my tasks on a worklist on the next day. Am I right?
Since I need something like this, is there a "spring" solution to this?
You are correct, out-of-box SWF is not a workflow engine with persistence beyond the current session. Its purpose is to make it easier for developers to define the navigation between pages and actions in a logical, reusable, and graphical way, and to better control the navigation and manage the lifecycle of flow attributes.
I've only briefly looked what you're after...not in depth, so I won't be of much help. From what I can tell, however, the implementation of the snapshotting mechanism is tied to the session. To persist it, you'll need to use your own snapshot solution. I haven't looked at how difficult it is to custimize this part of SWF. I DO know that this question has been asked before, so maybe someone else is working on it, or developed their own solution.
I know that it's possible to customize conversation management to store flow data in a more permanent store than the Session (i.e. the filesystem or a DB or something). If memory serves, it's a matter of replacing the default ConversationManager with one that does what you want. I was playing with that a while ago before Real Life got in the way, and I never got past the theoretical stages.
This may be a little easier to do when Spring 3.1 (and possibly Web Flow 3.0) come out - I know the former is due to have some advanced conversation management features in it directly.