diff --git a/spring-webflow-reference/images/flow-view-packaging.png b/spring-webflow-reference/images/flow-view-packaging.png
new file mode 100644
index 00000000..bcd2207b
Binary files /dev/null and b/spring-webflow-reference/images/flow-view-packaging.png differ
diff --git a/spring-webflow-reference/src/spring-faces.xml b/spring-webflow-reference/src/spring-faces.xml
index 505a3922..a4c42a7f 100644
--- a/spring-webflow-reference/src/spring-faces.xml
+++ b/spring-webflow-reference/src/spring-faces.xml
@@ -5,31 +5,20 @@
Introduction
- Spring Faces is Spring's JSF integration module that ships with the Spring Web Flow 2.0 distribution and
- aims to simplify the programming model for using JSF with Spring. It provides support for using JSF in a
- Spring-centric environment using Spring MVC and Spring Web Flow for control flow and event handling.
+ Spring Faces is Spring's JSF integration module that simplifies using JSF with Spring.
+ It lets you use the JSF UI Component Model with Spring MVC and Spring Web Flow controllers.
- It includes a lightweight Facelets component library that focuses on providing rich client-side behavior and
- Ajax support through the use of progressive enhancement. The client-side functionality of the component
- library is provided by Spring JavaScript, an integration layer that aims to be agnostic to the underlying
- client-side JavaScript toolkit. Spring Faces also aims to ensure that other JSF component libraries
- integrate smoothly with Spring Web Flow, for the cases where a more desktop-like UI is desired as opposed to
- the lightweight approach of the Spring Faces components.
+ Spring Faces also includes a small Facelets component library that provides Ajax and client-side validation capabilities.
+ This component library builds on Spring Javascript, a Javascript abstraction framework that integrates Dojo as the underlying UI toolkit.
Spring-centric Integration Approach
- Spring Faces aims to emphasize the strengths of JSF (i.e, its component model and EL binding) while
- providing an alternative controller model that addresses many of its traditional weaknesses. Spring Faces
- requests are routed through the Spring MVC DispatcherServlet instead of the FacesServlet, and the JSF
- lifecycle is executed within the context of the current flow execution. Whereas pure JSF requests are
- essentially driven by the current JSF view in a pull-oriented fashion, routing through the Spring
- infrastructure allows for more flexible request processing with many well-defined extension points for
- initialization and manipulation of the model and event-handling mechanisms that enable a reduced dependence
- on the JSF API.
+ Spring Faces combines the strengths of JSF, its UI component model, with the strengths of Spring, its controller and configuration model.
+ This brings you all the strengths of JSF without any of the weaknesses.
Spring Faces provides a powerful supplement to a number of the standard JSF facilities, including:
@@ -45,13 +34,13 @@
Ajax partial page updates and full navigationprogressive enhancement and graceful degradation
+
Using these features will significantly reduce the amount of configuration required in faces-config.xml
while providing a cleaner separation between the view and controller layer and better modularization of your
application's functional responsibilities. These use of these features are outlined in the sections to
follow. As the majority of these features build on the flow definition language of Spring Web Flow, it is
assumed that you have an understanding of the foundations presented in
- Defining Flows
- .
+ Defining Flows.
diff --git a/spring-webflow-reference/src/spring-webflow-reference.xml b/spring-webflow-reference/src/spring-webflow-reference.xml
index 6daf75d2..e7ca8d38 100644
--- a/spring-webflow-reference/src/spring-webflow-reference.xml
+++ b/spring-webflow-reference/src/spring-webflow-reference.xml
@@ -5,8 +5,10 @@
+
+
]>
@@ -70,8 +72,10 @@
&overview;
&defining-flows;
⪙
+ &views;
&flow-security;
&flow-inheritance;
+ &spring-faces;
&upgrade-guide;
&flow-definition-field-mappings;
diff --git a/spring-webflow-reference/src/views.xml b/spring-webflow-reference/src/views.xml
new file mode 100644
index 00000000..0419c154
--- /dev/null
+++ b/spring-webflow-reference/src/views.xml
@@ -0,0 +1,287 @@
+
+
+ Rendering Views
+
+ Introduction
+
+ This chapter shows you how to use the view-state element to render views within a flow.
+
+
+
+ view-state
+
+ Use the view-state element to define a step of the flow that renders a view and waits for a user event to resume:
+
+
+<view-state id="enterBookingDetails" >
+ <transition on="submit" to="reviewBooking" />
+</view-state>
+
+
+ By convention, a view-state maps its id to a view template in the directory where the flow is located.
+ For example, the state above might render /WEB-INF/hotels/booking/enterBookingDetails.xhtml
+ if the flow itself was located in the /WEB-INF/hotels/booking directory.
+
+
+ Below is a sample directory structure showing views and other resources like message bundles co-located with their flow definition:
+
+
+
+ Explicit view ids
+
+ Use the view attribute to explictly specify the id of the view to render.
+
+
+ Flow relative view ids
+
+ The view id may be a relative path to view resource in the flow's working directory:
+
+
+<view-state id="enterBookingDetails" view="bookingDetails.xhtml">
+
+
+
+ Absolute view ids
+
+ The view id may be a absolute path to a view resource in the webapp root directory:
+
+
+<view-state id="enterBookingDetails" view="/WEB-INF/hotels/booking/bookingDetails.xhtml">
+
+
+
+ Logical view ids
+
+ With some view frameworks, such as Spring MVC's view framework, the view id may also be a logical identifier resolved by the framework:
+
+
+<view-state id="enterBookingDetails" view="bookingDetails">
+
+
+ See the Spring MVC integration section for more information on how to integrate with the MVC ViewResolver infrastructure.
+
+
+
+ A sample directory structure showing views and other resources co-located with their flow is shown below:
+
+
+
+
+
+
+
+
+
+ Flow Packaging
+
+
+
+
+ viewScope
+
+ A view-state allocates a new viewScope when it enters.
+ This scope may be referenced within the view-state to assign variables that should live for the duration of the state.
+ This scope is useful for manipulating objects over a series of requests from the same view, often Ajax requests.
+ A view-state destroys its viewScope when it exits.
+
+
+ Assigning a viewScope variable using an Action
+
+ Variables are often assigned before the view renders:
+
+
+<on-render>
+ <evaluate expression="bookingService.findHotels(searchCriteria)" result="viewScope.hotels" result-type="dataModel" />
+</on-render>
+
+
+
+ Using the var tag to allocate view variables
+
+ Use the var tag to declare a view variable.
+ Like a flow variable, any @Autowired references are automatically restored when the view state resumes.
+
+
+<var name="searchCriteria" class="com.mycompany.myapp.hotels.SearchCriteria" />
+
+
+
+ Manipulating objects view scope
+
+ Objects in view scope are often manipulated over a series of requests from the same view.
+ The following example illustrates paginiation through a search results list.
+ The list is updated in view scope before each render.
+ Asynchronous event handlers modify the current data page, then request re-rendering of the search results fragment.
+
+
+<view-state id="searchResults">
+ <on-render>
+ <evaluate expression="bookingService.findHotels(searchCriteria)" result="viewScope.hotels" result-type="dataModel" />
+ </on-render>
+ <transition on="next">
+ <evaluate expression="searchCriteria.nextPage()" />
+ <render fragments="searchResultsTFragment" />
+ </transition>
+ <transition on="previous">
+ <evaluate expression="searchCriteria.previousPage()" />
+ <render fragments="searchResultsFragment" />
+ </transition>
+</view-state>
+
+
+
+
+ on-render
+
+ Use the on-render element to execute one or more actions before view rendering
+ Render actions are executed on the initial render as well as any subsequent refreshes, including any partial re-renderings of the view.
+
+
+<on-render>
+ <evaluate expression="bookingService.findHotels(searchCriteria)" result="viewScope.hotels" result-type="dataModel" />
+</on-render>
+
+
+
+ Model binding
+
+ Use the model attribute to declare the model object the view binds to.
+ The following example declares the enterBookingDetails state manipulates the booking model:
+
+
+<view-state id="enterBookingDetails" model="booking">
+
+
+ The model may be in any accessible scope, such as flowScope or viewScope.
+ Specifying a model triggers the following behavior when a view event occurs:
+
+
+ View-to-model binding. On view postback, form values are bound to model object properties for you.
+ Model validation. After binding, if the model object requires validation, that validation logic will be invoked.
+
+
+ For a flow event to be generated that can drive a view state transition, model binding must complete successfully.
+ If model binding fails, the view is re-rendered to allow the user to revise their edits.
+
+
+ The exact model binding and validation semantics are a function of the view technology in use.
+ See the Spring MVC and Faces section for more information on MVC and JSF semantics, respectively.
+ Regardless of the view technology used, the flow definition metadata should not change.
+
+
+
+ bind
+
+ Use the bind attribute to suppress model binding and validation for particular view events.
+
+
+<view-state id="enterBookingDetails">
+ <transition on="proceed" to="reviewBooking">
+ <transition on="cancel" to="bookingCancelled" bind="false" />
+</view-state>
+
+
+
+ Validation
+
+ Model validation is driven by constraints specified against the model object.
+ These constraints may be specified declaratively, or enforced using a programmatic validation routine or external Validator.
+
+
+ Programmatic validation
+
+ There are two ways to perform model validation programatically.
+
+
+ Implementing a model validate method
+
+ The first way has you define a validate method on the model object class.
+ To do this, create a public method with the name validate<state>, where state is the id of the view-state.
+ The method must declare a MessageContext parameter for recording validation error messages.
+ For example:
+
+
+public void validateEnterBookingDetails(MessageContext context) {
+ Calendar calendar = Calendar.getInstance();
+ calendar.add(Calendar.DAY_OF_MONTH, -1);
+ if (checkinDate.before(calendar.getTime())) {
+ context.addMessage(new MessageBuilder().error().source("checkinDate").defaultText(
+ "Check in date must be a future date").build());
+ } else if (!checkinDate.before(checkoutDate)) {
+ context.addMessage(new MessageBuilder().error().source("checkoutDate").defaultText(
+ "Check out date must be later than check in date").build());
+ }
+}
+
+
+
+ Implementing a Validator
+
+ The second way has you define a separate object, called a Validator, which validates your model object.
+ To do this, create a class that defines a public method with the name validate<state>, where state is the id of the view-state.
+ The method must declare a Object parameter to accept your model object, and a MessageContext parameter for recording validation error messages.
+ For example:
+
+
+public class BookingValidator {
+ public void validateEnterBookingDetails(Object object, MessageContext context) {
+ Booking booking = (Booking) object;
+ Calendar calendar = Calendar.getInstance();
+ calendar.add(Calendar.DAY_OF_MONTH, -1);
+ if (booking.getCheckinDate().before(calendar.getTime())) {
+ context.addMessage(new MessageBuilder().error().source("checkinDate").defaultText(
+ "Check in date must be a future date").build());
+ } else if (!booking.getCheckinDate().before(checkoutDate)) {
+ context.addMessage(new MessageBuilder().error().source("checkoutDate").defaultText(
+ "Check out date must be later than check in date").build());
+ }
+ }
+}
+
+
+ A Validator can also accept a Spring MVC Errors object, useful for invoking existing Spring Validators.
+
+
+
+
+
+ Event handlers
+
+ From a view-state, transitions without targets can also be defined. Such transitions are called "event handlers":
+
+
+<transition on="event">
+ <-- Handle event -->
+</transition>
+
+
+ These event handlers do not change the state of the flow.
+ They simply execute their actions and re-render the current view or one or more fragments of the current view.
+
+
+ render
+
+ Use the render element to request partial re-rendering of a view after handling an event:
+
+
+<transition on="next">
+ <evaluate expression="searchCriteria.nextPage()" />
+ <render fragments="searchResultsTFragment" />
+</transition>
+
+
+
+
+ popup
+
+ Use the popup attribute to indicate the view should be rendered in a model popup dialog:
+
+
+<view-state id="changeSearchCriteria" view="enterSearchCriteria.xhtml" popup="true">
+
+
+ When using Web Flow with the Spring Javascript, no client side code is necessary for the popup to display.
+ Web Flow will send a response to the client requesting a redirect to the view from a popup, and the client will honor the request.
+
+
+
\ No newline at end of file