Concept Overview
The previous tutorial introduced spring web flow and the concept of states, transitions and flow data. In this tutorial we show an example of how a sub flow can be used a state in a root flow
Sample Program Overview
We continue with the earlier example of the logic application, however we add the functionality of creating a new account if the user does not have an account. The new account creation is a sub flow
- 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
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 the following:
- Creating a new account (see lines 27-34 below)
- Authenticating the login credentials of the user (see lines 11-25 below) and throwing IncorrectLoginCredentialsException if the login credentials are incorrect (see line20 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)
and create-new-account-flow.xml
(also 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-15 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).
When a user requests to create a new account then the appropriate transtion to launch the
createNewAccountSubFlowState
is invoked (see line 14 below). (see
Create an action state to perform login (see lines 17-24 below) which is executed in the following steps:
- Call the LoginService.performLogin() method by passing the ‘loginCredentials’ flow variable (see line 18 below)
- If login is successful then the flow goes to ‘displayLoginSuccessView’ state (see line 20 below).
- If an exception occurs during login due to incorrect login credentials then the flow goes to ‘displayLoginErrorView’ state (see lines 22-23 below).
Create a view state called ‘displayLoginSuccessView’ which refers to display_login_success.jsp (see line 28 below).
Create a view state called ‘displayLoginErrorView’ which refers to display_login_error.jsp (see line 30 below).
Create a subflow-state called
createNewAccountSubFlowState
(see lines 32-34 below). This refers to the subflow called
createNewAccountFlow
(see line 32 below) defined in login-webflow-config.xml
(described earlier)
indicating that this subflow should be initiated.
It also declares that when ‘newAccountCreated’ end-state of ‘createNewAccountFlow’ subflow is reached then the flow should continue to the ‘displayLoginView’ state (see line 33 below).
This demonstrates the usage of subflow-state within Spring Web Flow.
Create the create-new-account-flow.xml configuration file (see below). This configuration file defines the sub flow.
Declare the start state for this sub-flow as ‘createNewAccountView’ (see line 6 below). This indicates that when this sub flow is launched then the first state to be called is ‘createNewAccountView’.
Declare the ‘loginCredentials’ flow variable (see line 9 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 ‘createNewAccountView’ (see lines 13-15 below) which refers to create_new_account.jsp (see line 13 below). It accepts the ‘loginCredentials’ flow variable as a model (see line 13 below) which will be bound to the to the create_new_account.jsp.
When the user enters the new account information then the new account create action is performed. This is modelled using Transitions (see line 14 below).
Define an action state to create a new account (see lines 17-26 below) which is executed in the following steps:
- Call the LoginService.createNewAccount() method by passing the ‘loginCredentials’ flow variable (see line 18 below)
- If new account creation is sucessful then the flow goes to ‘newAccountCreated’ state (see line 20 below).
- If an exception occurs during creation of new account then the flow goes to ‘displayLoginErrorView’ state (see lines 22-23 below).
Create an end state called ‘newAccountCreated’ (see line 28 below) which marks the end of this sub flow. This demonstrates the usage of end state
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 (see line 6 below). 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.
Add a link to launch the ‘Create New Account’ sub flow (see line 31 below) by using the URL
${flowExecutionUrl}&_eventId=createNewAccountRequested’
.
This URL has the following components:
- flowExecutionUrl: This represents the context-relative URI for the current flow execution view-state.
- _eventId=createNewAccountRequested: This specifies the event that occurs when the user click on this link. Note that the ‘createNewAccountRequested’ event is mentioned as a transition within ‘displayLoginView’ view state described the login-flow.xml described earlier. This tells Spring Web Flow that the ‘createNewAccountRequested’ event has occured and that the appropriate transition needs to be invoked.
Create create_new_account.jsp (as shown below) to display a form to enter the new user’s account credentials (see lines 6-26 below).
When a user enters his new account credentials and presses the ‘Submit’ button then the URL represented by
${flowExecutionUrl}&_eventId=accountInformationEntered’
is called. This URL has the following components:
- flowExecutionUrl: This represents the context-relative URI for the current flow execution view-state.
- _eventId=accountInformationEntered: This specifies the event that occurs when the user creates a new account. Note that the ‘accountInformationEntered’ event is mentioned a transition within ‘createNewAccountView’ view state described the create-new-account-flow.xml described earlier. This tells Spring Web Flow that the ‘accountInformationEntered’ 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 springwebflowusingsubflows-installer.jar and execute the jar using
java -jar springwebflowusingsubflows-installer.jar
command)
This demonstrates the running of this sample code.
This source code for this program is downloaded in the folder specified by you (say, C:\Temp) as an eclipse project called
springwebflowusingsubflows
. 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.