I'm pleased to announce the first milestone of Spring Web Flow 2.2 is now available for download. The release is also available through the Maven milestone repository at http://maven.springframework.org/milestone. As with Spring Web Flow 2.1, this release requires JDK 1.5, Spring 3 and Spring Security 3.
The main focus of the release is to address the needs of JSF users by extending the list of supported JSF 2 features. Not long ago Web Flow 2.1 made it possible to use JSF 2 dependencies without the need for the separate Sun Facelets jar that is commonly used with JSF 1.2 today.
In Spring Web Flow 2.2 you can look forward to taking advantage of core JSF 2 features and JSF 2 component libraries. More on component libraries later in this post. First here is an overview of the new features.
JSF 2 Ajax Requests
JSF 2 defines client and server side facilities for processing Ajax requests. You can add Ajax behavior to a component with the <f:ajax> tag as follows:
<h:commandButton value="More Results" action="next"> <f:ajax render="@form" /> </h:commandButton>
When the above button is pressed an Ajax request is sent to the server that will result in partial request processing, rendering, and an update to the form the button belongs to.
If you are a Web Flow 2 user you will find it familiar to process the above request as you do today:
<view-state id="reviewHotels"> <transition on="next"> <evaluate expression="searchCriteria.nextPage()" /> </transition> </view-state>
The transition on "next" does not have a target view state. That will keep us in the current view while advancing the SearchCriteria backing bean to the next page. To ensure rendering happens without a client-side redirect (the POST-redirect-GET pattern), you need to configure Web Flow to be able to recognize JSF 2 Ajax requests:
<bean class="org.springframework.webflow.mvc.servlet.FlowHandlerAdapter"> <property name="flowExecutor" ref="flowExecutor" /> <property name="ajaxHandler"> <bean class="org.springframework.faces.webflow.JsfAjaxHandler"/> </property> </bean>
The booking-faces sample in the 2.2.0.M1 release uses the <f:ajax /> tag throughout including use cases such as search result pagination and Ajax-based form validation.
JSF 2 Resource Requests
JSF 2 introduces a ResourceHandler API for serving resources (images, .js, .css files) packaged relative to the web application root under /resources/** or on the classpath under META-INF/resources/**. JSF component libraries can add resources transparently via an API or @ResourceDependency annotation. Alternatively you can also add an <outputScript> tag to the view.
JSF renders resource URLs such that they point back to the same servlet like this:
Note the "/javax.faces.resources" segment that comes after the servlet mapping. This is what distinguishes it as a JSF resource requests.
In Web Flow, JSF resource URLs point back to the Spring MVC DispatcherServlet. To handle such requests a new Spring MVC HttpRequestHandler is provided to delegate resource requests to the JSF 2 resource handling mechanism. Below is the configuration required to configure this handler. The final release will simplify this configuration.
<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping"> <property name="mappings" value="/javax.faces.resource/**=jsfResourceHandler"/> </bean> <bean class="org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter" /> <bean id="jsfResourceHandler" class="org.springframework.faces.webflow.FacesJsfResourceRequestHandler"/>
The booking-faces sample in the 2.2.0.M1 release contains the necessary configuration.
Partial State Saving
Partial state saving is arguably one of the most important changes in JSF 2 (Facelets only). The way it works is, rather than storing the entire component tree state for every view the partial state saving algorithm always restores the tree to its initial state and then applies and keeps track of what's changed only. This rational is that component tree changes are likely to be smaller than the full component tree state thus resulting in less memory usage.
In Web Flow, the JSF component tree state has always been stored in a view-scoped Web Flow variable rather than directly in the HTTP session. Unfortunately to achieve that in JSF 1.2, Web Flow had to take over the entire state saving algorithm. This is why partial state didn't work out of the box in Web Flow 2.1 and had to be disabled through the "javax.faces.PARTIAL_STATE_SAVING" context parameter in web.xml.
General improvements in JSF 2 state saving made it possible to delegate to the standard JSF StateManager implementation and plug in a custom ResponseStateManager to override only the parts that do the actual reading and writing of component state. That is what Web Flow 2.2 does to provide support for partial state saving.
The change has been tested with Mojarra and in particular Mojarra version 2.0.3 (recommended version). If you use the Apache MyFaces JSF 2 implementation for the time being you will need to continue to use the "javax.faces.PARTIAL_STATE_SAVING" parameter to disable partial state saving. Unfortunately in MyFaces it wasn't as simple to customize how state is where state is read from and written to so it will take a little more time.
Single FacesContext Per Request
Part of the changes for partial state saving required making sure a single FacesContext instance is used for the duration of a single flow request. This is probably a welcome change for JSF users as evidenced by a few of your comments in JIRA. To avoid getting a NullPointerException on FacesContext you will need to add this FlowExecutionListener:
<webflow:flow-executor id="flowExecutor"> <webflow:flow-execution-listeners> <webflow:listener ref="facesContextListener" /> </webflow:flow-execution-listeners> </webflow:flow-executor> <bean id="facesContextListener" class="org.springframework.faces.webflow.FlowFacesContextLifecycleListener"/>
This is needed regardless of the JSF version used.
More JSF 2 Features
The only features that aren't supported are the ones where Web Flow provides core value including navigation and scopes. JSF 2 uses conventions to simplify navigation rules, adds conditional navigation, and provides view, flash, and custom scopes. You will find that Web Flow continues to provide significant value in both of these areas.
View parameters is another feature that isn't supported. Web Flow does provide a way to access request parameters and to bind them to fields of scoped beans. If you however have any good use cases in mind please do provide us with feedback.
Any other features not already mentioned (composite components, JSR-303 validation, system events, etc) are expected to work. With regards to composite components the following Mojarra issue may affect you. If so please vote for it.
JSF 2 Component Libraries
As a result you can expect Spring Web Flow 2.2 to release with JSF 2 samples featuring PrimeFaces components demonstrating effective use of Web Flow, JSF 2 and a first-class JSF 2 component library.
Web Flow 2.2 will be the first release to provide support for core JSF 2 features and close integration with the PrimeFaces component library. If you're a JSF user I hope you will find this an exciting step forward. To try the release please download it, run the updated booking-faces sample, and give us your feedback. You can expect a release candidate at the end of this month in sync with the PrimeFaces 2.2 release.
Meanwhile work on Web Flow 3 is continuing towards a first milestone. The defining feature of Web Flow 3 is Java flow definitions. The JSF work being done in the 2.2 branch will feed into the 3.0 branch.
- Spring Web Flow 2.0 M4 – Feedback Requested
- Spring For JavaServerFaces – TSSJS Slides and Demos
- The Spring Web Flow 2.0 Vision
- Spring Web Flow Bean Scopes and JSF
- What Spring Web Flow Offers JSF Developers