diff --git a/spring-webflow-samples/getting-started-with-spring-webflow/src/main/webapp/WEB-INF/spring/app-config.xml b/spring-webflow-samples/getting-started-with-spring-webflow/src/main/webapp/WEB-INF/spring/app-config.xml index b9d03235..6ae1d945 100644 --- a/spring-webflow-samples/getting-started-with-spring-webflow/src/main/webapp/WEB-INF/spring/app-config.xml +++ b/spring-webflow-samples/getting-started-with-spring-webflow/src/main/webapp/WEB-INF/spring/app-config.xml @@ -8,7 +8,7 @@ http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd"> - + \ No newline at end of file diff --git a/spring-webflow-samples/getting-started-with-spring-webflow/src/main/webapp/WEB-INF/spring/mvc-config.xml b/spring-webflow-samples/getting-started-with-spring-webflow/src/main/webapp/WEB-INF/spring/mvc-config.xml index 9585a223..01fce252 100644 --- a/spring-webflow-samples/getting-started-with-spring-webflow/src/main/webapp/WEB-INF/spring/mvc-config.xml +++ b/spring-webflow-samples/getting-started-with-spring-webflow/src/main/webapp/WEB-INF/spring/mvc-config.xml @@ -20,7 +20,7 @@ - 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 47b2c6a8..a5cd7015 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 @@ -38,7 +38,7 @@ The Spring Faces project uses Spring Web Flow as the controller framework to sup 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: +How Spring Web Flow fits into Spring's layered, a-la-carte "Web Stack" is illustrated below:
" />

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 7949929a..b72d8d28 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 @@ -49,13 +49,14 @@ 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		
+				webflow-config.xml
+			web.xml
 

The example above shows the configuration for a Spring web application spread across three files. @@ -63,13 +64,24 @@ mvc-config.xml configures the Spring MVC framework infrastructure, including the properties of the DispatcherServlet. webflow-config configures the Spring Web Flow infrastructure, which plugs into Spring MVC.

+

+ 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" />
@@ -81,14 +93,14 @@
 

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" />
@@ -103,9 +115,66 @@
 

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>
+	
+	<!-- Maps requests to @Controllers based on controller class name convention; e.g. a request for /hotels or a /hotels sub-resource maps to HotelsController
+	     If no class mapping is found, Spring MVC sends a 404 response and logs a pageNotFound warning. -->
+	<bean class="org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping">
+		<property name="order" value="2" />
+	</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 the DispatcherServlet pipeline, the following graphic illustrates the sequence when a request is mapped to a web flow:
+ +

+

+ The following graphic shows the sequence when a request is mapped to a @Controller:
+ +

Next >