Introduction to JavaServer Faces

This article is meant to acquaint the reader with JavaServer Faces, commonly known as JSF. JSF technology simplifies building the user interface for web applications. It does this by providing a higher-level framework for working with your web app, representing the page as event-aware components rather than raw markup.

At this time, there are two JSF variants: JSF early access 4 (which is included in the Java Web Services Developer Pack 1.3), and JSF 1.0 Beta. It's important to remember that JSF is a specification, much like J2EE. And like J2EE, there is a reference implementation from Sun, along with other implementations of the interface, such as the open source MyFaces. This article is concerned with the distinctive features of the JSF specification and its ideas, not with a particular implementation. After all, since JSF is not yet final, the specifics might yet change.

We assume the reader is already somewhat familiar with Java programming, servlets, JavaServer Pages (JSPs) and custom tag technologies. The reader should be experienced with servlet/JSP containers such as Tomcat, and design patterns such as model-view-controller (MVC).

Roles in Web-Application Development

In developing web applications, we often deal with the same problems. First off, the interface is the most frequently updated part of the application, so we want to simplify modification of the interface as much as possible. Secondly, those developing the application have significantly different skill sets — server-side programmers, HTML coders, graphic designers, etc. — and we want their work to be as independent as possible. This leads to a model-view-controller design to separate the roles.

In many organizations, the development of a web application works in a familiar manner. The designer creates a prototype, the HTML coder does everything in HTML, and the server-side programmer achieves his or her needed functionality in Java. This approach often fails badly. The designer, when creating the prototype, is limited only by his or her imagination, inadvertently causing problems for the other participants, often forcing them to start from scratch when developing a new application.

Reusable Components

Even if the problem of role division can be solved in existing frameworks (for example, by using custom tags or XML/XSL transformations), there can still be a problem with code reuse. So what's so different between creating the GUI for a Swing application and a web application? It's obvious: in Swing, there is a set of standard GUI components and an entire infrastructure for tweaking and extending the functionality. A Swing developer works with the concept of a Component — an element of the user interface, such as a panel, button, list, or table — and can either set values to use the default behavior or extend the component to provide new behavior.

Some of these components, specifically Containers allow combinations of components, such as a panel with a table that contains buttons in some of its cells. As an added bonus, the developer gets to work with high-level concepts: when the button is clicked, an event is generated.

Meanwhile, for the web developer to know the button has been pressed, he has to analyze the HTTP request and try to determine what has happened. This is not ideal. The programmer shouldn't have to work so hard to figure out if a button, image, or hyperlink was clicked, or how these pieces were implemented in HTML. Ideally, the developer just wants to know that an event occurred. In other words, the developer needs to be able to see the web interface in terms of familiar high-level concepts.

This is the problem JSF aims to solve.

The JSF Approach

The following presentation of JSF concepts is based on the most recent specification (dated Dec. 18, 2003).

The core JSF architecture is designed to be independent of communication protocols or markup language specifics. However, it's also meant to solve the problems experienced working with HTML clients communicating via HTTP with a Java application server that supports Servlet/JSP applications. JSF aims to provide the following features to simplify application development:

Handling of UI components between requests.

Consideration of markup features supported by the client/browser.

Support for processing forms.

Strictly-typed event model.

Transformation of data on the page (Strings) into the models' corresponding data types.

User-friendly exception handling.

Navigation between pages based on UI events and interaction with data models.

Of course, when developing web applications today, everyone has to deal with these problems, and everyone solves them in their own way, increasing development time and hurting maintainability. JSF tries to offer a unified way to deal with these issues.

The specification understands the importance of dividing software development roles and assigns responsibilities to these roles.

Page Authors

Page authors are responsible for the appearance of the application. They should understand client-side markup (HTML and JavaScript) and also page structure during development (such as JSP). Page authors usually create pages from ready-made components delivered by component developers, modifying them to achieve the desired appearance.

Component Writers

Making components "understandable" to the final client (e.g., providing HTML to a browser). This process involves encoding information from the application.

Making the application understand the request form, by decoding the information in a request.

Reacting to events received by a component and understanding when such an even has occurred.

Application Developers

Application developers are responsible for the server-side tasks, such as creating an application's business logic, its persistence layer, etc. They should develop appropriate Java objects to represent the desired functionality, and make these objects accessible from servlets.

Tool Providers

Tool providers supply tools like IDEs that facilitate creating JSF-based applications, or even higher-level frameworks that might use JSF to create their user interface.

JSF Implementors

JSF implementors are responsible for implementing all the required specifications of JSF. For example, they might provide a JSF implementation within their J2EE server.

Note that most developers will not perform either of the latter two roles. But they indicate the seriousness of Sun's intentions with respect to role-division: for JSF to succeed, it's necessary to follow the role-division guidelines.

JSF in Detail

Let's look in detail at what JSF provides us. As noted above, the highlight of JSF is the availability of reusable server components for creating GUI's. From JSF's point of view, all components should inherit from javax.faces.component.UIComponent (note that in the EA4 release this was an interface). Any page or screen of the application will consist of a set of such components. A set of hierarchically ordered components is called the JSF Tree (EA4's term) or the View (1.0 beta's term). This tree of components represents the structure of the onscreen page. Each element of a tree is UIComponent, with some components being composites and thus having child components.

In JSF there is a set of standard components. The UML diagram shows the notation structure of these standard components. The developer can create new components based on existing components (for example, by inheriting from UIOutput), or by a completely new subclass of UIComponent. To make creating components easier, it's possible to inherit from UIComponentBase, which contains default implementations for the methods in UIComponent along with some convenience methods.