diff --git a/spring-webflow-samples/getting-started-with-spring-webflow/src/main/webapp/WEB-INF/tutorial/webflowExercise.jsp b/spring-webflow-samples/getting-started-with-spring-webflow/src/main/webapp/WEB-INF/tutorial/webflowExercise.jsp index f26cb36f..835b3545 100644 --- a/spring-webflow-samples/getting-started-with-spring-webflow/src/main/webapp/WEB-INF/tutorial/webflowExercise.jsp +++ b/spring-webflow-samples/getting-started-with-spring-webflow/src/main/webapp/WEB-INF/tutorial/webflowExercise.jsp @@ -3,8 +3,13 @@ Getting Started with Spring Web Flow: Creating Your First Web Flow + " type="text/css" /> + " type="text/css" /> + + + - +

Creating Your First Web Flow

@@ -28,185 +33,211 @@

Step-by-step instructions for creating your first flow using the Eclipse-based SpringSource Tool Suite IDE:

-

Setup the project development environment

-
    -
  1. - Download SpringSource Tool Suite (STS) and the latest Spring Web Flow 2.0.x release. - After downloading completes, extract both archives to your directory of choice. -
  2. -
  3. - Open STS and access File -> Import... -> Existing Projects Into Workspace. Select Browse... and navigate to where you extracted the Spring Web Flow release. - Select the spring-webflow-samples/getting-started-with-spring-webflow folder and import the project. -
  4. -
  5. - After the project import, if you do not already have a servlet container such as Tomcat installed on your workstation you can uses STS to install an embedded Tomcat instance. - To do this, select the SpringSource logo on the tool bar, access the Configuration tab, and select Create Server Instance. -
  6. -
  7. - Next, right-click on the project in your Package Explorer view, and select Run On Server. - Select the server runtime you wish to deploy to and finish to deploy the project. - You should see the tutorial welcome page appear in the embedded web browser. - Alternatively, you can access the application in an external browser such as Firefox at http://localhost:8080/getting-started-with-spring-webflow -
  8. -
-

Create your first helloworld flow

-
    -
  1. - Once the application is running, create a new directory for your flow inside /src/main/webapp/WEB-INF; name the directory helloworld. - Next, right-click on the directory and access New -> Spring Web Flow Definition. - Enter the filename helloworld-flow.xml and finish. - The flow definition will be generated for you with an initial view-state named start. -
  2. -
  3. - Go ahead and create a start.jsp in your flow directory and paste in the following: -
    -	<html>
    -		<head>
    -			<title>Hello world!</title>
    -		</head>
    -		<h1>
    -			Hello world!
    -		</h1>
    -	</html>
    -		
    -
  4. -
  5. - From the Servers view, restart your server, then startup your flow by accessing http://localhost:8080/getting-started-with-spring-webflow/app/helloworld. - You should see your Hello world! message display. - Note you only have to restart your server when you add new flows to the system. When you change flows, changes will be refreshed automatically. -
  6. -
-

Add a navigation rule

-
    -
  1. - Next, try transitioning your flow from one state to another to implement a navigation rule. In your helloworld flow, add the following transition to your start view-state: -
    -	<transition on="submit" to="page2" />
    -		
    - Then define your page2 view-state: -
    -	<view-state id="page2">
    -	</view-state>
    -		
    - And the corresponding page2.jsp: -
    -	<html>
    -		<head>
    -			<title>Hello world!</title>
    -		</head>
    -		<h1>
    -			This is page 2!
    -		</h1>
    -	</html>
    -		
    - Finally, create a button on your start.jsp that raises the submit event to trigger the state transition: -
    -	<form method="post">
    -		<input type="submit" name="_eventId_submit" value="Submit" />
    -	</form>
    -		
    - Click the button and you should be taken to page 2. -
  2. -
-

Add a dynamic navigation rule

-

- Web flow excels at implementing dynamic navigation logic that takes a user through different paths based on what they enter or who they are. -

-
    -
  1. - Try implementing a dynamic navigation rule by first adding a bound checkbox to your start.jsp. - Do this by replacing the contents of your start.jsp with the following snippet: -
    -	<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
    -	<html>
    -		<head>
    -			<title>Hello world!</title>
    -		</head>
    -		<h1>
    -			Hello world!
    -		</h1>
    -		<form:form method="post" modelAttribute="helloWorldForm">
    -			<form:checkbox path="selected" />
    +
    +

    Setup your project

    +
      +
    1. + Download SpringSource Tool Suite (STS) and the latest Spring Web Flow 2.0.x release. + After downloading completes, extract both archives to your directory of choice. +
    2. +
    3. + Open STS and access File -> Import... -> Existing Projects Into Workspace. Select Browse... and navigate to where you extracted the Spring Web Flow release. + Select the spring-webflow-samples/getting-started-with-spring-webflow folder and import the project. +
    4. +
    5. + After the project import, if you do not already have a servlet container such as Tomcat installed on your workstation you can uses STS to install an embedded Tomcat instance. + To do this, select the SpringSource logo on the tool bar, access the Configuration tab, and select Create Server Instance. +
    6. +
    7. + Next, right-click on the project in your Package Explorer view, and select Run On Server. + Select the server runtime you wish to deploy to and finish to deploy the project. + You should see the tutorial welcome page appear in the embedded web browser. + Alternatively, you can access the application in an external browser such as Firefox at http://localhost:8080/getting-started-with-spring-webflow +
    8. +
    +
    +
    +

    Create your first helloworld flow

    +
      +
    1. + Once the application is running, create a new directory for your flow inside /src/main/webapp/WEB-INF; name the directory helloworld. + Next, right-click on the directory and access New -> Spring Web Flow Definition. + Enter the filename helloworld-flow.xml and finish. + The flow definition will be generated for you with an initial view-state named start. +
    2. +
    3. + Go ahead and create a start.jsp in your flow directory and paste in the following: +
      +		<html>
      +			<head>
      +				<title>Hello world!</title>
      +			</head>
      +			<h1>
      +				Hello world!
      +			</h1>
      +		</html>
      +			
      +
    4. +
    5. + From the Servers view, restart your server, then startup your flow by accessing http://localhost:8080/getting-started-with-spring-webflow/app/helloworld. + You should see your Hello world! message display. + Note you only have to restart your server when you add new flows to the system. When you change flows, changes will be refreshed automatically. +
    6. +
    +
    +
    +

    Add a navigation rule

    +
      +
    1. + Next, try transitioning your flow from one state to another to implement a navigation rule. In your helloworld flow, add the following transition to your start view-state: +
      +		<transition on="submit" to="page2" />
      +			
      + Then define your page2 view-state: +
      +		<view-state id="page2">
      +		</view-state>
      +			
      + And the corresponding page2.jsp: +
      +		<html>
      +			<head>
      +				<title>Hello world!</title>
      +			</head>
      +			<h1>
      +				This is page 2!
      +			</h1>
      +		</html>
      +			
      + Finally, create a button on your start.jsp that raises the submit event to trigger the state transition: +
      +		<form method="post">
       			<input type="submit" name="_eventId_submit" value="Submit" />
      -		</form:form>		
      -	</html>
      -		
      -
    2. -
    3. - Next, create a HelloWorldForm class in the org.springframework.webflow.samples.helloworld package with the following code: -
      -	package org.springframework.webflow.samples.helloworld;
      +		</form>
      +			
      + Click the button and you should be taken to page 2. +
    4. +
    +
    +
    +

    Add a dynamic navigation rule

    +

    + Web flow excels at implementing dynamic navigation logic that takes a user through different paths based on what they enter or who they are. +

    +
      +
    1. + Try implementing a dynamic navigation rule by first adding a bound checkbox to your start.jsp. + Do this by replacing its contents with the following snippet: +
      +		<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
      +		<html>
      +			<head>
      +				<title>Hello world!</title>
      +			</head>
      +			<h1>
      +				Hello world!
      +			</h1>
      +			<form:form method="post" modelAttribute="helloWorldForm">
      +				<form:checkbox path="selected" />
      +				<input type="submit" name="_eventId_submit" value="Submit" />
      +			</form:form>		
      +		</html>
      +			
      +
    2. +
    3. + Next, create a HelloWorldForm class in the org.springframework.webflow.samples.helloworld package with the following code: +
      +		package org.springframework.webflow.samples.helloworld;
      +		
      +		import java.io.Serializable;
      +		
      +		public class HelloWorldForm implements Serializable {
      +		    private boolean selected = true;
      +		    
      +		    public boolean isSelected() {
      +		        return selected;
      +		    }
      +		    
      +		    public void setSelected(boolean selected) {
      +		        this.selected = selected;
      +		    }
      +		}
      +			
      +
    4. +
    5. + At the top of your helloworld-flow, declare the HelloWorldForm as a flow variable: +
      +		<var name="helloWorldForm" class="org.springframework.webflow.samples.helloworld.HelloWorldForm" />
      +			
      + Then update your start view-state to use this variable as its data model, enabling automatic model binding and validation: +
      +		<view-state id="start" model="helloWorldForm"> ...	
      +			
      +

      + Refresh your flow and the checkbox should render checked since the default value for the HelloWorldForm selected property is true. + Uncheck the box and submit and go back in your browser and the unchecked status should be preserved. +

      +
    6. +
    7. + Now insert a decision state that says if the checkbox is selected goto page2, else goto a new page3: +
      	
      +		<decision-state id="isSelected">
      +			<if test="helloWorldForm.selected" then="page2" else="page3" />
      +		</decision-state>
       	
      -	import java.io.Serializable;
      -	
      -	public class HelloWorldForm implements Serializable {
      -	    private boolean selected = true;
      +		<view-state id="page2">
      +		</view-state>	
       	    
      -	    public boolean isSelected() {
      -	        return selected;
      -	    }
      -	    
      -	    public void setSelected(boolean selected) {
      -	        this.selected = selected;
      -	    }
      -	}
      -		
      -
    8. -
    9. - At the top of your helloworld-flow, declare the HelloWorldForm as a flow variable: -
      -	<var name="helloWorldForm" class="org.springframework.webflow.samples.helloworld.HelloWorldForm" />
      -		
      - Then update your start view-state to use this variable as its data model, enabling automatic model binding and validation: -
      -	<view-state id="start" model="helloWorldForm"> ...	
      -		
      -

      - Refresh your flow and the checkbox should render checked since the default value for the HelloWorldForm.selected property is true. - Uncheck the box and submit and go back in your browser and the unchecked status should be preserved. -

      -
    10. -
    11. - Now insert a decision state that says if the checkbox is selected goto page2, else goto a new page3: -
      	
      -	<decision-state id="isSelected">
      -		<if test="helloWorldForm.selected" then="page2" else="page3" />
      -	</decision-state>
      -
      -	<view-state id="page2">
      -	</view-state>	
      -    
      -	<view-state id="page3">
      -	</view-state>	
      -		
      - Be sure to update your start view-state to transition to the isSelected decision state instead of page2 directly: -
      -	<view-state id="start">
      -		<transition on="submit" to="isSelected" />
      -	</view-state>		
      -		
      - Click the Submit button with the checkbox selected and you should be taken to page2. - Click the button with the checkbox de-selected and you should be taken to page3 (you'll need to create a JSP or you'll get a 404). -
    12. -
    -

    Finish your helloworld flow

    -
      -
    1. - Finish up your helloworld flow by adding another button on the start.jsp that ends the flow: -
      -	<input type="submit" name="_eventId_finish" value="Finish" />
      -		
      - In your start view-state, declare the finish transition: -
      -	<transition on="finish" to="finished" />
      -		
      - And finally define the end-state: -
      -	<end-state id="finished" view="externalRedirect:welcome" />
      -		
      - Click the Finish button and you should be taken back to the application welcome screen. -
    2. -
    - Next > + <view-state id="page3"> + </view-state> +
    + Be sure to update your start view-state to transition to the isSelected decision state instead of page2 directly: +
    +		<view-state id="start">
    +			<transition on="submit" to="isSelected" />
    +		</view-state>		
    +			
    + Click the Submit button with the checkbox selected and you should be taken to page2. + Click the button with the checkbox de-selected and you should be taken to page3 (you'll need to create a JSP or you'll get a 404). +
  2. +
+ +
+

Finish your helloworld flow

+
    +
  1. + Finish up your helloworld flow by adding another button on the start.jsp that ends the flow: +
    +		<input type="submit" name="_eventId_finish" value="Finish" />
    +			
    + In your start view-state, declare the finish transition: +
    +		<transition on="finish" to="finished" />
    +			
    + And finally define the end-state: +
    +		<end-state id="finished" view="externalRedirect:welcome" />
    +			
    + Click the Finish button and you should be taken back to the application welcome screen. +
  2. +
+
+
+

+ Next > +

+
+ \ No newline at end of file diff --git a/spring-webflow-samples/getting-started-with-spring-webflow/src/main/webapp/WEB-INF/tutorial/webflowProjectOverview.jsp b/spring-webflow-samples/getting-started-with-spring-webflow/src/main/webapp/WEB-INF/tutorial/webflowProjectOverview.jsp index 8faf7dac..e9b6defb 100644 --- a/spring-webflow-samples/getting-started-with-spring-webflow/src/main/webapp/WEB-INF/tutorial/webflowProjectOverview.jsp +++ b/spring-webflow-samples/getting-started-with-spring-webflow/src/main/webapp/WEB-INF/tutorial/webflowProjectOverview.jsp @@ -3,46 +3,59 @@ Getting Started with Spring Web Flow: Overview of the Spring Web Flow Project + " type="text/css" /> + " type="text/css" /> + + + - +

Overview of the Spring Web Flow Project

-

- What is Spring Web Flow? -

-

- Spring Web Flow is a framework for implementing stateful web controllers. - It is a Spring Project and part of Spring's open-source Web Stack. -

-

- When do I use Web Flow? -

-

-Use Spring Web Flow when you need to implement a flow that guides your users through a series of screens to complete a business goal. -Web Flow provides a flow definition language for authoring flows that define screen navigation rules. -The framework also cares for managing conversational state and preventing duplicate transactions. -

-

- How does Web Flow relate to other Spring projects? -

-

-Spring Web Flow builds on the Spring Framework project, which includes the Spring MVC web framework. -Concretely, Spring Web Flow plugs into Spring MVC as a Controller technology. -A typical Spring-powered web application is implemented using a mix of annotated Spring MVC Controllers and web flows. -In general, use @Controllers for implementing simple, single-request user interactions, and web flows for stateful, multi-step user interactions. -

-

-A number of other Spring projects also integrate with Spring Web Flow. -The Spring Faces project uses Spring Web Flow as the controller framework to support implementing Spring-powered web applications that use JavaServerFaces (JSF) as the view technology. -Spring Web Flow also provides integration with Spring Security for securing web flows. -

-

-How Spring Web Flow fits into Spring's layered, a-la-carte "Web Stack" is illustrated below:
-" /> -

-

- Next > -

+
+

+ What is Spring Web Flow? +

+

+ Spring Web Flow is a framework for implementing stateful web controllers. + It is a Spring Project and part of Spring's open-source Web Stack. +

+
+
+

+ When do I use Web Flow? +

+

+ Use Spring Web Flow when you need to implement a flow that guides your users through a series of screens to complete a business goal. + Web Flow provides a high-level flow definition language for authoring flows that define screen navigation rules. + The framework also cares for managing conversational state and preventing duplicate transactions. +

+
+
+

+ How does Web Flow relate to other Spring projects? +

+

+ Spring Web Flow builds on the Spring Framework project, which includes the Spring MVC web framework. + Concretely, Spring Web Flow plugs into Spring MVC as a Controller technology. + A typical Spring-powered web application is implemented using a mix of annotated Spring MVC Controllers and web flows. + In general, use @Controllers for implementing simple, single-request user interactions, and web flows for stateful, multi-step user interactions. +

+

+ A number of other Spring projects also integrate with Spring Web Flow. + The Spring Faces project uses Spring Web Flow as the controller framework to support implementing Spring-powered web applications that use JavaServerFaces (JSF) as the view technology. + Spring Web Flow also provides integration with Spring Security for securing web flows. +

+

+ How Spring Web Flow fits into Spring's layered, a-la-carte "Web Stack" is illustrated below:
+ " /> +

+
+
+

+ Next > +

+
\ No newline at end of file diff --git a/spring-webflow-samples/getting-started-with-spring-webflow/src/main/webapp/WEB-INF/tutorial/webflowSetup.jsp b/spring-webflow-samples/getting-started-with-spring-webflow/src/main/webapp/WEB-INF/tutorial/webflowSetup.jsp index 3395b052..6b3b4bef 100644 --- a/spring-webflow-samples/getting-started-with-spring-webflow/src/main/webapp/WEB-INF/tutorial/webflowSetup.jsp +++ b/spring-webflow-samples/getting-started-with-spring-webflow/src/main/webapp/WEB-INF/tutorial/webflowSetup.jsp @@ -3,8 +3,13 @@ Getting Started with Spring Web Flow: Setting up Web Flow in a Spring Web Application + " type="text/css" /> + " type="text/css" /> + + + - +

Setting up Web Flow in a Spring Web Application

@@ -12,181 +17,203 @@ This step covers the one-time configuration step of setting Web Flow up in a Spring web application. If you prefer to go right to implementing your first flow, you can skip this step.

-

- What does the configuration of a typical Spring web application look like? -

-

- The configuration of every Spring web application starts in web.xml. - There, a Spring MVC DispatcherServlet is defined to process all requests into the application. - The DispatcherServlet itself is configured using a Spring container. - It is responsible for routing web requests to the proper application controllers, such as your Spring MVC @Controllers and web flows. - A typical DispatcherServlet declaration is shown below: -

-
-	<!-- The front controller of this Spring MVC application, responsible for handling all application requests -->
-	<servlet>
-		<servlet-name>Spring MVC Dispatcher Servlet</servlet-name>
-		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
-		<init-param>
-			<param-name>contextConfigLocation</param-name>
-			<param-value>
-				/WEB-INF/spring/*.xml
-			</param-value>
-		</init-param>
-		<load-on-startup>1</load-on-startup>
-	</servlet>
-		
-	<!-- Map all /app requests to the DispatcherServlet for handling -->
-	<servlet-mapping>
-		<servlet-name>Spring MVC Dispatcher Servlet</servlet-name>
-		<url-pattern>/app/*</url-pattern>
-	</servlet-mapping>
-
-

- This DispatcherServlet is configured to process requests into /app/*. - The servlet's configuration is defined in the .xml files in /WEB-INF/spring. -

-

- How are Spring configuration files typically organized? -

-

- Inside /WEB-INF/spring, we generally recommend defining a configuration file for your application logic, - and separate configuration files for framework infrastructure. For example: -

-
-	/webapp
-		/WEB-INF
-			/spring
-				app-config.xml
-				mvc-config.xml
-				webflow-config.xml
-			web.xml
-
-

- The example above shows the configuration for a Spring web application spread across three files. - The app-config.xml file configures your components that carry out application-specific controller, business, and data access logic. - The mvc-config.xml file configures the Spring MVC framework infrastructure, including the properties of the DispatcherServlet. - The webflow-config.xml file configures the Spring Web Flow infrastructure. -

-

- We also generally recommend using annotations to configure your application components, and externalized XML to configure infrastructure. - This is illustrated in app-config.xml by use of the component-scan directive to scan your classpath for application components to deploy: -

-
-	<!-- Scans within the base package of the application for @Components to configure as beans -->
-	<context:component-scan base-package="org.springframework.webflow.samples.gettingstarted" />
-
-

- With this technique, your Spring configuration is setup once and you generally never have to update your configuration files again as new components are added to your application. -

-

- How do I plug-in Spring Web Flow? -

-

- In webflow-config.xml, first define a flow-registry to register the flows you have defined in your application: -

-
-	<!-- Registers the web flows that can be executed -->	
-	<webflow:flow-registry id="flowRegistry" base-path="/WEB-INF/">
-		<webflow:flow-location-pattern value="**/*-flow.xml" />
-	</webflow:flow-registry>
-
-

- The example above scans /WEB-INF looking for -flow.xml files and registers them. -

-

- Then, define a flow-executor that uses this registry to execute your flows: -

-
-	<!-- Configures the engine that executes web flows in this application -->
-	<webflow:flow-executor id="flowExecutor" flow-registry="flowRegistry" />
-
-

- Finally, in mvc-config.xml plug in adapters to hook the flow-executor into the Spring MVC DispatcherServlet request processing pipeline: -

-
-	<!-- Maps requests to flows in the flowRegistry -->
-	<bean id="flowMappings" class="org.springframework.webflow.mvc.servlet.FlowHandlerMapping">
-		<property name="order" value="0" />
-		<property name="flowRegistry" ref="flowRegistry" />
-	</bean>
-
-	<!-- Enables Spring Web Flow as a Spring MVC request handler -->
-	<bean class="org.springframework.webflow.mvc.servlet.FlowHandlerAdapter">
-		<property name="flowExecutor" ref="flowExecutor" />
-	</bean>
-
-

- We also recommend you turn on development mode while developing so you never have to redeploy your application to test changes: -

-
-	<webflow:flow-builder-services id="flowBuilderServices" development="true" />
-
-

- How do Spring MVC @Controllers and Web Flows co-exist in the same application? -

-

- A typical Spring web application consists of a mix of stateless MVC @Controllers and stateful web flows, which are two distinct types of handlers. - When a web request comes in for a resource, the DispatcherServlet figures out which handler should be invoked. - This is done by consulting an ordered chain of HandlerMapping objects configured in your mvc-config.xml. - Generally, the first HandlerMapping consulted is the FlowHandlerMapping, which determines if the requested resource should be handled by a web flow. - If no flow handler is found, the next HandlerMapping in the chain is queried. - This is generally the DefaultAnnotationHandlerMapping, which consults explicit @RequestMapping rules defined inside annotated Spring MVC Controllers. -

-

- Setting up the HandlerMapping chain is a one-time configuration step, and makes it easy to plug in different types of handlers and mapping strategies. - A typical HandlerMapping chain for Spring web applications looks like: -

-
-	<!-- Maps requests to flows in the flowRegistry; for example, a request for resource /hotels/booking maps to a flow with id "hotels/booking"
-	     If no flow is found with that id, Spring MVC proceeds to the next HandlerMapping (order=1 below). -->
-	<bean id="flowMappings" class="org.springframework.webflow.mvc.servlet.FlowHandlerMapping">
-		<property name="order" value="0" />
-		<property name="flowRegistry" ref="flowRegistry" />
-	</bean>
-
-	<!-- Maps requests to @Controllers based on @RequestMapping("path") annotation values
-	     If no annotation-based path mapping is found, Spring MVC proceeds to the next HandlerMapping (order=2 below). -->
-	<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
-		<property name="order" value="1" />
-	</bean>	
-
-

- Once a request has been mapped to a handler object such as a @Controller of web flow, the DispatcherServlet uses the HandlerAdapter registered for that kind of handler to invoke it. - This decouples the DispatcherServlet from specific handler implementations, which allows Spring MVC to support different controller technologies in an extensible manner. - As a one-time configuration step, a typical Spring web application registers HandlerAdapters that know how to invoke @Controllers and web flows when they are mapped: -

-
-	<!-- Enables annotated @Controllers; responsible for invoking an annotated POJO @Controller when one is mapped. -->
-	<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" />
-
-	<!-- Enables web flows; responsible for calling the Spring Web Flow system to execute a flow when one is mapped. -->
-	<bean class="org.springframework.webflow.mvc.servlet.FlowHandlerAdapter">
-		<property name="flowExecutor" ref="flowExecutor" />
-	</bean>	
-
-

- To illustrate a typical DispatcherServlet pipeline, the following graphic illustrates the sequence of events that happen in this application when the /tutorial resource is requested, which is handled by the web flow you are interacting with right now:
- " /> -

-

- In this scenario, the FlowHandlerMapping returned the tutorial flow which was then invoked by the FlowHandlerAdapter. -

-

- The following graphic shows the sequence in this application when the /welcome resource is requested, which is handled by the annotated WelcomeController:
- " /> -

-

- In this scenario, the FlowHandlerMapping returned null because the /welcome resource was not mapped to a web flow. - The DefaultAnnotationHandlerMapping was then queried and returned the WelcomeController, which was invoked by the AnnotationMethodHandlerAdapter. -

-

- The main point to understand here is there is one-time configuration that enables full customization of the DispatcherServlet processing pipeline. - Once this configuration is established, you simply create new controllers and web flows, and they get picked up and hooked into the pipeline automatically. - No other configuration is required. -

-

- Next > -

+
+

+ What does the configuration of a typical Spring web application look like? +

+

+ The configuration of every Spring web application starts in web.xml. + There, a Spring MVC DispatcherServlet is defined to process all requests into the application. + The DispatcherServlet itself is configured using a Spring container. + It is responsible for routing web requests to the proper application controllers, such as your Spring MVC @Controllers and web flows. + A typical DispatcherServlet declaration is shown below: +

+
+		<!-- The front controller of this Spring MVC application, responsible for handling all application requests -->
+		<servlet>
+			<servlet-name>Spring MVC Dispatcher Servlet</servlet-name>
+			<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
+			<init-param>
+				<param-name>contextConfigLocation</param-name>
+				<param-value>
+					/WEB-INF/spring/*.xml
+				</param-value>
+			</init-param>
+			<load-on-startup>1</load-on-startup>
+		</servlet>
+			
+		<!-- Map all /app requests to the DispatcherServlet for handling -->
+		<servlet-mapping>
+			<servlet-name>Spring MVC Dispatcher Servlet</servlet-name>
+			<url-pattern>/app/*</url-pattern>
+		</servlet-mapping>
+	
+

+ This DispatcherServlet is configured to process requests into /app/*. + The servlet's configuration is defined in the .xml files in /WEB-INF/spring. +

+
+
+

+ How are Spring configuration files typically organized? +

+

+ Inside /WEB-INF/spring, we generally recommend defining a configuration file for your application logic, + and separate configuration files for framework infrastructure. For example: +

+
+		/webapp
+			/WEB-INF
+				/spring
+					app-config.xml
+					mvc-config.xml
+					webflow-config.xml
+				web.xml
+	
+

+ The example above shows the configuration for a Spring web application spread across three files. + The app-config.xml file configures your components that carry out application-specific controller, business, and data access logic. + The mvc-config.xml file configures the Spring MVC framework infrastructure, including the properties of the DispatcherServlet. + The webflow-config.xml file configures the Spring Web Flow infrastructure. +

+

+ We also generally recommend using annotations to configure your application components, and externalized XML to configure infrastructure. + This is illustrated in app-config.xml by use of the component-scan directive to scan your classpath for application components to deploy: +

+
+		<!-- Scans within the base package of the application for @Components to configure as beans -->
+		<context:component-scan base-package="org.springframework.webflow.samples.gettingstarted" />
+	
+

+ With this technique, your Spring configuration is setup once and you generally never have to update your configuration files again as new components are added to your application. +

+
+
+

+ How do I plug-in Spring Web Flow? +

+

+ In webflow-config.xml, first define a flow-registry to register the flows you have defined in your application: +

+
+		<!-- Registers the web flows that can be executed -->	
+		<webflow:flow-registry id="flowRegistry" base-path="/WEB-INF/">
+			<webflow:flow-location-pattern value="**/*-flow.xml" />
+		</webflow:flow-registry>
+	
+

+ The example above scans /WEB-INF looking for -flow.xml files and registers them. +

+

+ Then, define a flow-executor that uses this registry to execute your flows: +

+
+		<!-- Configures the engine that executes web flows in this application -->
+		<webflow:flow-executor id="flowExecutor" flow-registry="flowRegistry" />
+	
+

+ Finally, in mvc-config.xml plug in adapters to hook the flow-executor into the Spring MVC DispatcherServlet request processing pipeline: +

+
+		<!-- Maps requests to flows in the flowRegistry -->
+		<bean id="flowMappings" class="org.springframework.webflow.mvc.servlet.FlowHandlerMapping">
+			<property name="order" value="0" />
+			<property name="flowRegistry" ref="flowRegistry" />
+		</bean>
+	
+		<!-- Enables Spring Web Flow as a Spring MVC request handler -->
+		<bean class="org.springframework.webflow.mvc.servlet.FlowHandlerAdapter">
+			<property name="flowExecutor" ref="flowExecutor" />
+		</bean>
+	
+

+ We also recommend you turn on development mode while developing so you never have to redeploy your application to test changes: +

+
+		<webflow:flow-builder-services id="flowBuilderServices" development="true" />
+	
+
+
+

+ How do Spring MVC @Controllers and Web Flows co-exist in the same application? +

+

+ A typical Spring web application consists of a mix of stateless MVC @Controllers and stateful web flows, which are two distinct types of handlers. + When a web request comes in for a resource, the DispatcherServlet figures out which handler should be invoked. + This is done by consulting an ordered chain of HandlerMapping objects configured in your mvc-config.xml. + Generally, the first HandlerMapping consulted is the FlowHandlerMapping, which determines if the requested resource should be handled by a web flow. + If no flow handler is found, the next HandlerMapping in the chain is queried. + This is generally the DefaultAnnotationHandlerMapping, which consults explicit @RequestMapping rules defined inside annotated Spring MVC Controllers. +

+

+ Setting up the HandlerMapping chain is a one-time configuration step, and makes it easy to plug in different types of handlers and mapping strategies. + A typical HandlerMapping chain for Spring web applications looks like: +

+
+		<!-- Maps requests to flows in the flowRegistry; for example, a request for resource /hotels/booking maps to a flow with id "hotels/booking"
+		     If no flow is found with that id, Spring MVC proceeds to the next HandlerMapping (order=1 below). -->
+		<bean id="flowMappings" class="org.springframework.webflow.mvc.servlet.FlowHandlerMapping">
+			<property name="order" value="0" />
+			<property name="flowRegistry" ref="flowRegistry" />
+		</bean>
+	
+		<!-- Maps requests to @Controllers based on @RequestMapping("path") annotation values
+		     If no annotation-based path mapping is found, Spring MVC proceeds to the next HandlerMapping (order=2 below). -->
+		<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
+			<property name="order" value="1" />
+		</bean>	
+	
+

+ Once a request has been mapped to a handler object such as a @Controller of web flow, the DispatcherServlet uses the HandlerAdapter registered for that kind of handler to invoke it. + This decouples the DispatcherServlet from specific handler implementations, which allows Spring MVC to support different controller technologies in an extensible manner. + As a one-time configuration step, a typical Spring web application registers HandlerAdapters that know how to invoke @Controllers and web flows when they are mapped: +

+
+		<!-- Enables annotated @Controllers; responsible for invoking an annotated POJO @Controller when one is mapped. -->
+		<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" />
+	
+		<!-- Enables web flows; responsible for calling the Spring Web Flow system to execute a flow when one is mapped. -->
+		<bean class="org.springframework.webflow.mvc.servlet.FlowHandlerAdapter">
+			<property name="flowExecutor" ref="flowExecutor" />
+		</bean>	
+	
+

+ To illustrate a typical DispatcherServlet pipeline, the following graphic illustrates the sequence of events that happen in this application when the /tutorial resource is requested, which is handled by the web flow you are interacting with right now:
+ " /> +

+

+ In this scenario, the FlowHandlerMapping returned the tutorial flow which was then invoked by the FlowHandlerAdapter. +

+

+ The following graphic shows the sequence in this application when the /welcome resource is requested, which is handled by the annotated WelcomeController:
+ " /> +

+

+ In this scenario, the FlowHandlerMapping returned null because the /welcome resource was not mapped to a web flow. + The DefaultAnnotationHandlerMapping was then queried and returned the WelcomeController, which was invoked by the AnnotationMethodHandlerAdapter. +

+

+ The main point to understand here is there is one-time configuration that enables full customization of the DispatcherServlet processing pipeline. + Once this configuration is established, you simply create new controllers and web flows, and they get picked up and hooked into the pipeline automatically. + No other configuration is required. +

+
+
+

+ Next > +

+
+ \ No newline at end of file diff --git a/spring-webflow-samples/getting-started-with-spring-webflow/src/main/webapp/WEB-INF/tutorial/webflowWhatsNext.jsp b/spring-webflow-samples/getting-started-with-spring-webflow/src/main/webapp/WEB-INF/tutorial/webflowWhatsNext.jsp index e0f0c0fb..1dc90fea 100644 --- a/spring-webflow-samples/getting-started-with-spring-webflow/src/main/webapp/WEB-INF/tutorial/webflowWhatsNext.jsp +++ b/spring-webflow-samples/getting-started-with-spring-webflow/src/main/webapp/WEB-INF/tutorial/webflowWhatsNext.jsp @@ -3,8 +3,13 @@ Getting Started with Spring Web Flow: Where To Go From Here + " type="text/css" /> + " type="text/css" /> + + + - +

Where To Go with From Here

diff --git a/spring-webflow-samples/getting-started-with-spring-webflow/src/main/webapp/styles/tutorial.css b/spring-webflow-samples/getting-started-with-spring-webflow/src/main/webapp/styles/tutorial.css new file mode 100644 index 00000000..6b9fb39d --- /dev/null +++ b/spring-webflow-samples/getting-started-with-spring-webflow/src/main/webapp/styles/tutorial.css @@ -0,0 +1,11 @@ +.dijitTitlePane + .dijitTitlePane { + padding-top: 1em; +} + +.file { + font-family: monospace; +} + +ol li { + padding-bottom: 1em; +} \ No newline at end of file