BUY THIS BOOK
Add to Cart

Print Book $39.95


Add to Cart

PDF $27.99

Safari Books Online

What is this?

Add to UK Cart

Print Book £28.50

What is this?

Looking to Reprint or License this content?

JavaServer Faces
JavaServer Faces

By Hans Bergsten
Book Price: $39.95 USD
£28.50 GBP
PDF Price: $27.99

Cover | Table of Contents | Colophon


Table of Contents

Chapter 1: Introducing JavaServer Faces
Over the last few years, Java has established itself as the leading technology for web application development. Developers are using technologies like servlets and JSP to develop scalable and robust browser-based user interfaces for countless applications with great success. But as web applications become more complex, some developers are longing for the good ol' days of traditional graphical user interface (GUI) frameworks with rich, powerful user interface widgets and event-driven development models. Servlets and JSP have served us well, but HTTP's stateless nature and simple, coarse-grained request/response model forces application developers using these technologies to struggle with details that are handled behind the scenes by GUI frameworks like AWT/Swing, the standard GUI framework for Java.
To make it easier to develop sophisticated web application user interfaces, open source projects and commercial companies have developed frameworks that mimic traditional GUI frameworks as far as possible. Some notable examples are Enhydra's Barracuda, Apache's Tapestry, Oracle's UIX, and Sun's JATO. In the spring of 2001, a Java Community Process (JCP) group was formed with representatives from most of these efforts (including yours truly) to come up with a standard solution that all frameworks can use. The result is JavaServer Faces; the 1.0 version of the specification was released in March 2004.
JavaServer Faces (JSF) simplifies development of sophisticated web application user interfaces, primarily by defining a user interface component model tied to a well-defined request processing lifecycle. This allows:
  • Java programmers to develop the application backend without worrying about HTTP details and integrate it with the user interface through a familiar event-driven model with type-safe interfaces.
  • Page Authors without programming knowledge to work with the user interface "look and feel" aspects by assembling components that encapsulate all user interaction logic—thereby minimizing the need for program logic embedded directly in the user interface pages.
  • Vendors to develop powerful tools for both frontend and backend development.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
What Is JavaServer Faces?
JavaServer Faces (JSF) simplifies development of sophisticated web application user interfaces, primarily by defining a user interface component model tied to a well-defined request processing lifecycle. This allows:
  • Java programmers to develop the application backend without worrying about HTTP details and integrate it with the user interface through a familiar event-driven model with type-safe interfaces.
  • Page Authors without programming knowledge to work with the user interface "look and feel" aspects by assembling components that encapsulate all user interaction logic—thereby minimizing the need for program logic embedded directly in the user interface pages.
  • Vendors to develop powerful tools for both frontend and backend development.
More specifically, JSF is a specification with implementations offered by multiple vendors. It defines a set of user interface (UI) components—basically, a one-to-one mapping to the HTML form element set plus a few extras—that can be used right out of the box, as well as an Application Programming Interface (API) for extending the standard components or developing brand new components. Validators attached to the components validate user input, which is then automatically propagated to application objects. Event handlers are triggered by user actions, such as clicking on a button or a link, and can change the state of other components or invoke backend application code. The outcome of the event processing controls which page is displayed next, with help from a pluggable navigation handler.
While HTML is the markup language of choice for most web applications today—and used for most examples in this book—JSF is not limited to HTML or any other markup language. Renderers that are separate from the UI components control the actual markup sent to the client, so the same UI component coupled with different renderers can produce very different output—for instance, either HTML and WML elements. If you're familiar with Swing, think "pluggable look and feel" (PLAF).
JSF gives you lots of flexibility in how you actually develop the user interface. All JSF implementations are required to support JavaServer Pages (JSP) as a presentation layer technology, with JSF components represented by JSP custom action elements (also commonly known as
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
How Does JSF Compare to Traditional Technologies?
JSF brings a component-based model to web application development that is similar to the model that's been used in standalone GUI applications for years. Let's look at some of the advantages this gives you compared to more traditional web application technologies.
Java web applications user interfaces have typically been implemented as a set of JSP pages (or pages for similar template-engine technologies, such as Velocity or FreeMarker), where static content (e.g., text and HTML elements for layout) is mixed with elements that generate dynamic content when the page is processed. A problem with this approach is that the pages often end up with logic for maintaining the user interface state—for instance, code for marking checkboxes and list items as selected and for displaying current values in input fields.
When you use JSF with JSP as the presentation layer technology, special elements (JSP custom actions) represent the JSF components. Here's a snippet of a page with a form showing a user's food preferences as a set of HTML checkboxes:
    ...
    <h:form>
      <table>
      ...
        <tr>
          <td>Favorite Foods:</td>
          <td>
            <h:selectManyCheckbox value="#{cust.foodSelections}">
                             <f:selectItem itemValue="z" itemLabel="Pizza" />
                             <f:selectItem itemValue="p" itemLabel="Pasta" />
                             <f:selectItem itemValue="c" itemLabel="Chinese" />
                           </h:selectManyCheckbox>
          </td>
        </tr>
        ...
      </table>
    </h:form>
    ...
The details are not important at this stage, but note that there are no loops or conditional tests in the page. This logic is instead encapsulated in the JSF components represented by the <h:selectManyCheckbox> and <f:selectItem> elements. When the form is submitted, the JSF framework saves the list of current selections in an application object on the server (referenced by the #{cust.foodSelection} expression specified by the value attribute in this example). When the response is rendered, JSF uses the list to check off the corresponding boxes. Separating logic from the layout in this manner makes the page author's life easier.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Where Does JSF Fit in the Big Picture?
JSF may not be a good fit for all web applications. If you develop a web site where the dynamic aspects are limited to things like pulling content from a database, generating dynamic navigation menus, adding dynamic "cookie trails" to the pages, and other features that just make it easier to maintain the site content and simplify access to different parts of the site, JSF may be overkill. The best fit for JSF is a true web application—a web site with a lot of user interaction—rather than a web site with some dynamic content. A simple dynamic web site is probably easier to implement and maintain using only servlets and JSP, or even just JSP and the JSP Standard Tag Library (JSTL).
JSF does not necessarily replace current technologies. It's a complement that brings structure and maintainability to the application user interface. The following sections describe how JSF fits with some established Java web application technologies.
As you have already seen, JSF plays nicely with JSP. In fact, all JSF implementations must support JSP and provide tag libraries with custom actions for representing the standard JSF UI components in JSP pages. If you're familiar with JSP, adding JSF to the mix is fairly simple. While you can use JSP to develop complete, simple applications without writing a single line of Java code, be aware that most JSF applications require event handlers and backend logic implemented as Java classes; hence, you must have a Java programmer handy when you use JSF.
You may have noticed that I refer to Struts and similar frameworks as application frameworks, and to JSF as a user interface framework. I do this to emphasize that they have different objectives. An application framework's objective is to support the development of complete applications; it's concerned with the Big Picture. This type of framework acts as a traffic cop, routing HTTP requests to request handling code and internal view requests to response rendering code based on mappings between symbolic names and the different types of application components. An application framework doesn't care about details, such as how the user interface is rendered, or make any distinction between user actions that only affect the user interface (e.g., asking for the next set of rows to be displayed in a table) and actions that need to be processed by backend code (e.g., processing an order on an e-commerce site). Struts, for instance, can use JSP, Velocity, XSLT, or any other presentation layer technology to render a response. The Struts servlet just routes requests to application classes that process them and then tell Struts which page to display next.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
What You Need to Get Started
Before we begin, let's quickly run through what you need in order to work with the examples in this book and develop your own applications:
  • A PC or workstation, with a connection to the Internet so you can download the software you need
  • A Java 2-compatible Java Software Development Kit (Java 2 SDK)
  • A JSP 2.0-enabled web server, such as Apache Tomcat 5 from the Jakarta Project
  • A JSF 1.0 implementation, such as Sun's Reference Implementation
All the examples in the book were tested on Tomcat 5 with the JSF Reference Implementation, but they should work with any JSP 2.0-compliant web container and JSF implementation. In Chapter 4, I'll show you how to download, install, and configure the Tomcat server to run the examples.
In addition, there are a variety of other tools and servers that support JSF, from open source projects and commercial companies. IBM, Oracle, and Sun are some of the companies that have announced plans for JSF development tools, and many others are expected to follow. Two sites to keep an eye on for what's available are http://java.sun.com/j2ee/javaserverfaces/(Sun's JSF site) and http://www.jamesholmes.com/JavaServerFaces/ (an independent JSF resources site run by James Holmes). You may want to evaluate some of these tools when you're ready to start developing your application, but all you really need to work with the examples in this book is a regular text editor, such as Notepad, vi, or Emacs, and of course the Tomcat server.
Let's take a closer look at what JSF has to offer. The next chapter starts with an overview of what it takes to use JSF in an application.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Chapter 2: JSF Development Process Overview
Imagine building a flight reservation application with a web interface. The user first enters the departure and destination airports and dates, and preferences such as ticket type, airlines, and number of stops. This information is then validated and the user is presented with matching flight choices. When the user picks his preferred flights, the application ensures that the seats are available and marks them as reserved, calculates the cost, verifies credit card information, and finalizes the purchase.
People who are not computer gurus use applications like this, so the user interface must be intuitive and easy to use, error messages must be understandable, and the underlying problems must be simple to correct. For instance, the interface may let the user pick the destination airport by first asking for a country, state, or city name, and then present a selection of airports matching the criteria, provide calendars for choosing the dates, and display tables with flights to choose from. And the interface must be easy to enhance with accumulated user feedback and usage log analysis. The backend code requirements are also complex: accessing real-time flight schedules and reservation information, interfacing with credit card companies, and providing secure tracking of all transactions.
Clearly, this is not an application that can be slapped together without careful design. Applying the Model-View-Controller (MVC) principles briefly introduced in Chapter 1, we first break the application into classes that represent the business data and logic (the Model, including things like Customer, Airport, Flight, Seat, and so on), the user interface (the View, including things like Departure Input Field, Airport List, and so on), and the code that ties it all together (the Controller).
The View can be implemented in many different ways, using both client-side and server-side technologies. For instance, any of the traditional Java server-side technologies like JSP, Velocity, or plain servlets can render an HTML page with input fields, selection lists, and tables representing calendars. For complex user interfaces like this, however, the traditional technologies tend to result in pages with so much code that it becomes hard to make purely visual changes, such as changing the layout of a table.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Developing an Application with a JSF-Based User Interface
To get an idea of how JSF simplifies development and maintenance of complex web-based user interfaces, let's implement a simple newsletter subscription application. The application contains a form where the user enters an email address and selects the newsletters of interest from a list, plus a button for submitting the form. Figure 2-1 shows this user interface.
Figure 2-1: Newsletter subscription form
When the user submits the form, the email address and subscription list is saved in a database. Other parts of the application use this information to send the newsletters, but we'll focus on this single page here.
JSF-based application development involves a number of different activities. It helps to define the different roles that the developers play, and then discuss the application aspects each role is responsible for. One person can, of course, take on more than one role. First, you need an implementation of the JSF framework itself. This is the responsibility of the JSF implementor, a role that's usually performed by web container vendors. Another role, the tool provider, is responsible for developing tools to support JSF application development. Some web container vendors take on this role as well, but vendors specializing in development tools, such as Macromedia, are also likely candidates. Remember that JSF is a specification, not a product, so you have a choice of many competing implementations.
Most development projects use an existing JSF framework and tools, so let's focus on the remaining roles: the application developer, the component writer, and the page author. Implementing the newsletter subscription example shows you what parts each role is responsible for and gives you a glimpse of how JSF works.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Developing the Application Backend
The application developer is primarily responsible for developing the backend part of the application; in other words, the classes that handle business logic and data.
For the newsletter subscription form, the application developer may create a class called Subscriber to hold the subscriber information:
package com.mycompany.newsservice.models;

public class Subscriber {
    private String emailAddr;
    private String[] subscriptionIds;

    public String getEmailAddr( ) {
        return emailAddr;
    }

    public void setEmailAddr(String emailAddr) {
        this.emailAddr = emailAddr;
    }

    public String[] getSubscriptionIds( ) {
        return subscriptionIds;
    }

    public void setSubscriptionIds(String[] subscriptionIds) {
        this.subscriptionIds = subscriptionIds;
    }
}
The Subscriber class adheres to the JavaBeans method naming conventions—"properties" are defined by methods for getting their values, named get plus the name of the property, and methods for setting their values, named set plus the property name. As you'll see shortly, this makes it easy to use properties of this class as JSF UI component models.
When a subscription is registered or updated, the information must be saved somewhere, likely in a database. The application developer may decide to develop a separate class responsible for this task or put this logic in the Subscriber class. To keep the example simple, we'll add a method that represents this behavior to the Subscriber class. Also, instead of saving the information in a database, we just write it to System.out:
    public void save( ) {
        StringBuffer subscriptions = new StringBuffer( );
        if (subscriptionIds != null) {
            for (int i = 0; i < subscriptionIds.length; i++) {
                subscriptions.append(subscriptionIds[i]).append(" ");
            }
        }
        System.out.println("Subscriber Email Address: " + emailAddress +
            "\nSubscriptions: " + subscriptions);
    }
This is all the backend code we need for this simple application. Note, however, that none of these application classes refer to JSF classes; the same classes could be used with any type of user interface.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Developing Components and Integration Code
The component writer develops all application-specific Java code needed for the user interface, ranging from simple classes that tie the user interface to the application backend code developed by the application developer to custom user interface components when the ones provided by JSF aren't sufficient.
Figure 2-2 shows the main classes and interfaces used by the newsletter application.
Figure 2-2: JSF component-related classes and the Subscriber application class
You probably recognize the Subscriber class from the previous section. The component writer develops the SubscriberHandler class, as shown in this section. All the other classes in Figure 2-2 are provided by the JSF implementation.
The UIComponentBase class is the base class for all JSF UI components. Subclasses represent specific interface elements, such as text fields, links and buttons, labels, menus and selection lists. JSF includes a set of component classes that can be used right out of the box, such as the ones shown in Figure 2-2, but a component writer can also implement custom components if needed. The UIInput class represents an input field and lets you bind the component to an application model through a value binding. When a component is rendered, it pulls its value from the application model object based on this value binding. Similarly, when an input component processes a request, it updates the model it's bound to with the value received with the request. In this example, value bindings for the UIInput and the UISelectMany (the checkbox group) components bind the components to the corresponding properties in the Subscriber application class.
The components fire events in response to user actions (such as clicking a button) and event listeners attached to the components handle the events (for example, by updating a database). Instead of implementing and registering listeners for each component, most JSF applications take advantage of shortcuts in the form of method bindings. A method binding is similar to a value binding, but it binds a component to an application method instead of an application property value. For instance, the
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Developing the User Interface Pages
With the Java classes defined and implemented in some form (maybe just prototypes initially), the page author can get to work.
The page author is the person who is responsible for developing the pages that make up the application's user interface, typically as templates that interleave static content (text, graphics, tables for layout, and so on) with dynamically generated content. A page is represented by a set of UI component instances bound to the application's data and methods. The static content and the dynamic content generated by the components is combined and sent to the browser. When the user clicks a link or a button in the page, the request is processed by the methods bound to the UI components. Depending on the outcome, the same page may be rendered again or the application may select a new page to send back to the user.
As I mentioned earlier, JSF can be combined with different presentation layer technologies, so the details of what the template looks like may vary depending on the options supported by the JSF implementation. For better or for worse, JSF 1.0 requires all implementations to support JSP as one of the possible presentation layer technologies. On one hand, JSP is familiar to many developers, so it lowers the barrier of entry to JSF. On the other hand, JSP has its own mechanism for adding dynamic content to a static template; when mixed with JSF UI components, there's a risk for confusion and clashes between the two technologies. I use JSP for the newsletter application and for most of the other examples in this book, but you should be aware that it's not the only option. Don't worry too much about the potential clashes between JSP and JSF. I'll explain the issues and show you how to steer clear of the potential problems as we encounter them.
When JSP is used as the presentation layer technology, the page author creates a JSP page with the static content plus special elements that represent JSF components. Example 2-1 shows a JSP page with JSF elements for the newsletter subscription form.
Example 2-1. JSP page with JSF elements for the subscription form (newsservice/subscribe.jsp)
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Chapter 3: Setting Up the JSF Environment
You need two things to run a JSF application: a Java web container and an implementation of the JSF specification.
There are plenty of Java web containers available, including commercial offerings, such as Caucho Technology's Resin, the BEA WebLogic Server, the IBM WebSphere Application Server, and the Oracle Application Server, and open source products, such as the Apache Tomcat server, Mortbay's Jetty server, and Gefion Software's LiteWebServer. JSF requires a web container that implements at least the Servlet 2.3 and JSP 1.2 specifications (part of J2EE 1.3), but the examples in this book use some features introduced in JSP 2.0, so to run them as is, you need a web container that implements the Servlet 2.4 and JSP 2.0 specifications (part of J2EE 1.4). All examples have been tested with the open source Tomcat 5 server (on which the reference implementation for these specifications is based) and I recommend that you use it as you read this book and develop your own JSF applications.
JSF is such a new technology that as of this writing, there aren't many implementations besides the reference implementation from Sun Microsystems available yet. This will change during 2004, though, so when you read this, your favorite web container may bundle a JSF implementation. The web application containing all the book examples includes a version of the reference implementation, and I recommend that you use it. You can always download the latest version of the JSF reference implementation from Sun's site at http://java.sun.com/j2ee/javaserverfaces. For deployment of your applications, you may want to use the JSF implementation supported by your production server instead, if any.
In this chapter, you will learn how to install the Tomcat server and deploy the web application containing all the examples used in this book. You can, of course, use any web server that supports JSP 2.0, but Tomcat is a good server for development and test purposes. You can learn more about the Jakarta project and Tomcat, as well as how you can participate in the development, at the Jakarta web site:
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Installing the Java Software Development Kit
Tomcat 5 is a pure Java web server with support for the Servlet 2.4 and JSP 2.0 specifications. In order to use it, you must first install a Java runtime environment. If you don't already have one, you can download a Java runtime for Windows, Linux, and Solaris at http://java.sun.com/j2se/. I recommend that you download and install the Java 2 SDK (a.k.a. JDK), as opposed to the slimmed-down Runtime Environment (JRE) distribution. The reason is that JSP, and therefore JSF applications that use JSP, requires a Java compiler, included in the SDK but not in the JRE.
Another alternative is to use the JRE plus the Jikes compiler from IBM (http://www10.software.ibm.com/developerworks/opensource/jikes/). Tomcat can be configured to use Jikes instead of the javac compiler available in the Java 2 SDK from Sun; read the Tomcat documentation if you would like to try this. To make things simple, though, I suggest installing the Java 2 SDK from Sun. The examples were developed and tested with Java 2 SDK, Standard Edition, v1.4.2. I suggest that you use the latest version of the SDK available for your platform.
If you need an SDK for a platform other than Windows, Linux, or Solaris, check your operating-system vendor's web site. Most operating-system vendors have their own SDK implementation available for free. Installation of the SDK varies per platform, but it is typically easy to do. Just follow the instructions on the web site where you download the SDK.
Before you install and run Tomcat, make sure that the JAVA_HOME environment variable is set to the installation directory of your Java environment, and that the Java bin directory is included in the PATH environment variable. On a Windows system, you can see if an environment variable is set by typing the following command in a command prompt window:
C:\> echo %JAVA_HOME%
C:\jdk1.4.2
If JAVA_HOME isn't set, you can set it and include the bin directory in the PATH on a Windows system like this (assuming Java is installed in C:\jdk1.4.2):
C:\> set JAVA_HOME=C:\jdk1.4.2
C:\> set PATH=%JAVA_HOME%\bin;%PATH%
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Installing the Tomcat Server
Tomcat supports many features and configuration options. In this section, I only describe the basics that you need to know to get Tomcat up and running. If you plan to use Tomcat extensively for development or as a production server, you'll find extensive information in Jason Brittain and Ian Darwin's Tomcat: The Definite Guide (O'Reilly).
You can download the Tomcat server in binary format or as source code that you compile yourself. If you're primarily interested in learning about JSF, I recommend that you use the binary download for running the examples in this book and to develop your own applications. If you're a Java programmer and are interested in seeing how Tomcat is implemented, feel free to download the source as well and take a look at the internals.
The binary distribution is available at http://jakarta.apache.org/site/binindex.cgi. On this page, you will find three types of builds: release builds, milestone builds, and nightly builds. Release builds are stable releases that have been tested extensively and verified to comply with the supported specifications. Milestone builds are created as intermediary steps towards a release build. They often contain new features that aren't yet fully tested but are generally known to work. A nightly build, however, may be very unstable. It's actually a snapshot of the latest source code and may have been tested only by the person who made the latest change. You should use a nightly build only if you're involved in the development of Tomcat.
I recommend that you download the latest release build. All examples in this book were developed and tested using Version 5.0.18, but any release later than 5.0.18 should work fine as well. The release builds are available as archive files of different formats. Which one to pick and how to install it varies a bit, depending on your platform.
For Windows, select jakarta-tomcat-5.0.18.zip and save it to your hard drive—for instance, in a directory named C:\Jakarta. Unpack the package either with a ZIP utility program such as
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Testing Tomcat
The Tomcat installation directory contains a number of subdirectories. All of them are described in the README.txt file, but the most important ones are:
bin
Scripts for starting and stopping the Tomcat server.
conf
Tomcat configuration files.
webapps
Default location for web applications served by Tomcat.
Two more subdirectories under the Tomcat home directory are created the first time you start the server:
logs
Server log files. If something doesn't work as expected, look in the files in this directory for clues as to what's wrong.
work
A directory for temporary files created by the JSP container and other files. This directory is where the servlets generated from JSP pages are stored.
To test the server, run the startup script as described in the platform-specific sections, and (assuming you're running Tomcat on the same machine as the browser and that you're using the default 8080 port for Tomcat) open a browser and enter this URL in the Location/Address field: http://localhost:8080/.
The Tomcat main page is shown in the browser, as in Figure 3-1. You can now run all examples bundled with Tomcat to ensure everything works.
Figure 3-1: The Tomcat main page
If you're trying this on a machine that sits behind a proxy—for instance, on a corporate network—and instead of Tomcat's main page you see an error message about not being able to connect to localhost, you need to adjust your proxy settings. For Netscape and Mozilla, you find the proxy settings under Edit Preferences Advanced Proxies, and for Internet Explorer, you find them under Tools Internet Options Connections > LAN Settings. Make sure that the proxy isn't used for local addresses, such as localhost and 127.0.0.1.
When you're done testing Tomcat, stop the server like this:
C:\Jakarta\jakarta-tomcat-5.0.18\bin> shutdown
         
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Installing the Book Examples
All JSP pages, HTML pages, Java source code, and class files for the examples can be downloaded from the O'Reilly site at http://www.oreilly.com/catalog/jsvrfaces/.
They can also be downloaded from my personal web site, where you also find articles, tips, and other resources:
http://www.hansbergsten.com/
On this site, you'll find a Download page where you can download the examples distribution file, called jsfexamples.zip. Save the file on your hard drive (for instance, in C:\JSFBook on a Windows platform) and unpack it:
C:\JSFBook> jar xvf jsfexamples.zip
         
You can use the same command on a Unix platform.
Two new directories are created: jsfbook and src. The first directory contains all examples described in this book, and the second contains the Java source files for the JavaBeans, custom components, and other classes used in the examples.
The examples directory structure complies with the standard Java web application format described in Chapter 4. You can therefore install the examples in any JSP 2.0-compliant web container to run the examples. If you like to use a container other than Tomcat, be sure to read the documentation for that container for instructions on how to install a web application.
To install the example application for Tomcat, simply copy the web application directory structure (the jsfbook directory) to Tomcat's default directory for applications, called webapps. On a Windows platform, you can copy/paste the directory structure with the Windows Explorer tool, or use this command in a Command Prompt window:
C:\JSFBook> xcopy /s /i jsfbook %CATALINA_HOME%\webapps\jsfbook
         
On a Unix platform it looks like this:
[hans@gefion jsfbook] cp -R jsfbook $CATALINA_HOME/webapps
         
As you'll learn more about in Chapter 4, each web application in a server is associated with a unique URI prefix (the context path). When you install an application in Tomcat's webapps directory, the subdirectory name is assigned automatically as the URI prefix for the application (/jsfbook, in this case).
To run the examples, you must also define a couple of usernames. If you use the Tomcat server, edit the
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Example Web Application Overview
The examples for this book are packaged as a standard Java web application. All servers compliant with the JSP 2.0 specification support this file structure, so you can use the example application as a guideline when you create your own web applications. How a web application is installed isn't defined by the specification, though, and it varies between servers. With Tomcat, you simply copy the file structure to the special webapps directory and restart the server. To modify the configuration information for an application, you must edit the application's WEB-INF/web.xml file using a text editor. Other servers may offer special deployment tools that copy the files where they belong, and let you configure the application using a special tool or through web-based forms.
If you look in the jsfbook web application directory, you'll see that it contains an index.html file and a number of directories. These directories contain all the example JSP and HTML pages.
There's also a WEB-INF directory with a web.xml file, a lib directory, and a classes directory. We will look at this in much more detail later, starting in Chapter 4, but here's a quick review:
web.xml file
The web.xml file contains configuration information for the example application in the format defined by the servlet and JSP specifications. It's too early to look at the contents of this file now; we will return to parts of it when needed.
Lib and classes directories
The lib and classes directories are standard directories, also defined by the servlet specification. A very common question asked by people new to servlets and JSP (prior to the standard web application format) was, "Where do I store my class files so that the server can find them?" The answer, unfortunately, differed depending on which implementation was used. With the standard web application format, it's easy to answer this question: if the classes are packaged in a JAR file, store the JAR file in the lib directory; otherwise, use the classes directory (with subdirectories mirroring the classes' package structure). The server will always look for Java class files in these two directories.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Chapter 4: Servlet and JavaServer Pages Basics
A JSF-based application runs as a web application in a Java web container. While the Java Servlet API dependencies are limited to a few classes, and a simple JSF application never needs to be exposed to it, the main concepts defined by the Servlet specification must be understood to develop and deploy a JSF application. In addition, JavaServer Pages (JSP) technology—which is based on the Servlet API—is often used as the presentation layer in a JSF application.
This chapter is a brief introduction to the Hypertext Transport Protocol (HTTP), servlets, and JSP, focusing on the areas that are important for a JSF application. This chapter contains the bare minimum you need to know to understand the rest of this book. I recommend that you read books dedicated to the subjects of servlets and JSP before you embark on a real development project. Two books I can recommend are Jason Hunter's and William Crawford's Java Servlet Programming (O'Reilly) and my own JavaServer Pages (O'Reilly). If you're already familiar with these technologies, you can safely skip this chapter.
The Hypertext Transport Protocol (HTTP) is the lingua franca of the web. In order to develop any type of web application, you must understand at least the basics of this protocol. Before we dig into servlets and JSP, let's see what HTTP is all about.
HTTP is based on a very simple communications model. Here's how it works: a client, typically a web browser, sends a request for a resource to a server, and the server sends back a response corresponding to the resource (or a response with an error message if it can't process the request for some reason). A resource can be a number of things, such as a simple HTML file returned verbatim to the browser or a program that generates the response dynamically. The request/response model is illustrated in Figure 4-1.
Figure 4-1: HTTP request/response with two resources
This simple model implies three important facts you must be aware of:
  • HTTP is a stateless protocol; the server doesn't keep any information about the client after it sends its response, and therefore can't recognize that multiple requests from the same client may be related.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
HTTP
The Hypertext Transport Protocol (HTTP) is the lingua franca of the web. In order to develop any type of web application, you must understand at least the basics of this protocol. Before we dig into servlets and JSP, let's see what HTTP is all about.
HTTP is based on a very simple communications model. Here's how it works: a client, typically a web browser, sends a request for a resource to a server, and the server sends back a response corresponding to the resource (or a response with an error message if it can't process the request for some reason). A resource can be a number of things, such as a simple HTML file returned verbatim to the browser or a program that generates the response dynamically. The request/response model is illustrated in Figure 4-1.
Figure 4-1: HTTP request/response with two resources
This simple model implies three important facts you must be aware of:
  • HTTP is a stateless protocol; the server doesn't keep any information about the client after it sends its response, and therefore can't recognize that multiple requests from the same client may be related.
  • Web applications can't easily provide the kind of immediate feedback typically found in standalone GUI applications, such as word processors or traditional client/server applications. Every interaction between the client and the server requires a request/response exchange. Performing a request/response exchange when a user selects an item in a list box or fills out a form element is usually too taxing on the bandwidth available to most Internet users.
  • There's nothing in the protocol that tells the server how a request is made; consequently, the server can't distinguish between various methods of triggering the request on the client. For example, the server can't differentiate between an explicit request caused by clicking a link or submitting a form and an implicit request caused by resizing the browser window or using the browser's Back button. In addition, HTTP doesn't provide any means for the server to invoke client specific functions, such as going back in the browser history list or sending the response to a certain frame. Also, the server can't detect when the user closes the browser.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Web Application Deployment and Runtime Environment
A JSF-based application consists of a lot of different pieces: user interface template files (e.g., JSP pages), static HTML files and image files, as well as class files for business logic, custom components, and so on. All pieces are packaged and deployed as a web application archive (WAR). The servlet specification describes the internal structure of the WAR and an application deployment descriptor containing configuration and metadata for the application.
The WAR structure contains directories for files accessed directly by browsers, such as HTML files and JSP pages, and directories for configuration files and classes seen only by the application. Here's part of the WAR structure for the example application we'll develop in this book:
/cover.gif
/index.html
/expense/reports.jsp
...
/WEB-INF/web.xml
/WEB-INF/classes/JSPSourceServlet.class
...
/WEB-INF/lib/commons-logging.jar
/WEB-INF/lib/jsf-api.jar
/WEB-INF/lib/jsf-ri.jar
/WEB-INF/lib/jsfbook.jar
...
The top level in this structure is the document root for all public web application files; in other words, all the files requested directly by the browser. For instance, the index.html file is a page with links to all book examples, and the expense/reports.jsp file is a JSP page used as a template in an example application.
The WEB-INF directory is the root for internal application files and it's inaccessible to a browser. This directory contains the application deployment descriptor (web.xml), as well as subdirectories for other types of resources, such as Java class files and configuration files. Two WEB-INF subdirectories have special meaning: lib and classes. All application class files must be stored in these two directories. The lib directory is for Java archive (JAR) files (compressed archives of Java class files). Class files that aren't packaged in JAR files must be stored in the classes directory, which can be convenient during development. The files must be stored in subdirectories of the classes directory that mirror their package structure, following the standard Java conventions. For instance, a class in a package named
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Servlets, Filters, and Listeners
All new Java web-tier technologies, such as JSP, JSF, and portlets, are defined on top of the API that started it all: the Servlet API. A servlet is a Java class that processes a request from a client and produces a response. Most implementations of the JSF specification use a servlet as the entry-point for the page requests, and some JSF-based applications may also include a few servlets and other classes defined by the servlet specification, such as listeners and filters.
The Servlet API is general enough to allow servlets to deal with any request/response-based protocol, but it's almost exclusively used with HTTP. The API consists of two packages: the javax.servlet package contains classes and interfaces that are protocol-independent, while the javax.servlet.http package provides HTTP-specific extensions and utility classes.
For HTTP processing, one class and two interfaces make up the bulk of the API:
javax.servlet.http.HttpServlet
This is the base class for most servlets. It contains empty default implementations of two methods that can be overridden by a subclass for initialization and release of internal resources used by a servlet: init() and destroy( ). The init() method is called once before the servlet is asked to process its first request, and the destroy() method is called just before the servlet is taken out of service.
The base class also provides default implementations of the request processing methods, one for each HTTP request type: doGet( ), doPost(), doDelete( ), doHead(), doOptions( ), doPut(), and doTrace( ). Most subclasses override the doGet() and doPost() methods (or at least one of them) to handle the corresponding HTTP request types, but rely on the default implementations for the other request types.
javax.servlet.http.HttpServletRequest
This interface represents the HTTP request, with methods for reading request parameters, headers, and the request URL. Other methods let you add, read, and remove application data—called request attributes—associated with the request. This mechanism comes in handy when the servlet delegates some of the processing (e.g., the rendering of the response) to another application class, as I describe later.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
JavaServer Pages
You can use JSF in a couple of fundamentally different ways: use the JSF API in pure Java code to generate the complete web page, or use JSF together with some sort of template that holds static markup for the overall page layout and place holders for JSF components that generate dynamic content. JavaServer Pages (JSP) fits the bill for the latter scenario and is supported out-of-the-box by all JSF implementations.
The JSP specification was created to allow all println( ) calls for adding HTML elements to the response that you see in Example 4-1 Example 4-2 to be moved from the servlet code to a separate file. This file can be managed by someone who knows HTML but is not a programmer, allowing programmers to focus on developing the application business logic instead of changing details in the user interface look every so often. Figure 4-6 illustrates this separation of concerns on different application component types.
Figure 4-6: Separation of request processing, presentation, and business logic
The servlet is still in charge of request processing, but it uses JSP pages to render the response. The business logic can also be forked off to separate JavaBeans components, typically created and populated with data by the servlet, and read by the JSP pages.
The result of this separation is a much more efficient development process. It also makes it possible to change different aspects of the application independently, such as changing the business rules without touching the user interface.
A JSP page is simply a regular web page combining static markup with JSP elements that generates the parts that differ between requests, as shown in Figure 4-7.
Figure 4-7: Template text and JSP elements
Everything in the page that isn't a JSP element is called template text. Template text can be any text: HTML, WML, XML, or even plain text. When a JSP page request is processed, the static template text and the dynamic content generated by the JSP elements are merged, and the result is sent as the response to the browser.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Accessing Application Data
The different parts of a Java web application need to be able access the same data objects. For instance, a product catalog object a listener creates at application start must be accessible by a servlet that processes a user query against the catalog, and the result of the query must be available to the JSP page that renders the response showing the result.
The Servlet API includes methods for managing this type of data as attributes of the objects representing the application, the user session, and the request, defined by these classes, respectively: javax.servlet.ServletContext, javax.servlet.http.HttpSession, and javax.servlet.ServletRequest.
All three classes contain these methods for managing the attributes:
public void setAttribute(String name, Object value);
public Object getAttribute(String name);
public void removeAttribute(String name);
In the product catalog example, the listener uses the setAttribute() method on the ServletContext to make the catalog available to the servlet, and the servlet uses the getAttribute( ) method to obtain it. To make the query result available to the JSP page, the servlet calls the setAttribute( ) method of either the HttpSession or the ServletRequest object (depending on how long the result must be available).
The JSP specification refers to these three attribute collections as different scopes: the application, session, and request scope. It also adds a collection of attributes available only to objects within the same JSP page during the processing of a request. It calls this the page scope. Figure 4-11 shows the lifetime and visibility of objects in the different scopes.
Figure 4-11: Lifetime and visibility of objects in different scopes
The JSP EL provides implicit variables that represent the scopes as java.util.Map instances, as shown in Table 4-5. Assuming the servlet in the product catalog example saves the query result as a bean with properties named rowCount and rows in a request attribute named
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Chapter 5: Developing the Business Logic and Setting Up Authentication
The best way to learn a new technology is to use it. In this book, I guide you through the development of an application with a JSF-based user interface. Along the way, we look at all the fundamental JSF concepts and use most of the JSF components. As we progress through the chapters, we'll build the application in stages, starting with a simple but functional version and then adding pieces to make it easier to maintain and make it look nicer. In this chapter, we'll walk through the layout and functionality of the final version of the application.
All versions of the application use the same business logic classes. This is a nice illustration of the separation of concerns supported by JSF: the business logic stays the same even when the user interface goes through significant changes. We look at all the business logic classes in this chapter. In the following chapters, we'll develop additional classes that make it easy to tie JSF components to these business logic classes.
The sample application relies on information about who the user is and adapts the functionality based on this information. In the last part of this chapter, we therefore look at how to configure the web container to handle identification of the user.
The sample application is a web-based expense report system. Employees enter their expense reports and submit them for approval; a manager looks at the reports and either accepts or rejects them. All users have to log in before they can access the application.
The main user interface consists of a single screen, shown in Figure 5-1. Employees and managers both use this screen, but different options are enabled depending on who's logged in.
Figure 5-1: The expense reports screen
The screen is divided into three main areas: a menu area at the top, a report list area to the left, and a report details area to the right. The menu area contains buttons for operations that affect the report displayed currently in the report details area. Its content differs depending on whether the user is an employee or a manager. An employee gets buttons for creating a new report, deleting the current report, and submitting the current report for approval. The buttons are enabled or disabled depending on the report's status. For instance, as long as the report has the status New (i.e., no entries have been added to it yet), all buttons are disabled; when at least one entry has been added (status Open), all buttons are enabled; when the report has been submitted (status Submitted), only the New button is enabled. If a manager is logged in, the menu area contains additional buttons for accepting or rejecting the report. These buttons are enabled only if the current report is submitted for approval.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Sample Application Overview
The sample application is a web-based expense report system. Employees enter their expense reports and submit them for approval; a manager looks at the reports and either accepts or rejects them. All users have to log in before they can access the application.
The main user interface consists of a single screen, shown in Figure 5-1. Employees and managers both use this screen, but different options are enabled depending on who's logged in.
Figure 5-1: The expense reports screen
The screen is divided into three main areas: a menu area at the top, a report list area to the left, and a report details area to the right. The menu area contains buttons for operations that affect the report displayed currently in the report details area. Its content differs depending on whether the user is an employee or a manager. An employee gets buttons for creating a new report, deleting the current report, and submitting the current report for approval. The buttons are enabled or disabled depending on the report's status. For instance, as long as the report has the status New (i.e., no entries have been added to it yet), all buttons are disabled; when at least one entry has been added (status Open), all buttons are enabled; when the report has been submitted (status Submitted), only the New button is enabled. If a manager is logged in, the menu area contains additional buttons for accepting or rejecting the report. These buttons are enabled only if the current report is submitted for approval.
The report list area provides access to existing expense reports. It contains two subareas. The filtering criteria area contains fields for a date range, report status choices, and a Filter button for applying the criteria. There's also an implicit filtering criteria: a regular employee sees only her own reports, but a manager sees reports owned by any employee.
The report list area contains a table with all reports matching the filtering criteria. The table rows can be sorted by clicking on the column labels. To make a report the current report, with the details shown in the report details area, the user clicks on the report title in the table.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Implementing the Business Logic Classes
Content preview·