What is JSF? Introducing JavaServer Faces

Find out what's new in JSF 2.3, the Java standard for developing component-based, event-oriented web UIs

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.

Evolving JSF

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.

Building component-based web interfaces in JSF

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.

Listing 1. JSF sample page


<lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<lt;html xmlns=http://www.w3.org/1999/xhtml  xmlns:h="http://xmlns.jcp.org/jsf/html" >
   <lt;h:head>
      <lt;title>Hello JavaWorld!<lt;/title>
   <lt;/h:head>
   <lt;body>
      #{javaBean.content}
   <lt;/body>

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 <h:head> element.

HTML components in JSF

In terms of syntax, Listing 1's <h:head> 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 <h:head> 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.)

Nesting components

Inside the head is nested a standard HTML <title> element. This element is provided to the <h:head> 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.

Using Java objects in JSF

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.

Structure of a JSF application

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.

JSF 2.3: Spec and implementations

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.

MVC in JSF 2.3

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.

Controller beans

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:

  1. Decide where to direct user requests
  2. Set up POJOs for the model
  3. Use the model to render the Facelets view

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.

Listing 2. A JavaBean defined using CDI


import javax.inject.Named;
import javax.enterprise.context.SessionScoped;

@Named
@ViewScoped

public class JavaBean  implements Serializable {
  private String content = ìWelcome to JSF!î
  // getters/setters

}

JSF 2.3 with PrimeFaces

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.

primefaces showcase Matthew Tyson

Figure 1. PrimeFaces showcase

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

basic table Matthew Tyson

Figure 2. Basic DataList component output

PrimeFaces DataList: Accessing the data model

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.

Listing 3. Facelet for PrimeFaces DataList


<p:dataList value="#{dataListView.cars1}" var="car" type="ordered">
  <f:facet name="header">
    Basic
  </f:facet>
  #{car.brand}, #{car.year}
</p:dataList>

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 <f:facet...> 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.

DataList's server-side components

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. DataListView class


package org.primefaces.showcase.view.data;

import java.io.Serializable;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.inject.Named;  // Pre JSF 2.3, this was: 
				     // import javax.faces.bean.ManagedBean;
import javax.inject.Inject;
import javax.faces.bean.ViewScoped;
import org.primefaces.showcase.domain.Car;
import org.primefaces.showcase.service.CarService;

@Named
@ViewScoped

public class DataListView implements Serializable {
    private List<Car> cars1; 
    private Car selectedCar;

    @Inject("#{carService}")
    private CarService service;

    @PostConstruct
    public void init() {

        cars1 = service.createCars(10);
    }
    public List getCars1() {
        return cars1;
    }
    public void setService(CarService service) {
        this.service = service;

    }
}

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

Dependency injection and annotations

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.

1 2 Page 1
Page 1 of 2
  
Shop Tech Products at Amazon