polish
This commit is contained in:
@@ -68,14 +68,12 @@
|
||||
<li>
|
||||
Go ahead and create a <span class="file">start.jsp</span> in your flow directory and paste in the following:
|
||||
<pre>
|
||||
<html>
|
||||
<head>
|
||||
<title>Hello world!</title>
|
||||
</head>
|
||||
<h1>
|
||||
Hello world!
|
||||
</h1>
|
||||
</html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Hello world!</title>
|
||||
</head>
|
||||
<h1>Hello world!</h1>
|
||||
</html>
|
||||
</pre>
|
||||
</li>
|
||||
<li>
|
||||
@@ -91,29 +89,27 @@
|
||||
<li>
|
||||
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:
|
||||
<pre>
|
||||
<transition on="submit" to="page2" />
|
||||
<transition on="submit" to="page2" />
|
||||
</pre>
|
||||
Then define your page2 view-state:
|
||||
<pre>
|
||||
<view-state id="page2">
|
||||
</view-state>
|
||||
<view-state id="page2">
|
||||
</view-state>
|
||||
</pre>
|
||||
And the corresponding page2.jsp:
|
||||
<pre>
|
||||
<html>
|
||||
<head>
|
||||
<title>Hello world!</title>
|
||||
</head>
|
||||
<h1>
|
||||
This is page 2!
|
||||
</h1>
|
||||
</html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Hello world!</title>
|
||||
</head>
|
||||
<h1>This is page 2!</h1>
|
||||
</html>
|
||||
</pre>
|
||||
Finally, create a button on your <span class="file">start.jsp</span> that raises the submit event to trigger the state transition:
|
||||
<pre>
|
||||
<form method="post">
|
||||
<input type="submit" name="_eventId_submit" value="Submit" />
|
||||
</form>
|
||||
<form method="post">
|
||||
<input type="submit" name="_eventId_submit" value="Submit" />
|
||||
</form>
|
||||
</pre>
|
||||
Click the button and you should be taken to page 2.
|
||||
</li>
|
||||
@@ -129,49 +125,47 @@
|
||||
Try implementing a dynamic navigation rule by first adding a bound checkbox to your <span class="file">start.jsp</span>.
|
||||
Do this by replacing its contents with the following snippet:
|
||||
<pre>
|
||||
<%@ 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>
|
||||
<%@ 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>
|
||||
</pre>
|
||||
</li>
|
||||
<li>
|
||||
Next, create a <span class="file">HelloWorldForm</span> class in the <span class="file">org.springframework.webflow.samples.helloworld</span> package with the following code:
|
||||
<pre>
|
||||
package org.springframework.webflow.samples.helloworld;
|
||||
package org.springframework.webflow.samples.helloworld;
|
||||
|
||||
import java.io.Serializable;
|
||||
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;
|
||||
}
|
||||
}
|
||||
public class HelloWorldForm implements Serializable {
|
||||
private boolean selected = true;
|
||||
|
||||
public boolean isSelected() {
|
||||
return selected;
|
||||
}
|
||||
|
||||
public void setSelected(boolean selected) {
|
||||
this.selected = selected;
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
</li>
|
||||
<li>
|
||||
At the top of your helloworld-flow, declare the HelloWorldForm as a flow variable:
|
||||
<pre>
|
||||
<var name="helloWorldForm" class="org.springframework.webflow.samples.helloworld.HelloWorldForm" />
|
||||
<var name="helloWorldForm" class="org.springframework.webflow.samples.helloworld.HelloWorldForm" />
|
||||
</pre>
|
||||
Then update your start view-state to use this variable as its data model, enabling automatic model binding and validation:
|
||||
<pre>
|
||||
<view-state id="start" model="helloWorldForm"> ...
|
||||
<view-state id="start" model="helloWorldForm"> ...
|
||||
</pre>
|
||||
<p>
|
||||
Refresh your flow and the checkbox should render checked since the default value for the HelloWorldForm selected property is true.
|
||||
@@ -181,21 +175,21 @@
|
||||
<li>
|
||||
Now insert a decision state that says if the checkbox is selected goto page2, else goto a new page3:
|
||||
<pre>
|
||||
<decision-state id="isSelected">
|
||||
<if test="helloWorldForm.selected" then="page2" else="page3" />
|
||||
</decision-state>
|
||||
<decision-state id="isSelected">
|
||||
<if test="helloWorldForm.selected" then="page2" else="page3" />
|
||||
</decision-state>
|
||||
|
||||
<view-state id="page2">
|
||||
</view-state>
|
||||
<view-state id="page2">
|
||||
</view-state>
|
||||
|
||||
<view-state id="page3">
|
||||
</view-state>
|
||||
<view-state id="page3">
|
||||
</view-state>
|
||||
</pre>
|
||||
Be sure to update your start view-state to transition to the isSelected decision state instead of page2 directly:
|
||||
<pre>
|
||||
<view-state id="start">
|
||||
<transition on="submit" to="isSelected" />
|
||||
</view-state>
|
||||
<view-state id="start">
|
||||
<transition on="submit" to="isSelected" />
|
||||
</view-state>
|
||||
</pre>
|
||||
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).
|
||||
@@ -208,15 +202,15 @@
|
||||
<li>
|
||||
Finish up your helloworld flow by adding another button on the <span class="file">start.jsp</span> that ends the flow:
|
||||
<pre>
|
||||
<input type="submit" name="_eventId_finish" value="Finish" />
|
||||
<input type="submit" name="_eventId_finish" value="Finish" />
|
||||
</pre>
|
||||
In your start view-state, declare the finish transition:
|
||||
<pre>
|
||||
<transition on="finish" to="finished" />
|
||||
<transition on="finish" to="finished" />
|
||||
</pre>
|
||||
And finally define the end-state:
|
||||
<pre>
|
||||
<end-state id="finished" view="externalRedirect:welcome" />
|
||||
<end-state id="finished" view="externalRedirect:welcome" />
|
||||
</pre>
|
||||
Click the Finish button and you should be taken back to the application welcome screen.
|
||||
</li>
|
||||
|
||||
@@ -29,24 +29,24 @@ If you prefer to go right to implementing your first flow, you can <a href="tuto
|
||||
A typical DispatcherServlet declaration is shown below:
|
||||
</p>
|
||||
<pre class="code">
|
||||
<!-- 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>
|
||||
<!-- 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>
|
||||
</pre>
|
||||
<p>
|
||||
This DispatcherServlet is configured to process requests into /app/*.
|
||||
@@ -62,13 +62,13 @@ If you prefer to go right to implementing your first flow, you can <a href="tuto
|
||||
and separate configuration files for framework infrastructure. For example:
|
||||
</p>
|
||||
<pre class="code">
|
||||
/webapp
|
||||
/WEB-INF
|
||||
/spring
|
||||
app-config.xml
|
||||
mvc-config.xml
|
||||
webflow-config.xml
|
||||
web.xml
|
||||
/webapp
|
||||
/WEB-INF
|
||||
/spring
|
||||
app-config.xml
|
||||
mvc-config.xml
|
||||
webflow-config.xml
|
||||
web.xml
|
||||
</pre>
|
||||
<p>
|
||||
The example above shows the configuration for a Spring web application spread across three files.
|
||||
@@ -81,8 +81,8 @@ If you prefer to go right to implementing your first flow, you can <a href="tuto
|
||||
This is illustrated in app-config.xml by use of the component-scan directive to scan your classpath for application components to deploy:
|
||||
</p>
|
||||
<pre class="code">
|
||||
<!-- Scans within the base package of the application for @Components to configure as beans -->
|
||||
<context:component-scan base-package="org.springframework.webflow.samples.gettingstarted" />
|
||||
<!-- Scans within the base package of the application for @Components to configure as beans -->
|
||||
<context:component-scan base-package="org.springframework.webflow.samples.gettingstarted" />
|
||||
</pre>
|
||||
<p>
|
||||
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.
|
||||
@@ -96,10 +96,10 @@ If you prefer to go right to implementing your first flow, you can <a href="tuto
|
||||
In webflow-config.xml, first define a flow-registry to register the flows you have defined in your application:
|
||||
</p>
|
||||
<pre class="code">
|
||||
<!-- 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>
|
||||
<!-- 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>
|
||||
</pre>
|
||||
<p>
|
||||
The example above scans /WEB-INF looking for -flow.xml files and registers them.
|
||||
@@ -108,29 +108,29 @@ If you prefer to go right to implementing your first flow, you can <a href="tuto
|
||||
Then, define a flow-executor that uses this registry to execute your flows:
|
||||
</p>
|
||||
<pre class="code">
|
||||
<!-- Configures the engine that executes web flows in this application -->
|
||||
<webflow:flow-executor id="flowExecutor" flow-registry="flowRegistry" />
|
||||
<!-- Configures the engine that executes web flows in this application -->
|
||||
<webflow:flow-executor id="flowExecutor" flow-registry="flowRegistry" />
|
||||
</pre>
|
||||
<p>
|
||||
Finally, in mvc-config.xml plug in adapters to hook the flow-executor into the Spring MVC DispatcherServlet request processing pipeline:
|
||||
</p>
|
||||
<pre class="code">
|
||||
<!-- 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>
|
||||
<!-- 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>
|
||||
</pre>
|
||||
<p>
|
||||
We also recommend you turn on development mode while developing so you never have to redeploy your application to test changes:
|
||||
</p>
|
||||
<pre class="code">
|
||||
<webflow:flow-builder-services id="flowBuilderServices" development="true" />
|
||||
<webflow:flow-builder-services id="flowBuilderServices" development="true" />
|
||||
</pre>
|
||||
</div>
|
||||
<div id="question4" class="question">
|
||||
@@ -150,18 +150,18 @@ If you prefer to go right to implementing your first flow, you can <a href="tuto
|
||||
A typical HandlerMapping chain for Spring web applications looks like:
|
||||
</p>
|
||||
<pre class="code">
|
||||
<!-- 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 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>
|
||||
</pre>
|
||||
<p>
|
||||
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.
|
||||
@@ -169,13 +169,13 @@ If you prefer to go right to implementing your first flow, you can <a href="tuto
|
||||
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:
|
||||
</p>
|
||||
<pre class="code">
|
||||
<!-- 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>
|
||||
<!-- 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>
|
||||
</pre>
|
||||
<p>
|
||||
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:<br>
|
||||
|
||||
Reference in New Issue
Block a user