docs updates
This commit is contained in:
@@ -5,31 +5,20 @@
|
||||
<sect1 id="spring-faces-introduction">
|
||||
<title>Introduction</title>
|
||||
<para>
|
||||
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.
|
||||
</para>
|
||||
<para>
|
||||
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.
|
||||
</para>
|
||||
</sect1>
|
||||
|
||||
<sect1 id="spring-faces-integration">
|
||||
<title>Spring-centric Integration Approach</title>
|
||||
<para>
|
||||
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.
|
||||
</para>
|
||||
<para>
|
||||
Spring Faces provides a powerful supplement to a number of the standard JSF facilities, including:
|
||||
@@ -45,13 +34,13 @@
|
||||
<listitem>Ajax partial page updates and full navigation</listitem>
|
||||
<listitem>progressive enhancement and graceful degradation</listitem>
|
||||
</orderedlist>
|
||||
|
||||
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
|
||||
<link linkend="defining-flows">Defining Flows</link>
|
||||
.
|
||||
<link linkend="defining-flows">Defining Flows</link>.
|
||||
</para>
|
||||
</sect1>
|
||||
<sect1 id="spring-faces-managed-beans">
|
||||
|
||||
@@ -5,8 +5,10 @@
|
||||
<!ENTITY overview SYSTEM "overview.xml">
|
||||
<!ENTITY defining-flows SYSTEM "defining-flows.xml">
|
||||
<!ENTITY el SYSTEM "el.xml">
|
||||
<!ENTITY views SYSTEM "views.xml">
|
||||
<!ENTITY flow-security SYSTEM "flow-security.xml">
|
||||
<!ENTITY flow-inheritance SYSTEM "flow-inheritance.xml">
|
||||
<!ENTITY spring-faces SYSTEM "spring-faces.xml">
|
||||
<!ENTITY upgrade-guide SYSTEM "upgrade-guide.xml">
|
||||
<!ENTITY flow-definition-field-mappings SYSTEM "flow-definition-field-mappings.xml">
|
||||
]>
|
||||
@@ -70,8 +72,10 @@
|
||||
&overview;
|
||||
&defining-flows;
|
||||
⪙
|
||||
&views;
|
||||
&flow-security;
|
||||
&flow-inheritance;
|
||||
&spring-faces;
|
||||
&upgrade-guide;
|
||||
&flow-definition-field-mappings;
|
||||
|
||||
|
||||
287
spring-webflow-reference/src/views.xml
Normal file
287
spring-webflow-reference/src/views.xml
Normal file
@@ -0,0 +1,287 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<chapter id="el">
|
||||
<title>Rendering Views</title>
|
||||
<sect1 id="views-introduction">
|
||||
<title>Introduction</title>
|
||||
<para>
|
||||
This chapter shows you how to use the view-state element to render views within a flow.
|
||||
</para>
|
||||
</sect1>
|
||||
<sect1 id="view-convention">
|
||||
<title>view-state</title>
|
||||
<para>
|
||||
Use the <code>view-state</code> element to define a step of the flow that renders a view and waits for a user event to resume:
|
||||
</para>
|
||||
<programlisting language="xml">
|
||||
<view-state id="enterBookingDetails" >
|
||||
<transition on="submit" to="reviewBooking" />
|
||||
</view-state>
|
||||
</programlisting>
|
||||
<para>
|
||||
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 <filename>/WEB-INF/hotels/booking/enterBookingDetails.xhtml</filename>
|
||||
if the flow itself was located in the <filename>/WEB-INF/hotels/booking</filename> directory.
|
||||
</para>
|
||||
<para>
|
||||
Below is a sample directory structure showing views and other resources like message bundles co-located with their flow definition:
|
||||
</para>
|
||||
</sect1>
|
||||
<sect1 id="view-explicit">
|
||||
<title>Explicit view ids</title>
|
||||
<para>
|
||||
Use the <code>view</code> attribute to explictly specify the id of the view to render.
|
||||
</para>
|
||||
<sect2 id="view-explicit-flowrelative">
|
||||
<title>Flow relative view ids</title>
|
||||
<para>
|
||||
The view id may be a relative path to view resource in the flow's working directory:
|
||||
</para>
|
||||
<programlisting language="xml">
|
||||
<view-state id="enterBookingDetails" view="bookingDetails.xhtml">
|
||||
</programlisting>
|
||||
</sect2>
|
||||
<sect2 id="view-explicit-absolute">
|
||||
<title>Absolute view ids</title>
|
||||
<para>
|
||||
The view id may be a absolute path to a view resource in the webapp root directory:
|
||||
</para>
|
||||
<programlisting language="xml">
|
||||
<view-state id="enterBookingDetails" view="/WEB-INF/hotels/booking/bookingDetails.xhtml">
|
||||
</programlisting>
|
||||
</sect2>
|
||||
<sect2 id="view-explicit-absolute">
|
||||
<title>Logical view ids</title>
|
||||
<para>
|
||||
With some view frameworks, such as Spring MVC's view framework, the view id may also be a logical identifier resolved by the framework:
|
||||
</para>
|
||||
<programlisting language="xml">
|
||||
<view-state id="enterBookingDetails" view="bookingDetails">
|
||||
</programlisting>
|
||||
<para>
|
||||
See the Spring MVC integration section for more information on how to integrate with the MVC <code>ViewResolver</code> infrastructure.
|
||||
</para>
|
||||
</sect2>
|
||||
<para>
|
||||
A sample directory structure showing views and other resources co-located with their flow is shown below:
|
||||
</para>
|
||||
<mediaobject>
|
||||
<imageobject role="fo">
|
||||
<imagedata fileref="images/flow-view-packaging.png" format="PNG" align="center"/>
|
||||
</imageobject>
|
||||
<imageobject role="html">
|
||||
<imagedata fileref="images/flow-view-packaging.png" format="PNG" align="center"/>
|
||||
</imageobject>
|
||||
<caption>
|
||||
<para>Flow Packaging</para>
|
||||
</caption>
|
||||
</mediaobject>
|
||||
</sect1>
|
||||
<sect1 id="view-scope">
|
||||
<title>viewScope</title>
|
||||
<para>
|
||||
A view-state allocates a new <code>viewScope</code> 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.
|
||||
</para>
|
||||
<sect2 id="view-scope-actions">
|
||||
<title>Assigning a viewScope variable using an Action</title>
|
||||
<para>
|
||||
Variables are often assigned before the view renders:
|
||||
</para>
|
||||
<programlisting language="xml">
|
||||
<on-render>
|
||||
<evaluate expression="bookingService.findHotels(searchCriteria)" result="viewScope.hotels" result-type="dataModel" />
|
||||
</on-render>
|
||||
</programlisting>
|
||||
</sect2>
|
||||
<sect2 id="view-scope-actions">
|
||||
<title>Using the var tag to allocate view variables</title>
|
||||
<para>
|
||||
Use the <code>var</code> tag to declare a view variable.
|
||||
Like a flow variable, any @Autowired references are automatically restored when the view state resumes.
|
||||
</para>
|
||||
<programlisting language="xml">
|
||||
<var name="searchCriteria" class="com.mycompany.myapp.hotels.SearchCriteria" />
|
||||
</programlisting>
|
||||
</sect2>
|
||||
<sect2 id="view-scope-ajax">
|
||||
<title>Manipulating objects view scope</title>
|
||||
<para>
|
||||
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.
|
||||
</para>
|
||||
<programlisting language="xml">
|
||||
<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>
|
||||
</programlisting>
|
||||
</sect2>
|
||||
</sect1>
|
||||
<sect1 id="view-on-render">
|
||||
<title>on-render</title>
|
||||
<para>
|
||||
Use the <code>on-render</code> 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.
|
||||
</para>
|
||||
<programlisting language="xml">
|
||||
<on-render>
|
||||
<evaluate expression="bookingService.findHotels(searchCriteria)" result="viewScope.hotels" result-type="dataModel" />
|
||||
</on-render>
|
||||
</programlisting>
|
||||
</sect1>
|
||||
<sect1 id="view-model">
|
||||
<title>Model binding</title>
|
||||
<para>
|
||||
Use the <code>model</code> attribute to declare the model object the view binds to.
|
||||
The following example declares the <code>enterBookingDetails</code> state manipulates the <code>booking</code> model:
|
||||
</para>
|
||||
<programlisting language="xml">
|
||||
<view-state id="enterBookingDetails" model="booking">
|
||||
</programlisting>
|
||||
<para>
|
||||
The model may be in any accessible scope, such as <code>flowScope</code> or <code>viewScope</code>.
|
||||
Specifying a <code>model</code> triggers the following behavior when a view event occurs:
|
||||
</para>
|
||||
<orderedlist>
|
||||
<listitem><para>View-to-model binding. On view postback, form values are bound to model object properties for you.</para></listitem>
|
||||
<listitem><para>Model validation. After binding, if the model object requires validation, that validation logic will be invoked.</para></listitem>
|
||||
</orderedlist>
|
||||
<para>
|
||||
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.
|
||||
</para>
|
||||
<para>
|
||||
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.
|
||||
</para>
|
||||
</sect1>
|
||||
<sect1 id="view-bind">
|
||||
<title>bind</title>
|
||||
<para>
|
||||
Use the <code>bind</code> attribute to suppress model binding and validation for particular view events.
|
||||
</para>
|
||||
<programlisting language="xml">
|
||||
<view-state id="enterBookingDetails">
|
||||
<transition on="proceed" to="reviewBooking">
|
||||
<transition on="cancel" to="bookingCancelled" bind="false" />
|
||||
</view-state>
|
||||
</programlisting>
|
||||
</sect1>
|
||||
<sect1 id="view-validate">
|
||||
<title>Validation</title>
|
||||
<para>
|
||||
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 <code>Validator</code>.
|
||||
</para>
|
||||
<sect2 id="view-validation-programmatic">
|
||||
<title>Programmatic validation</title>
|
||||
<para>
|
||||
There are two ways to perform model validation programatically.
|
||||
</para>
|
||||
<sect3 id="view-validation=programmatic-validate-method">
|
||||
<title>Implementing a model validate method</title>
|
||||
<para>
|
||||
The first way has you define a validate method on the model object class.
|
||||
To do this, create a public method with the name <code>validate<state></code>, where <code>state</code> is the id of the view-state.
|
||||
The method must declare a <code>MessageContext</code> parameter for recording validation error messages.
|
||||
For example:
|
||||
</para>
|
||||
<programlisting language="java">
|
||||
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());
|
||||
}
|
||||
}
|
||||
</programlisting>
|
||||
</sect3>
|
||||
<sect3 id="view-validation=programmatic-validator">
|
||||
<title>Implementing a Validator</title>
|
||||
<para>
|
||||
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 <code>validate<state></code>, where <code>state</code> is the id of the view-state.
|
||||
The method must declare a <code>Object</code> parameter to accept your model object, and a <code>MessageContext</code> parameter for recording validation error messages.
|
||||
For example:
|
||||
</para>
|
||||
<programlisting language="java">
|
||||
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());
|
||||
}
|
||||
}
|
||||
}
|
||||
</programlisting>
|
||||
<para>
|
||||
A Validator can also accept a Spring MVC <code>Errors</code> object, useful for invoking existing Spring Validators.
|
||||
</para>
|
||||
</sect3>
|
||||
</sect2>
|
||||
</sect1>
|
||||
<sect1 id="simple-event-handlers">
|
||||
<title>Event handlers</title>
|
||||
<para>
|
||||
From a view-state, transitions without targets can also be defined. Such transitions are called "event handlers":
|
||||
</para>
|
||||
<programlisting language="xml">
|
||||
<transition on="event">
|
||||
<-- Handle event -->
|
||||
</transition>
|
||||
</programlisting>
|
||||
<para>
|
||||
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.
|
||||
</para>
|
||||
<sect2 id="event-handlers-render">
|
||||
<title>render</title>
|
||||
<para>
|
||||
Use the <code>render</code> element to request partial re-rendering of a view after handling an event:
|
||||
</para>
|
||||
<programlisting language="xml">
|
||||
<transition on="next">
|
||||
<evaluate expression="searchCriteria.nextPage()" />
|
||||
<render fragments="searchResultsTFragment" />
|
||||
</transition>
|
||||
</programlisting>
|
||||
</sect2>
|
||||
</sect1>
|
||||
<sect1 id="view-popup">
|
||||
<title>popup</title>
|
||||
<para>
|
||||
Use the <code>popup</code> attribute to indicate the view should be rendered in a model popup dialog:
|
||||
</para>
|
||||
<programlisting language="java">
|
||||
<view-state id="changeSearchCriteria" view="enterSearchCriteria.xhtml" popup="true">
|
||||
</programlisting>
|
||||
<para>
|
||||
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.
|
||||
</para>
|
||||
</sect1>
|
||||
</chapter>
|
||||
Reference in New Issue
Block a user