BT

Facilitating the Spread of Knowledge and Innovation in Professional Software Development

Write for InfoQ

Topics

Choose your language

InfoQ Homepage News The Java EE 6 Web Tier: JSF 2 Gains Facelets, Composite Components, Partial State Saving and Ajax

The Java EE 6 Web Tier: JSF 2 Gains Facelets, Composite Components, Partial State Saving and Ajax

This item in japanese

In a previous article we looked at the Servlet 3.0 API including its support for Ajax. Whilst it took a great deal of work to make the Servlet API suitable for this family of technologies, Java EE's web framework, JavaServer Faces (JSF) has always been a more natural fit for the Ajax approach since the JSF framework maintains a stateful UI component tree. JSF 1.x, however, did not have built in Ajax support, relying instead on support from a number of third party libraries such as Ajax4jsf/RichFaces, ICEFaces and ADF Faces/Trinidad. JSF 2.0, included as part of EE 6, addresses this by adding support for partial page updates and partial view traversal so that selected components in the view can be processed, rendered, or both, without requiring the entire page to be re-drawn. When a user interface event occurs, the server simply processes the relevant sections of the tree and pushes any changes back to the browser. JSF 2's Ajax support also make uses of the new "behaviour" concept. A component can have a behaviour attached to it to add support for a particular feature in the best way for that particular component. For example a text field can have the AjaxBehaviour attached to it causing events to be bound to the text field's JavaScript onChange() event. Similarly a command button could have an AjaxBehaviour attached to it which would trigger from the button's onClick() event.

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:

  1. 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.
  2. 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.
  3. Using multiple component libraries on one page: Since JSF 1.x did not include support for serving resources, component libraries generally developed their own servlet or filter for this purpose, such as Shale Remoting (now retired) or weblets. This made it very difficult for developers using multiple component libraries in the same page of the application since the resource servlets would frequently clash. JSF 2 provides a standard mechanism for defining and accessing resources from the classpath or from the file system, with built in support for image, JavaScript and CSS files, eliminating the problem.
  4. 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:

  1. 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().
  2. 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.
  3. 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.
  4. 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.

Rate this Article

Adoption
Style

BT