Spring Web Flow allows you to handle JSF action events in a decoupled way, requiring no direct dependencies in your Java code on JSF API's. In fact, these events can often be handled completely in the flow definiton language without requiring any custom Java action code at all. This allows for a more agile development process since the artifacts being manipulated in wiring up events (JSF view templates and SWF flow definitions) are instantly refreshable without requiring a build and re-deploy of the whole application.
                A simple but common case in JSF is the need to signal an event that causes manipulation of the model in
                some way and then redisplays the same view to reflect the changed state of the model. The flow
                definition language has special support for this in the
                transition
                element.
            
                A good example of this is a table of paged list results. Suppose you want to be able to load and display
                only a portion of a large result list, and allow the user to page through the results. The initial
                view-state
                definition to load and display the list would be:
            
<view-state id="reviewHotels"> <on-render> <evaluate expression="bookingService.findHotels(searchCriteria)" result="viewScope.hotels" result-type="dataModel" /> </on-render> </view-state>
                You construct a JSF DataTable that displays the current
                hotels
                list, and then place a "More Results" link below the table:
            
<h:commandLink id="nextPageLink" value="More Results" action="next"/>
                This commandLink signals a "next" event from its action attribute. You can then handle the event by
                adding to the
                view-state
                definition:
            
<view-state id="reviewHotels"> <on-render> <evaluate expression="bookingService.findHotels(searchCriteria)" result="viewScope.hotels" result-type="dataModel" /> </on-render> <transition on="next"> <evaluate expression="searchCriteria.nextPage()" /> </transition> </view-state>
                Here you handle the "next" event by incrementing the page count on the searchCriteria instance. The
                on-render
                action is then called again with the updated criteria, which causes the next page of results to be
                loaded into the DataModel. The same view is re-rendered since there was no
                to
                attribute on the
                transition
                element, and the changes in the model are reflected in the view.
            
The next logical level beyond in-page events are events that require navigation to another view, with some manipulation of the model along the way. Achieving this with pure JSF would require adding a navigation rule to faces-config.xml and likely some intermediary Java code in a JSF managed bean (both tasks requiring a re-deploy). With the flow defintion language, you can handle such a case concisely in one place in a quite similar way to how in-page events are handled.
                Continuing on with our use case of manipulating a paged list of results, suppose we want each row in the
                displayed DataTable to contain a link to a detail page for that row instance. You can add a column to
                the table containing the following
                commandLink
                component:
            
<h:commandLink id="viewHotelLink" value="View Hotel" action="select"/>
                This raises the "select" event which you can then handle by adding another
                transition
                element to the existing
                view-state
                :
            
<view-state id="reviewHotels"> <on-render> <evaluate expression="bookingService.findHotels(searchCriteria)" result="viewScope.hotels" result-type="dataModel" /> </on-render> <transition on="next"> <evaluate expression="searchCriteria.nextPage()" /> </transition> <transition on="select" to="reviewHotel"> <set name="flowScope.hotel" value="hotels.selectedRow" /> </transition> </view-state>
                Here the "select" event is handled by pushing the currently selected hotel instance from the DataTable
                into flow scope, so that it may be referenced by the "reviewHotel"
                view-state
                .
            
JSF provides useful facilities for validating input at field-level before changes are applied to the model, but when you need to then perform more complex validation at the model-level after the updates have been applied, you are generally left with having to add more custom code to your JSF action methods in the managed bean. Validation of this sort is something that is generally a responsibility of the domain model itself, but it is difficult to get any error messages propagated back to the view without introducing an undesirable dependency on the JSF API in your domain layer.
                With Spring Faces, you can utilize the generic and low-level
                MessageContext
                in your business code and any messages added there will then be available to the
                FacesContext
                at render time.
            
                For example, suppose you have a view where the user enters the necessary details to complete a hotel
                booking, and you need to ensure the Check In and Check Out dates adhere to a given set of business
                rules. You can invoke such model-level validation from a
                transition
                element:
            
<view-state id="enterBookingDetails"> <transition on="proceed" to="reviewBooking"> <evaluate expression="booking.validateEnterBookingDetails(messageContext)" /> </transition> </view-state>
                Here the "proceed" event is handled by invoking a model-level validation method on the booking instance,
                passing the generic
                MessageContext
                instance so that messages may be recorded. The messages can then be displayed along with any other JSF
                messages with the
                h:messages
                component,
            
                Spring Faces provides some special
                UICommand
                components that go beyond the standard JSF components by adding the ability to do Ajax-based partial
                view updates. These components degrade gracefully so that the flow will still be fully functional by
                falling back to full page refreshes if a user with a less capable browser views the page.
                
| ![[Note]](images/note.gif) | Note | 
|---|---|
| Though the core JSF support in Spring Faces is JSF 1.1-compatible, the Spring Faces Ajax components require JSF 1.2. | 
                Revisiting the earlier example with the paged table, you can change the "More Results" link to use an
                Ajax request by replacing the standard
                commandButton
                with the Spring Faces version (note that the Spring Faces command components use Ajax by default, but
                they can alternately be forced to use a normal form submit by setting ajaxEnabled="false" on the
                component):
            
<sf:commandLink id="nextPageLink" value="More Results" action="next" />
                This event is handled just as in the non-Ajax case with the
                transition
                element, but now you will add a special
                render
                action that specifies which portions of the component tree need to be re-rendered:
            
<view-state id="reviewHotels"> <on-render> <evaluate expression="bookingService.findHotels(searchCriteria)" result="viewScope.hotels" result-type="dataModel" /> </on-render> <transition on="next"> <evaluate expression="searchCriteria.nextPage()" /> <render fragments="hotels:searchResultsFragment" /> </transition> </view-state>
                The
                fragments="hotels:searchResultsFragment"
                is an instruction that will be interpreted at render time, such that only the component with the JSF
                clientId "hotels:searchResultsFragment" will be rendered and returned to the client. This fragment will
                then be automatically replaced in the page. The
                fragments
                attribute can be a comma-delimited list of ids, with each id representing the root node of a subtree
                (meaning the root node and all of its children) to be rendered. If the "next" event is fired in a
                non-Ajax request (i.e., if JavaScript is disabled on the client), the
                render
                action will be ignored and the full page will be rendered as normal.
            
                In addition to the Spring Faces
                commandLink
                component, there is a corresponding
                commandButton
                component with the same functionality. There is also a special
                ajaxEvent
                component that will raise a JSF action even in response to any client-side DOM event. See the Spring
                Faces tag library docs for full details.
            
                An additional built-in feature when using the Spring Faces Ajax components is the ability to have the
                response rendered inside a rich modal popup widget by setting
                popup="true"
                on a
                view-state
                .
            
<view-state id="changeSearchCriteria" view="enterSearchCriteria.xhtml" popup="true"> <on-entry> <render fragments="hotelSearchFragment" /> </on-entry> <transition on="search" to="reviewHotels"> <evaluate expression="searchCriteria.resetPage()"/> </transition> </view-state>
                If the "changeSearchCriteria"
                view-state
                is reached as the result of an Ajax-request, the result will be rendered into a rich popup. If
                JavaScript is unavailable, the request will be processed with a full browser refresh, and the
                "changeSearchCriteria" view will be rendered as normal.