The Java EE 6 Web Tier: JSF 2 Gains Facelets, Composite Components, Partial State Saving and Ajax
Ajax support is one of a number of areas where the JSF 2 Expert Group have been able to draw on community experience, addressing another frequent criticism of JSF 1; that it was designed by the Expert Group with limited external input. For example JSF 2 has deprecated JSP as its view layer, replacing it with the more JSF-centric Facelets, which started life as an open source project under the Apache license and was developed independently of the JCP. Facelets has seen widespread adoption amongst JSF developers since it eliminated the issues raised in Hans Bergsten's article "Improving JSF by Dumping JSP", including the mismatch between the rendering order of JSF and JSP. Since the standardised Facelets is more deeply integrated into the framework than was possible with the stand-alone version the Expert Group have also been able to take some of the key ideas further. For example Facelets supports templating via composite components, which may be any valid Faclets XHTML page. When using Facelets with JSF 1.x however composite components are not treated as true UI components. In JSF 2 they are, and can therefore support validators, converters, and listeners (both action and value change).
The Expert Group also drew heavily on ideas from the Seam framework, amongst them view parameters, an evolution of Seam's page parameters, which are a mapping between a query string parameter and a model value. Mappings are specified using the new <f:viewParam> component, which lives in the <f:metadata> section of the view. View parameters allow GET request parameters to participate in the JSF request lifecycle with full support for parameter decoding, type conversion, validation and model updates. A GET request can also invoke an application-defined listener via the PreRenderViewEvent which is fired after view parameters have finished processing, but before the view is rendered.
Rounding out support for GET requests in JSF are two related additions to the Standard HTML RenderKit (<h:link> and <h:button>) which provide a means for JSF 2 to generate GET requests links. When combined with view parameters these provide the foundation for bookmarkable pages in JSF 2.
The PreRenderViewEvent mentioned above is an example of a System Event, another new JSF feature influenced by Seam and also Ken Paulsen's work on JSFTemplating. System Events are a publish/subscribe style event bus for things that occur during the JSF lifecycle. Listeners can be registered at one of three scopes:
- component - UIComponent.subscribeToEvent()
- view - UIViewRoot.subscribeToEvent()
- application - Application.subscribeToEvent()
Publish is always with Application.publishEvent()
JSF 2 also looks to address a number of other pain points for developers using the framework. These include:
- Navigation improvements: There are new implicit navigation rules so that developers don't have to define every navigation case in faces-config.xml. The navigation subsystem also now offers support for conditional navigation allowing a pre-condition to be specified as an EL expression using the <if> configuration element.
- State saving: The saved state information in JSF tends to be substantial, making client-side session saving impractical so resulting in heavy use of the session. Apache Trinidad included a feature called State Saving which has also been adopted into JSF 2, becoming the default for pages written with Facelets. The new implementation, referred to as Partial State Saving, relies on the component tree being restored to its initial state by re-executing the view, and then updating it to reflect any changes that have taken place since. In effect it takes advantage of the fact that a lot of state information is typically embedded in the page in a mark-up based UI. The result is a significant reduction of the pre-view state size, typically making it around 4x smaller than in JSF 1.2.
- Annotation support for configuration: Both Managed Beans and Custom Components get new annotation support reducing the amount of XML required.
Finally, JSF 2 introduces a number of smaller enhancements. Amongst the key ones:
- Standardisation of a "project stage" parameter: Project stage provides a means to affect JSF behaviour based on a set of pre-defined enums which may be set via a context parameter or JNDI. For example, additional debug information might be displayed in a browser during development and suppressed in production. Defined stages include production, development, unit test and system test, with production as the default value. At run time you can query the application object for the configured value by calling Application.getProjectStage().
- New scopes: View scope preserves state until the user finishes interaction with the current view, whilst flash scope is an idea borrowed from Ruby on Rails. Anything placed in flash scope will be exposed to the next view encountered by the same user session and then cleared out.
- Built in integration with Bean Validation: JSR 303, Bean Validation, aims to provide a unifying mechanism for expressing constraints across the different tiers of an application, such as DDL updates when generated via an ORM tool, entity validation on insertion/update by the Java Persistence API, and JavaServer Faces components. Along with other parts of the Java EE stack, JSF 2 has been updated to work with Bean Validation constraints.
- Error handling improvements: The Facelets error page is more informative than the JSF 1.x one including, for example, the line numbers within the Facelet file. JSF 2 also introduces a new ExceptionHandler API providing a centralised mechanism for handling exceptions.
Since it was first introduced in March 2004, JavaServer Faces has been heavily criticised as the standard Java web framework. JSF 2 has addressed the vast majority of complaints and has added a number of new features, making it worth another look if you are considering a component based approach for your next web application. However to fully assess how effective JSF 2 may be you need to consider it in the wider context of the Java EE Web Profile - in particular CDI, described here, which provides both a type-safe, annotation-driven dependency injection framework, and a declarative way to manage the scope, state and life-cycle of components bound to contexts, and EJB/JPA which we'll look at in a future article.
1. HTTP GET (and may be other HTTP verbs)
2. Loose coupling between UI and web tier. Why server is deciding the UI rendering? This is the main drawbacks of JSF IMHO. Just deprecating JSPs in favor of Facelets will not bring the flexibility that a content developer should have. The spec still enforces a single view technology.
3. Multiple HTML form on same page.
4. Please do not create specs which are contradicting with each other; best example being Portlet and JSF. Both have their own rendering mechanism (JSR 301 is yet to address it properly) and make it a developer's life hell.
Re: JSF 2
1 - GET (as explained in the article above) is well served by JSP 2.
2. Not sure what you mean here. You seem to be talking about two separate things. JSF has never enforced a single view technology. I don't really see how this connects to loose coupling either. The point about loose coupling, surely, is to get a decent separation of concerns so that the UI is decoupled from the model which JSF manages reasonably successfully. The web model itself dictates that all logic is sent from the server to the browser. How is JSF any different here from anything else?
3. You've always been able to have multiple forms on one page in JSF.
4. Can you elaborate on why this is an issue or how it is an issue?
Re: JSF 2
The spec still enforces a single view technology.
This is something I didn't draw attention to in the article but JSF 2 actually includes a ViewDeclarationLanguage API which allows framework authors to define their own view declaration languages and integrate these with JSF in a standard way. So I'd say that JSF 2 actually provides a lot of flexibility in terms of the way the view layer operates.
Re: JSF 2
2. JSF-2 says deprecation of JSP and embrace Facelet. Why? What's wrong with JSP?
3. When your server maintains UI hierarchy information, that increases coupling.
4. Can you tell me why JSR-301 came into picture? Why we need a bridge for Portlet and JSF components?
Re: JSF 2
JSF 2 *does* support HTTP GET. Quoting from the news post
"View parameters allow GET request parameters to participate in the JSF request lifecycle with full support for parameter decoding, type conversion, validation and model updates. A GET request can also invoke an application-defined listener via the PreRenderViewEvent which is fired after view parameters have finished processing, but before the view is rendered."
"JSF-2 says deprecation of JSP and embrace Facelet. Why? What's wrong with JSP?"
Choosing JSP as the view technology for JSF 1 was fairly sensible as a pragmatic choice - it is well known and understood and didn't require any new development work. But (again as described in the news post) it caused a few problems for JSF since it was a separate piece of technology with its own rendering order and so on - see onjava.com/pub/a/onjava/2004/06/09/jsf.html for more details on this.
"When your server maintains UI hierarchy information, that increases coupling."
> Doesn't every web framework do this? I don't really see a problem with it either - its just the nature of the web surely that some state information is generally stored on the server. The important thing, I think, is that my rendering is independent from my model/business layer (which JSF has always supported particularly well) so I can chop and change presentation technologies and potentially swap out one presentation framework for another.
"Can you tell me why JSR-301 came into picture? Why we need a bridge for Portlet and JSF components? "
Oh I see what you mean here. I guess if you are using a portlet that proxies for JSF artefacts it would be a pain. I've never seen the point of portals really so it isn't an issue I've ever come across. I guess because portlets have never been part of the base Java EE spec they've not felt the need to standardise the model.
Re: JSF 2
Thanks for the explanation. I always had a bad impression on JSF because the only project I worked on JSF was to develop a reporting portlet on Jboss portal. That was really hell.
Anyways, hope to see some implementation of JSF-2 soon. We are however, going with Spring MVC for now.
Re: JSF 2