JavaServer Faces (JSF) is the Java standard technology for building component-based, event-oriented web interfaces. Like JavaServer Pages (JSP), JSF allows access to server-side data and logic. Unlike JSP, which is essentially an HTML page imbued with server-side capabilities, JSF is an XML document that represents formal components in a logical tree. JSF components are backed by Java objects, which are independent of the HTML and have the full range of Java abilities, including accessing remote APIs and databases.

The key idea to a framework like JSF is to encapsulate (or wrap) client-side technologies like HTML, CSS, and JavaScript, allowing developers to build web interfaces without much interaction with these technologies.

This article presents a snapshot of JSF's approach to component-based UI development for Java web applications. Simple examples introduce JSF's MVC architecture, event model, and component library. Examples include new features in JSF 2.3, and we'll use PrimeFaces for our component library.

Long popular, JSF has recently faced competition from Java-compatible web frameworks, including client-side JavaScript frameworks. Still, JavaServer Faces remains the Java standard, especially for large-scale, Java enterprise development. The JSF specification has also spawned a wealth of frameworks and libraries, which have kept pace with recent client-side improvements. One of these is PrimeFaces, which we explore in this tutorial.

While the schedule for future development is unclear, JSF 2.3 gives developers plenty to work with while we wait. Released in March 2017, JSF 2.3 was intentionally designed to modernize JSF. Among several hundred small repairs and larger updates, JSF 2.3 deprecates managed bean annotations in favor of CDI, which I'll introduce later in this tutorial.

In September 2017, Oracle announced its intention to transition Java EE to the Eclipse Foundation. Java EE has since been rebranded to Jakarta EE, and JSF 2.3 (Eclipse Mojarra) has been adopted for continuation. The next major release of the JSF specification will be Eclipse Mojarra 3.0.

JSF's core idea is to encapsulate functionality into reusable components. This is similar to the reusable tags used in JSP, but JSF components are more formal.

While you can use JSF pages within JavaServer Pages, it's more common to use Facelets to build standalone JSF pages. Facelets are XHTML pages designed for defining JSF interfaces. With Facelets, you use XML tags to create a component tree that becomes the scaffold for a JSF user interface.

Listing 1 presents the main parts of a simple JSF page written using Facelets. In this example we're accessing Java's server-side capabilities via a bean that's been placed in scope via CDI. You'll see more about CDI later on.

In Listing 1 we see a standard XHTML page. A Facelets view is built on top of XHTML. In addition to the XHTML namespace, a secondary namespace is defined and referenced.

The h library contains standard components for use in JSF HTML pages. The http://xmlns.jcp.org/jsf/html library defines a collection of JSF components, in this case a collection of common HTML elements. One of these components is the element.

In terms of syntax, Listing 1's element references the jsf/html library with the h prefix. It then references the specific component within the library, which is the head component.

The component outputs the HTML head element. (All that syntax might seem like overkill for such a simple purpose, but there's good reason for it, as you'll see shortly.)

Inside the head is nested a standard HTML element. This element is provided to the component, along with the content child elements nested inside of it.

In the body of the doc, a JSF expression is contained by the #{} syntax. This is exactly analogous to a JSP expression with the ${} format: it allows the access of Java objects in scope, and simple functions.

The basic pattern for JSF is simple: Use Facelets to build an XML tree that references a component library or libraries, then use components within the library to render Java objects as HTML.

Going back to Listing 1, notice that inside the JSF expression (${javaBean.content) The javaBean object is in scope when this markup is executed. The XHTML of Facelets accesses the .content property on the javaBean object. The final output is a web interface that merges the Facelets view structure with Java's server-side data and logic capabilities.

Using a JSF expression is just one way to access Java application data from a JSF user interface. Eventually, you'll want to explore other ways a JSF component can interact with the Java backend--things like data lists and grids and a variety of input controls. For now, it's enough to absorb how JSF uses XML tags (or annotations) to create a tree of components that outputs HTML based on the data contained in Java objects.

With JSF 2.3 it has become possible to define JSF components with annotations, eschewing XML metadata entirely. It's fully possible to define and deploy a JSF app without editing any XML.

Like JavaServer Pages and the Servlet API, JavaServer Faces requires a standard directory structure and metadata. These are deployed as .war files.

The structure of a .war file is similar to a Servlet or JSP application. It contains a /web-app directory, which holds the application's markup files (in this case HTML, JSP, and Facelets), as well as a /WEB-INF directory, which presents the metadata to describe the application.

While you can run JSF in a Java EE container like Glassfish, a simple servlet container is all you really need. Tomcat is a popular container for JSF and other server-side Java technologies.

One of Java's strengths is that it is standards based, and those standards are governed by an open source community process. Since its inception, the Java Community Process (JCP) has overseen the development of Java technology. Once a specification or specification improvement has been developed and approved by JCP, it is available to be implemented by multiple parties. Until recently, Servlets, JSP, and JSF were all developed using JCP's open source specification process.

The most recent JSF specification as of this writing is JSF 2.3, released as part of Java EE 8 in 2017. Oracle's (now Eclipse's) Mojarra is the JSF reference implementation, and MyFaces and PrimeFaces are popular third-party implementations.

Each of these frameworks implements the JSF core, which includes some standard components. Vendors may also offer additional component libraries on top of the standard. When evaluating JSF frameworks, it's a good idea to consider the needs of your application and what component libraries are available to help you build it. Ideally, your JSF framework should get you as close as possible to what you need, right out of the box.

JSF is an MVC framework, implementing the model-view-controller pattern. In the MVC pattern, the idea is to separate the three concerns of a UI into discreet parts, so they're easier to manage. In general, the view is responsible for displaying data in the model, and the controller is responsible for setting up the model and routing the user to the correct view.

In a JSF implementation, the view is the Facelets page with its set of XML tags. These define the layout of the user interface. The other half of using JSF is the server-side, where Java classes back those UI components.

Managed bean annotations have been deprecated in JSF 2.3, and replaced by CDI (Contexts and Dependency Injection). With CDI, developers define a context and inject objects to that context. Those familiar with managed beans will find the annotation syntax slightly different, but the semantics remain exactly the same.

In JSF 2.3, controller beans provide the controller part of the MVC equation. Normal Java objects (often called POJOs, or plain old Java objects) provide the model.

In terms of process flow, controller beans:

JSF then folds together the component tree and model to render the output HTML.

Listing 2 shows how you would define the javaBean object from Listing 1 using CDI. This listing assumes the application has the cdi-api-1.2.jar in its dependencies.

In the next sections I'll use PrimeFaces to show you how JSF implements the MVC pattern, event-driven messaging, and reusable components. To start, open up the PrimeFaces Showcase, click the Data link in the left-side column, and select DataList. This will pull up the DataList demo code for PrimeFaces.

Figure 1 shows you where to find these samples.

Figure 1. PrimeFaces showcase

Figure 2 shows the output of a simple data table, which is taken from the PrimeFaces DataList demo.

Figure 2. Basic DataList component output

Listing 3 presents the markup for this dataList display. If you scroll to the bottom of the PrimeFaces showcase, you can see the markup in the dataList.xhtml tab.

In Listing 3, notice the value property of the dataList component. You can see that this references a dataListView object, and accesses the .cars1 property on it. The component is going to use the model object returned by that field. JSF tokens use conventional accessors to reference object properties, so .cars1 will refer to the getCars() getter on the object.

Next, notice the var="car" property. This tells the dataList component what variable to use when it iterates over the list of cars returned by the value field. These properties are specific to the dataList component, but the value property is very common. The var attribute is also conventional for components that iterate over lists.

In the body of the component in Listing 3, you can see the car variable is accessed via JSF expressions like #{car.brand}. Each iteration of the dataListView.cars1 instance will output the car.brand field.

Notice that the tag demonstrates the ability to customize components for how they will display. In this case, the header is defined as Basic.

You can see how the Facelets XML will drive this output by combining the data with the markup. Now let's look at the Java code behind it.

Listing 4 shows DataListView, the Java class that is used by the markup in Listing 3. You'll see shortly how the dataListView instance is associated with the DataListView class.

Listing 4 has a few other important elements, which we'll consider piece by piece.

First, notice that the DataListView class is annotated with @Named, which you can see from the import import javax.inject.Named; is part of JSF. The @Named annotation tells JSF this bean is part of the app. The @ViewScoped annotation informs JSF that the bean will live for just the life of the view.

ITNews