JSF Central - Introduction to Spring Faces Part 1
JSF Central

 
 Home 
 
 Products 
 
 Articles & Books 
 
 Resources 
Articles
 
Introduction to Spring Faces Part 1
(continued)
by Jeremy Grelle
17 Sep 2008 04:45 EDT

Spring Web Flow 2 introduced the Spring Faces module, which provides first-class integration support between JavaServer Faces (JSF) and Spring. This is the first article in a series about Spring Faces. It explains both the JSF-centric and Spring-centric approaches to integrating the two frameworks.


Spring-centric JSF with Spring Faces

Spring Faces takes a much more prescriptive approach to integration between JSF and Spring. A further strength of JSF is the many extension points it provides, and Spring Faces takes full advantage of this to fit JSF more naturally into a Spring world. It makes a number of assumptions about the environment it is running in, such as a Spring MVC DispatcherServlet being configured to handle request routing, and Spring Web Flow 2.x being available as the primary controller model. It also builds upon the new Spring JavaScript module to provide a number of lightweight JSF Ajax components that focus on web development best practices, such as progressive enhancement, graceful degradation, and accessibility. (Spring Faces is designed to work with any JSF component library, thus the use of these components is entirely optional.) Figure 1 below gives a high-level picture of the Spring Faces architecture:

  Figure 1 - High-level View of Spring-Faces Architecture
Figure 1 - High-level View of Spring-Faces Architecture

For the remainder of this article, I will be using pieces of the Spring Faces version of the Spring Travel sample application (included in the Spring Web Flow 2 distribution ) to illustrate the Spring Faces approach to building a JSF web application.

The full source for the Spring Faces sample can be found under /projects/spring-webflow-samples/booking-faces/ from the root of the distribution.

If you want to at least familiarize yourself with the functionality of the application, a running version of the sample is available here.

Structure of the Spring Faces sample

One of the first things worth noting about the sample is the content of /src/main/webapp/WEB-INF/faces-config.xml. The only piece of infrastructure configured there is the standard FaceletViewHandler. Since Spring Faces takes a more prescriptive approach, all of its JSF integration artifacts are configured automatically through inclusion of spring-faces.jar on the classpath.

You will also want to familiarize yourself with the basic setup for the routing infrastructure of the application by looking at:

  • /src/main/webapp/WEB-INF/web.xml
  • /src/main/webapp/WEB-INF/config/webmvc-config.xml
  • /src/main/webapp/WEB-INF/config/webflow-config.xml

I won't explore the gory details of the configuration here, as that is well covered in the Spring Web Flow 2 Reference Guide, but I will briefly examine the result of this configuration.

All requests that have a /spring path get routed through the Spring DispatcherServlet. The DispatcherServlet then looks at the rest of the URL and selects either a stateless JSF view to render, or it hands control over to SWF for rendering of a stateful JSF view.

So for example:

/spring/intro -> renders the stateless Facelets template at /WEB-INF/intro.xhtml

/spring/main -> hands control over to the flow defined at /WEB-INF/flows/main/main.xml

/spring/booking?hotelId=5 -> hands control over to the flow defined at /WEB-INF/flows/booking/booking.xml, passing the hotelId parameter as input to the flow

As you can see by examining the contents of the /flows directory (Figure 2), Spring Faces enables and encourages the organization of controller and view artifacts into logical re-usable modules.

  Figure 2 - Logical Organization of Modules
Figure 2 - Logical Organization of Modules

Agile JSF controllers with Spring Web Flow

The core power of Spring Faces comes from its deep integration with Spring Web Flow, and the ability to use the high-level flow DSL that provides concise and elegant constructs for event handling, domain model orchestration, and view navigation. Flow definitions are dynamic and hot-refreshable without an application restart, as well as fully unit-testable standalone without having to be deployed to the web container. This gives you a much more agile JSF development process that can better keep pace with the flow of ideas. Its finer-grained scopes (flash, view, and flow scopes) allow you to work directly with your domain model across multiple requests, so you can focus more energy on adding value to your domain model and spend less time worrying about the infrastructural concerns of saving and restoring the model on every request. This stateful nature makes for an excellent pairing with rich JSF views, where the model needs to be frequently manipulated in response to multiple events.

With Spring Faces, the JSF postback lifecycle is executed under the control of SWF. As opposed to SWF 1.x's limited integration approach where the flow execution was wedged into the JSF lifecycle via a PhaseListener, the Spring Faces JSF extension points build directly on SWF constructs. This allows for several architectural advances that weren't previously possible such as:

  • JSF views now work smoothly with SWF's automatic POST+Redirect+GET behavior, eliminating the step-behind-URL and browser refresh warning problems inherent in typical JSF applications.
  • FacesMessages are adapted to and from Spring Binding's lower-level web-independent MessageContext, providing deep integration with Spring's strong i18n support. Messages are stored in flash scope so that they will be preserved across redirects.
  • The component tree state is automatically synchronized with the flow execution state, with pluggable storage mechanisms to allow handling of various clustering scenarios

All of the integration classes use the standard JSF delegation approach, so for non-Spring requests, everything will pass through to the default implementation. This allows you to incrementally introduce Spring Faces into a traditional JSF application. In the next installment, I'll examine in detail some of the code from the sample application, to show how SWF addresses the aforementioned deficiencies of the traditional JSF controller model, and enables the "Spring all the way down" approach.



RSS feed(all feeds)

The Editor's Desk
Podcasts
Inside Facelets
In the Trenches

Site version 1.83  Report web site problems

Copyright (C) 2003-2015 Virtua, Inc. All Rights Reserved. Java, JavaServer Faces, and all Java-based marks are trademarks or registered trademarks of Oracle Corporation. in the United States and other countries. Virtua, Inc. is independent of Oracle Corporation. All other trademarks are the sole property of their respective owners.