Concept Overview
Spring Web Flow is a framework that allows development of a flow in a web application. The flow guides user from one element of the application to another.
How Does it Work
Spring Web Flow uses the Spring MVC framework. The DispatcherServlet handles the request. A FlowHandlerMapping is used to map the request to a particular Web Flow. Look at this link to get an idea of how DispatcherServlet works. The FlowHandlerMapping is provided an instance of FlowRegistry. The FlowRegistry has the definitions for the flow. The FlowHandlerMapping maps the request to a FlowHandlerAdapter which is responsible for handling the flow requests. The FlowHandlerAdapter is provided with an instance of FlowExecutor which is responsible for the actual flow lifecycle. Lets look at the above classes in brief
Important classes
- FlowHandlerMapping – This is a HandlerMapping that creates a URL from the ids registered in the flow registry. It returns a FlowHandler if a matching id is found in the flow registry.
- FlowHandler – This is a controller helper that has the reference to the actual flow. It handles the execution of the flow, its outcomes and exceptions.
- FlowHandlerAdapter – This is the HandlerAdapter for web flows. It delegates work to the mapped FlowHandler.
- FlowExecutor – This is the central class of the Flow and is the facade for the actual flow. It manages creating of new flows or resuming existing flows. It is an entry into the Spring web flow system.
- FlowDefinition – This class stores the definition of the flow. It contains the set of states that form part of the flow. Each flow has one start state.
- FlowRegistry – This class contains all the flow definitions.
What are the different parts of a flow
The web flow has three main parts – States, Transition and Data.
States – States are points on the flow where an action happens or decision is made or a view is displayed. The end of a flow is also a state. Sometimes, to increase brewity, a subset of a flow can be combined together to form a sub-flow and then the sub-flow is a state in the main flow.
Transitions – Transition connects two states. A movement of request from one state to another is called a transition.
Data – Data is the information that is carried from one state to another. The life span of the data depends on the scope with which it is declared.
States– There are five kinds of states
- View States – A view state displays information to a user or obtains user input using a form. a model can be passed to bind the elements of the form. The view may be implemented as any view defined in spring mvc. (e.g. JSP)
- Action States – Action states are where actions are perfomed by the spring beans. The action state transitions to another state. The action states generally have an evaluate property that describes what needs to be done. The evaluate is generally a method of one of the registered spring beans. The evaluate expression is a SpEL. More than one action can be configured in which case the actions will be executed one after the other.
- Decision States: Decision state is where a decision is made. A decision state has two transitions depending on whether the decision evaluates to true or false.
- Subflow States – It may be advantageous to call another flow from one flow to complete some steps. The sub flow returns to the original flow when it is complete. Data may be passed from the calling flow into the subflow and output data from the subflow may be retrieved into the calling flow.
- End States – The end state signifies the end of flow. If the end state is part of a root flow then the execution is ended. However, if its part of a sub flow then the root flow is resumed.
Flow Data Scopes
Flow Data can be stored as variables that can be created using the ‘var’ element or using the evaluate expression.
Variable scope – The lifespan of the variable depends on the scope with which it is declared. The scopes available are:
- Conversation – The conversation scope starts when a flow starts and ends when the flow ends. It is available in sub flows
- Flow – Available within a flow. Not available in sub flows
- Request – Available during the life of a request in a flow
- Flash – Available during the lifetime of a flow. However, once a state is rendered, the variable is cleared.
- View – Available only during the lifetime of a view. Created when a view is created and destroyed once a view is destroyed
Sample Program Overview
We take a very simple example to explain spring flow. Consider a login system. The user first sees a login page. She types in the username and password and hits Enter. If the login is successful sucess view is displayed else error view is displayed.
- commons-beanutils.jar
- commons-collections.jar
- commons-digester.jar
- el-api.jar
- el-ri-1.0.jar
- org.springframework.aop.jar
- org.springframework.asm.jar
- org.springframework.beans.jar
- org.springframework.context.jar
- org.springframework.context.support.jar
- org.springframework.core.jar
- org.springframework.expression.jar
- org.springframework.web.jar
- org.springframework.web.servlet.jar
- retrotranslator-runtime-1.2.3.jar
- servlet-api-2.5.jar
- spring-binding-2.4.0.M1.jar
- spring-js-2.4.0.M1.jar
- spring-webflow-2.4.0.M1.jar
- springwebflow.jar
Create LoginCredentials class as show below.
This represents a model that will hold values for login name and password (see lines 9-10 below).
This shall be defined as a Flow Variable
(described later)
so that it can be passed across various states.
Create the LoginService class (as shown below).
It is a service class that is responsible for checking the login credentials of the user (see lines 9-10 below). It returns ‘success’ when the login name and password are correct (see line 12 below) and throws
IncorrectLoginCredentialsException
when login credentials are incorrect (see line 14 below).
Create the IncorrectLoginCredentialsException class (as shown below). This exception is thrown from LoginCredentials class
(described above)
when the login credentials of the user are incorrect.
Create the web.xml configuration file (as shown below).
Create a servlet mapping with name
login
(see lines 22-25 below) and define the corresponding servlet using Spring
DispatcherServlet
class (see lines 8-20 below).
It includes three spring configuration files: login-servlet-config.xml, login-webflow-config.xml and spring-config.xml (see lines 13-17 below).
Create the login-servlet-config.xml.
This is used to declare
FlowHandlerMapping
bean which tells
DispatcherServlet
defined in
web.xml
to send the requests to Spring Web Flow (see lines 19-21 below). It refers to ‘loginFlowRegistry’ bean defined in login-webflow-config.xml
(described below)
It also declares the
FlowHandlerAdapter
bean which acts as a Controller class and handles all requests coming to Spring Web Flow. It refers to ‘loginFlowExecutor’ bean defined in login-webflow-config.xml
(described below)
Create login-webflow-config.xml as shown below.
It defines the ‘loginFlowExecutor’ (see line 12 below) responsible for executing the login related web flow.
It also defines the ‘loginFlowRegistry’ (see lines 15-17 below) that holds references to all the flow related configurations. In this case, it refers to login-flow.xml
(described later)
Create the spring-config.xml file (as shown below)
Declare the loginService bean referring the LoginService class
(described earlier)
Create the login-flow.xml configuration file. This is the main configuration that is used to define Spring Web Flow.
Declare the ‘loginCredentials’ flow variable (see line 8 below). It refers to the
LoginCredentials
class
(described earlier)
. This flow variable is used to hold the value of login name and password entered by the user.
Create a view state called ‘displayLoginView’ (see lines 12-14 below) which refers to display_login.jsp (see line 12 below). It accepts the ‘loginCredentials’ flow variable as a model (see line 12 below) which will be bound to the to the display_login.jsp.
When the user enters the login credentials then login action is performed. This is modelled using Transitions (see line 13 below).
Create an action state to perform login (see lines 16-23 below) which is executed in the following steps:
- Call the LoginService.performLogin() method by passing the ‘loginCredentials’ flow variable (see line 17 below)
- If login is sucessful then the flow goes to ‘displayLoginSuccessView’ state (see line 19 below).
- If an exception occurs during login due to incorrect login credentials then the flow goes to ‘displayLoginErrorView’ state (see lines 21-22 below).
Create a view state called ‘displayLoginSuccessView’ which refers to display_login_success.jsp (see line 27 below).
Create a view state called ‘displayLoginErrorView’ which refers to display_login_error.jsp (see line 29 below).
Create display_login.jsp (as shown below) to display a form to enter the user’s login credentials.
Note that the names of the input fields ‘loginName’ and ‘password’ match with the members of LoginCredentials class
(described earlier)
Also note the hidden field _flowExecutionKey (see line 8 below). It is used to uniquely identifies a flow execution.
When the user enters his login credentials and presses the ‘Login’ button then the URL represented by
${flowExecutionUrl}&_eventId=loginCredentialsEntered’
is called. This URL has the following components:
- flowExecutionUrl: This represents the context-relative URI for the current flow execution view-state.
- _eventId=loginCredentialsEntered: This specifies the event that occurs when the user enters the login credentials. Note that the ‘loginCredentialsEntered’ event is mentioned a transition within ‘displayLoginView’ view state described the login-flow.xml described earlier. This tells Spring Web Flow that the ‘loginCredentialsEntered’ event has occured and that the appropriate transition needs to be invoked.
Create display_login_success.jsp (as shown below) which displays the successful login message.
Create display_login_eror.jsp (as shown below) which displays a message that the login credentias are incorrect.
This sample program has been packaged as a jar installer which will copy the source code (along with all necessary dependencies)on your machine and automatically run the program for you as shown in the steps below. As this sample program contains Java Server Pages (JSPs), you will need Java Development Kit (JDK preferably 1.5 or higher) on your machine so that the JSPs can be complied locally. Note that no other setup is required on your machine! Also please ensure that the port 8080 is not being used by any other program on your machine.
(Alternatively you can go the folder containing the springwebflow-installer.jar and execute the jar using
java -jar springwebflow-installer.jar
command)
This demonstrates the successful execution of Spring Web Flow sample for a typical login scenario.
This source code for this program is downloaded in the folder specified by you (say, C:\Temp) as an eclipse project called
springwebflow
. All the required libraries have also been downloaded and placed in the same location. You can open this project from Eclipe IDE and directly browse the source code. See below for details of the project structure.
Hi
I tried the same example and it worked fine up to the login page the after hitting the login button it says “Property or field ‘ValidateCredentials’ cannot be found on object of type ‘org.springframework.webflow.engine.impl.RequestControlContextImpl’ – maybe not public?”
here ValidateCredentials is my service class
Please help!
Great example for a quick start! Super!!
Thank you so much for clear introduction with example
Hi Sir ,
First thanks for the above description of Spring webflow .
Sir I cannot find the source code for the above webapplication ,So can you please send me the above source code tomy mail .
Thanks
Hi,
Please please please provide the source code.
Thanks