Fear, uncertainty, and doubt (FUD) has been circulating about J2EE's JavaServer Faces (JSF) technology for a while now and I've decided the time has come to put a stop to it; or at least offer a balancing perspective. The first myth about JSF is that you need a WYSIWYG drag-and-drop tool to do JSF development. The second is that JSF doesn't support MVC Model 2 frameworks like Struts. And the final, most all-encompassing myth about JSF development is that it's just plain difficult.
In this four-part series, I'll do my best to dispel all three myths in the most practical way possible: by teaching you to work around them. The fact is, if you think JSF development is difficult you're probably not doing it right, and fortunately that's pretty easy to fix. I'll get you started this month with an architectural overview of JSF and a working example demonstrating the fundamentals of MVC and JSF. But before we get into all that, I'll take just a minute to separate some JSF FUD from fact.
As previously mentioned, there are three big myths about JSF and the first is that it requires WYSIWYG tools to work. Well, that's bunk. Just like many Swing developers don't use WYSIWYGs to build Swing applications, you don't need WYSIWYG editors to build JSF applications. In fact, JSF development without WYSIWYG tools is much easier than development with traditional Model 2 frameworks like Struts and WebWork. I'll explain why in detail later in this article, but for now just remember that you read it here first: JSF development is much easier than Struts, even without the WYSIWYG tools!
The next myth about JSF is that it doesn't support the Model 2 architecture. Now, this is actually partially true. The fact is that Model 2 is a watered down version of MVC (Model-View-Controller) for Web development built on top of Servlets. Whereas Model 2 is geared towards a stateless protocol (HTTP), JSF supports a richer MVC model, a much closer approximation of a traditional GUI application. While the basis in MVC does make JSF framework implementations harder to build than other frameworks, the upside is that a lot of the real work of implementing JSF has already been done for you, so your net effort is less and your net gain is considerably more.
The broadest and most widespread myth about JSF development is that it's hard. I hear this most often from people who have read a lot about the technology but haven't actually tried it out for themselves, so I think I can clear it up pretty easily. The fact is, if you based your opinion of JSF on its admittedly extensive specification -- with all its lifecycle diagrams and pictures -- then the technology could easily scare the mess out of you. The thing to remember, though, is that the spec is for the implementers of the tools, not for application developers per se. As previously mentioned, the JSF framework is designed to be remarkably easy on the application developer.
In fact, although the component-based, event-driven GUI development model of JSF is somewhat new to the Java world, it has existed for quite some time elsewhere. Apple's WebObjects is a similar architecture to JSF and so is ASP.net. Tapestry is an open source Java-based Web component framework that takes a somewhat different approach from JSF's but is also founded on a Web GUI component model.
And that's probably enough talk about FUD, for now anyway. The easiest way to dissolve your preconceptions about JSF is to delve right into the technology, and we'll do that in just a few minutes. But just in case this is your first-ever look at JSF, I'll start with an architectural overview.
Like Swing and AWT JSF is a development framework that provides a set of standard, reusable GUI components. JSF is used for building Web application interfaces. JSF provides the following development advantages:
- Clean separation of behavior and presentation
- Component-level control over statefulness
- Events easily tied to server-side code
- Leverages familiar UI-component and Web-tier concepts
- Offers multiple, standardized vendor implementations
A typical JSF application consists of the following parts:
- JavaBeans components for managing application state and behavior
- Event-driven development (via listeners as in traditional GUI development)
- Pages that represent MVC-style views; pages reference view roots via the JSF component tree
While you will need to overcome some conceptual hurdles to use JSF, doing so is well worth the effort. JSF's component state management, easy to use user input validation, granular, component-based event handling, and easily extensible architecture will greatly simplify your Web development efforts. I'll explain the most important of these features in greater detail in the next several sections.
A component-based architecture
JSF provides component tags for every input field available in standard HTML. You can also write your own custom components for application-specific purposes or for combining multiple HTML components together to form a composite -- for example a Data Picker component that consists of three drop-down menus. JSF components are stateful. The statefulness of the components is provided through the JSF framework. JSF uses components to produce HTML responses.
JSF's component set includes an event publishing model; a lightweight IoC container; and components for just about every other common GUI feature, including pluggable rendering, server-side validation, data conversion, page navigation management, and more. Being a component-based architecture, JSF is extremely configurable and extensible. Most JSF functions -- such as navigation and managed bean lookup -- can be replaced with pluggable components. This degree of pluggability gives you considerable flexibility in building your Web application GUIs and allows you to easily incorporate other component-based technologies into your JSF development efforts; for example, you could replace JSF's built-in IoC framework with the more full-featured IoC/AOP Spring framework for managed bean lookups.
The user interface of a JSF application is comprised of JSP (JavaServer Pages) pages. Each JSP page contains JSF components that represent the GUI functionality. You use JSF custom tag libraries inside JSP pages to render the UI components, to register event handlers, to associate components with validators, to associate components with data converters, and more.
That said, the truth is that JSF is not bound to JSP technology inherently. In fact, the JSF tags used by JSP pages merely reference the components so they can be displayed. You'll realize this the first time you modify a JSP page to change the attributes of a JSF component and reload the page, and nothing happens. This is because the tag looks up the component in its current state. Thus, if the component already exists the custom tag will not modify its state. The component model allows your controller code to change the state of a component (for example, disable a text field), and when that view is displayed the current state of your component tree will be displayed.
A typical JSF application needs no Java code and very little JSTL EL (JSP Standard Tag Library, Expression Language) code in the UI. As previously noted, there are lots of IDE tools for building and assembling applications in JSF, and there seems to be a growing third-party market for JSF GUI components. It is also possible to code JSF without the use of WYSIWYG tools.
JSF is the result of lessons learned over several years of evolving
Web development techniques on the Java platform. This trend started with
JSP technology, which was nice but made it too easy to mix Java code in with HTML
(and HTML-like) pages. The next step up was the Model 1 architecture,
which had developers pushing most backend code into JavaBeans components and then
importing the JavaBeans components into Web pages with the <jsp:useBean> tag. This worked well for simple Web
apps, but many Java developers disliked JSP technology's incorporation of C++ features
such as static includes. So the Model 2 architecture was introduced.
Essentially, the Model 2 architecture is a watered-down version of MVC for Web applications (see "About MVC"). In the Model 2 architecture the controller is represented by Servlets and display is delegated to JSP pages. Struts is a simplified Model 2 implementation wherein Actions take the place of Servlets. In Struts the application's controller logic is separated from its data (represented by ActionForms). The main complaint against Struts is that it can feel more procedural than object-oriented. WebWork and Spring MVC are two other Model 2 architectures that improve on Struts by being less procedural, but neither is as widely accepted (nor as mature, some would argue) as Struts. Plus neither offers a component model like JSF does.
The real issue with most Model 2 frameworks is that the event model is too simplistic (essentially a very scaled down MVC), which leaves too much of the work to the developer. A richer event model makes it easier to create the kind of interactions most users expect. Like JSP technology, most Model 2s also make it too easy to mix HTML layout and formatting with GUI custom tags, which act loosely like components. And some Model 2 architectures (like Struts) make the mistake of separating behavior and state, which leaves many Java developers feeling like they're programming COBOL.
JSF provides a component model and a richer MVC environment than most Model 2 implementations. Essentially, JSF is much closer to a true MVC programming environment than the Model 2 architectures, although it's still a stateless protocol. JSF also facilitates building more fine-grained event-driven GUIs than the Model 2 frameworks. Whereas JSF gives you a host of event options -- menu item selected, button clicked, etc. -- most Model 2s rely on the more simple "request received."
JSF's fine-tuned event model allows your applications to be less tied to HTTP details and simplifies your development effort. JSF also improves somewhat on the traditional Model 2 architecture by making it easier to move presentation and business logic out of your controller and move business logic out of your JSP pages. In fact, simple controller classes aren't tied to JSF at all, making them easier to test. Unlike a true MVC architecture it is unlikely that the JSF model tier is issuing many events that have to be resolved in more than one viewport; again we are still dealing with a stateless protocol so this would be unnecessary. The system event for changing or updating a view is almost always (dare I say always?) a request from the user.
Details of JSF's MVC implementation
In JSF's MVC implementation, mapping backing beans mediate between view and model. Because of this it's important to limit the business logic and persistence logic in the backing beans. One common alternative is to delegate business logic to the application model. In this case the backing beans also map model objects where the view can display them. Another option is to put the business logic in a Business delegate, a facade that acts as the model.
Unlike JSP technology, JSF's view implementation is a stateful component model. The JSF view is comprised of two pieces: the view root and JSP pages. The view root is a collection of UI components that maintain the state of the UI. Like Swing and AWT, JSF components use the Composite design pattern to manage a tree of components (simply put: a container contains components; a container is a component). The JSP page binds UI components to JSP pages and allow you to bind field components to properties of backing beans (or properties of properties more likely), and buttons to event handlers and action methods.
Here's an example application (the one you're about to get to know in detail!) seen from an MVC point of view.
Figure 1. Example application from an MVC point of view
And that's enough fluff: let's get started with JSF!
For the remainder of the article I'll focus on the step-by-step process of actually creating an application in JSF. The example application is a very simple demonstration of JavaServer Faces technology. It demonstrates the following:
- How to lay out a JSF application for deployment
- How to configure a web.xml file for JSF
- How to configure a faces-config.xml for an application
- Writing Model beans (a.k.a. backing beans)
- Constructing the view using JSP technology
- Using custom tag libraries to construct the component tree in the view root
- Default validation of form fields
The example is a simple Calculator application. The goal in creating
the application is to present a page to the end user that allows him or
her to enter two numbers. Therefore the page has two text fields, two
labels, two error-message locations, and a Submit button. The text
fields are for entering the numbers. The labels are for labeling the
text fields. The error message locations are to display validation or
data-conversion error messages for the text fields. There are three JSP
pages: index.jsp, which just redirects to calculator.jsp;
calculator.jsp, which present the GUI mentioned above; and
results.jsp, which displays the results. A managed bean
called CalculatorController serves as the
backing bean for calculator.jsp and results.jsp.
Figure 2 shows a second MVC view of the example Calculator application. You can download the application source by clicking the Code icon at the top or bottom of this page.
Figure 2. Second MVC view of the sample application
To build the Calculator application in JSF you'll need to do the following:
- Collect the web.xml and faces-config.xml file, found
under the example application's src/webapp/WEB-INF directory.
- Declare the Faces Servlet, and Faces Servlet mapping in the web.xml file.
- Specify the faces-config.xml file in the web.xml file.
- Declare what beans get managed by JSF in the faces-config.xml file.
- Declare the navigation rules in the faces-config.xml file.
- View the model object
Calculator.
- Use the
CalculatorControllerto talk to theCalculatormodel.
- Create the index.jsp page.
- Create the calculator.jsp page.
- Create the results.jsp page.
Omitting step 1, which is really just setup, I'll go over each step in the process in detail.
Declare the Faces Servlet and Servlet mapping
In order to use Faces you first need to install the Faces Servlet in your web.xml file as shown here:
<!-- Faces Servlet -->
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup> 1 </load-on-startup>
</servlet>
|
This is very similar to most web.xml descriptors except that you're giving control over to the JSF Servlet to handle requests instead of specifying your own Servlet. All requests to JSP files that use f:view must go through this Servlet. Therefore, you need to add a mapping and only load the JSF-enabled JSP technology through that mapping, as shown here.
<!-- Faces Servlet Mapping -->
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>/calc/*</url-pattern>
</servlet-mapping>
|
The above tells the Faces Servlet container to send all requests that map to
/calc/ to the Faces Servlet for processing. This
allows JSF to initialize the JSF context and the view root.
Specify the faces-config.xml file
If you name your faces configuration file faces-config.xml and place it in the WEB-INF directory of your Web application then the Faces Servlet will pick it up and use it automatically (since it's the default). Alternatively, you may load one or more application configuration files through an initialization parameter in your web.xml file -- javax.faces.application.CONFIG_FILES -- with a comma-separated list of files as the argument. You will likely use the second approach for all but the simplest JSF Web applications.
Next, you will want to declare which beans get used by JSF GUI components. The example application only has one managed bean. It is configured in faces-config.xml as follows:
<faces-config>
...
<managed-bean>
<description>
The "backing file" bean that backs up the calculator webapp
</description>
<managed-bean-name>CalcBean</managed-bean-name>
<managed-bean-class>com.arcmind.jsfquickstart.controller.CalculatorController</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
</managed-bean>
</faces-config>
|
The above config tells JSF that you want to add a bean to the JSF context called
CalcBean. You can call your managed bean anything you want. With
the beans declared, your next step is to state the high-level navigation rules for the application.
For this simple application you need only to establish the navigation path from the calculator.jsp page to the results.jsp page, as shown below.
<navigation-rule>
<from-view-id>/calculator.jsp</from-view-id>
<navigation-case>
<from-outcome>success</from-outcome>
<to-view-id>/results.jsp</to-view-id>
</navigation-case>
</navigation-rule>
|
The above states that if an action returns the logical outcome "success" from the /calculator.jsp view, then forward the user to the /results.jsp view.
As my goal is to demonstrate how to get started with JSF, I've kept the model object very simple. The model of this application is contained within one model object, shown in Listing 1.
Listing 1. The Calculator app's model object
package com.arcmind.jsfquickstart.model;
/**
* Calculator
*
* @author Rick Hightower
* @version 0.1
*/
public class Calculator {
//~ Methods ----------------------------------------------------------------
/**
* add numbers.
*
* @param a first number
* @param b second number
*
* @return result
*/
public int add(int a, int b) {
return a + b;
}
/**
* multiply numbers.
*
* @param a first number
* @param b second number
*
* @return result
*/
public int multiply(int a, int b) {
return a * b;
}
}
|
With that, the business logic is all set up. Your next step is to glue it to the Web application interface.
The goal of the controller is to act as the glue from the model to
the view. One function of the Controller
object is to keep the model agnostic with regard to the view technology.
As you can see below, the controller specifies three JavaBeans properties
that will be used to collect input and display results. The properties
are results (output); firstNumber (input); and secondNumber (input). The Controller also presents two operations that
delegate to operations of the same name in the Calculator objects. Listing 2 shows the code for
the CalculatorController.
Listing 2. The CalculatorController
package com.arcmind.jsfquickstart.controller;
import com.arcmind.jsfquickstart.model.Calculator;
/**
* Calculator Controller
*
* @author $author$
* @version $Revision$
*/
public class CalculatorController {
//~ Instance fields --------------------------------------------------------
/**
* Represent the model object.
*/
private Calculator calculator = new Calculator();
/** First number used in operation. */
private int firstNumber = 0;
/** Result of operation on first number and second number. */
private int result = 0;
/** Second number used in operation. */
private int secondNumber = 0;
//~ Constructors -----------------------------------------------------------
/**
* Creates a new CalculatorController object.
*/
public CalculatorController() {
super();
}
//~ Methods ----------------------------------------------------------------
/**
* Calculator, this class represent the model.
*
* @param aCalculator The calculator to set.
*/
public void setCalculator(Calculator aCalculator) {
this.calculator = aCalculator;
}
/**
* First Number property
*
* @param aFirstNumber first number
*/
public void setFirstNumber(int aFirstNumber) {
this.firstNumber = aFirstNumber;
}
/**
* First number property
*
* @return First number.
*/
public int getFirstNumber() {
return firstNumber;
}
/**
* Result of the operation on the first two numbers.
*
* @return Second Number.
*/
public int getResult() {
return result;
}
/**
* Second number property
*
* @param aSecondNumber Second number.
*/
public void setSecondNumber(int aSecondNumber) {
this.secondNumber = aSecondNumber;
}
/**
* Get second number.
*
* @return Second number.
*/
public int getSecondNumber() {
return secondNumber;
}
/**
* Adds the first number and second number together.
*
* @return next logical outcome.
*/
public String add() {
result = calculator.add(firstNumber, secondNumber);
return "success";
}
/**
* Multiplies the first number and second number together.
*
* @return next logical outcome.
*/
public String multiply() {
result = calculator.multiply(firstNumber, secondNumber);
return "success";
}
}
|
Notice in Listing 2 that the multiply and
add methods return "success." The string
success
signifies a logical outcome. Note that it is not a keyword.
You used the string success when specifying
navigation rules in faces-config.xml; therefore, after the add or multiply operation is
executed the application will forward the user to the results.jsp page.
With that, you're done with the backing code. Next you'll specify the JSP pages and component trees that represent the application view.
The purpose of the index.jsp page in this application is to ensure that the /calculator.jsp page loads in the JSF context so that the page can find the corresponding view root. The index.jsp page looks as follows:
<jsp:forward page="/calc/calculator.jsp" /> |
All this page does is redirect the user to calculator.jsp under the
"calc" Web context. This puts the calculator.jsp page
under the JSF context, where it can find its view root.
Create the calculator.jsp page
The calculator.jsp page is the meat of the Calculator application's view. This page takes two numbers input by the user, as shown in Figure 3.
Figure 3. The Calculator page
Because this page is complex, I'll show you how to build it step by step. You'll start off by declaring the taglibs for JSF as follows:
<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %> <%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %> |
The above tells the JSP engine that you want to use the two JSF
taglibs html and core. The
html taglib contains all the tags for
dealing with forms and other HTML-specific goodies. The core taglib
contains all the logic, validation, controller, and other tags specific
to JSF.
Once you've laid out the page in normal HTML you want to tell the JSF
system that you're going to be using JSF to manage your components. You do
this by using the <f:view> tag, which
informs the container that you're using JSF to manage the components
contained inside of it. (When pronouncing this tag make sure you say
"f colon view"; it is very important to enunciate the colon lest you offend!)
Without <f:view>
JSF cannot build the component tree, and later cannot look up the
component tree that was already created. Use the <f:view> tag as follows:
<f:view>
<h:form id="calcForm">
...
</h:form>
</f:view>
|
The first line above is the declaration of <f:view>, telling the container that it is
managed by JSF. The next line is the <h:form>
tag telling JSF that you want an HTML form here. During the render phase
the components contained within the form component will be looked up and asked to
render themselves, whereupon they will generate standard HTML to the
output.
Next, you tell JSF what other components you want in the form.
Inside of the <h:form> you declare a
panelGrid. A panelGrid is
a composite component -- that is, a component that contains other components. The
panelGrid specifies the layout of the other
components. The panelGrid is declared as
shown in Listing 3.
Listing 3. Declaring the panelGrid
<h:panelGrid columns="3">
<h:outputLabel value="First Number" for="firstNumber" />
<h:inputText id="firstNumber" value="#{CalcBean.firstNumber}" required="true" />
<h:message for="firstNumber" />
<h:outputLabel value="Second Number" for="secondNumber" />
<h:inputText id="secondNumber" value="#{CalcBean.secondNumber}" required="true" />
<h:message for="secondNumber" />
</h:panelGrid>
|
The attribute column being set to 3 indicates that the components will be
laid out in a grid with three columns. You add six components to the
panelGrid, that is, two rows. Each row consists of an
outputLabel, an inputText,
and a message. The label and message are associated
with the inputText component; therefore, when a
validation error or error message is associated with the
textField, the message will show up in the
message component. Both of the text fields are
required, which means if their values are not present on submit an error message will
be created and control will return to this view; namely /calculator.jsp.
Notice that both inputFields use a JSF EL (JavaServer
Faces Expression Language) value binding for the value attribute (for example,
value="#{CalcBean.firstNumber}"). At first
blush this looks a lot like JSTL EL. However, the JSF EL code actually
associates the fields with the corresponding values of the backing beans
properties. This association is reflexive: that is, if
firstNumber was 100 then 100 would show up when the form
was displayed. Likewise, if the user submitted a valid value such as 200 then
200 would be the new value of the firstNumber property.
A more common (but also more involved) approach would be for the backing bean to expose model objects via properties and bind those model object properties to fields. You'll see an example of this approach in later articles in the series.
In addition to the fields, the calcForm is associated with two actions
using two commandButtons inside of a panelGroup, as shown below.
<h:panelGroup>
<h:commandButton id="submitAdd" action="#{CalcBean.add}" value="Add" />
<h:commandButton id="submitMultiply" action="#{CalcBean.multiply}" value="Multiply" />
</h:panelGroup>
|
The panelGroup is similar in concept to
the panelGrid with the exception that it lays
things out differently. The command buttons use the action="#{CalcBean.add}" to bind the button to a
method on the backing bean. Thus, when the form is submitted with the
button, the associated method gets invoked (assuming that all validation
is ok).
And with that -- whew! -- you're over the biggest hump of coding a JSF application. The last couple of steps will be a breeze.
The results.jsp page is used to display the results of the last calculator operation. It is defined as shown in Listing 4.
Listing 4. The results.jsp page
<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>
...
<f:view>
First Number: <h:outputText id="firstNumber" value="#{CalcBean.firstNumber}"/>
<br />
Second Number: <h:outputText id="secondNumber" value="#{CalcBean.secondNumber}"/>
<br />
Result: <h:outputText id="result" value="#{CalcBean.result}"/>
<br />
</f:view>
|
This results.jsp file is a relatively simplistic page that
displays the addition results to the user. It accomplishes this through
the <outputText> tag. The <outputText> tag takes an id and
value attribute. The value attribute outputs the bean value as a
string when rendered. The value attribute uses JSF to bind the output
value to your backing bean properties (namely, as you'll recall, firstNumber, secondNumber, and result).
To run this application go the page where the war file is mapped.
This causes the index.jsp file to load the calculator.jsp page. If you
enter some invalid text (for example, "abc") in either the firstNumber field or
the secondNumber field and submit, you will be taken back to the
/calculator.jsp view and an error message will be displayed next to the
corresponding field. If you leave either the firstNumber field or the
secondNumber field blank and submit, you will be taken back to the
/calculator.jsp view and an error message will be displayed next to the
corresponding field. Thus, you can see that some validation is nearly automatic in JSF
merely by specifying that the fields are required and binding the fields
to int properties.
Figure 4 shows how the application deals with validation and data conversion errors.
Figure 4. Validation and data conversion errors
If this intro to JSF has left you shaking your head a little, don't worry: you're over the worst hump. Getting into the conceptual framework of JSF is more than half the battle with implementing this technology -- and you'll soon see that it's well worth the trouble.
Just in case you're thinking that doing it with Struts would have
been easier, my estimate is that it would take at least twice the effort
to create the Struts version of the simple JSF application you built
here. To build the same example app in Struts you would need two action
classes for the two buttons, each requiring its own set of action
mappings. You would also need an action mapping to load the first page,
at least assuming you were following the Model 2 recommendation. To
mimic JSF's default error handling and validation you would have to
configure Struts to use the validator framework or implement the
equivalent in the validate method on an ActionForm. You would also have to either declare a
DynaValidatorForm in the Struts config or
create an ActionForm and override the validate method or use the subclass of the ValidatorForm with the hooks into validator
framework. And finally, you would probably need to configure some
forwards (possibly two sets for each action) or global forwards to be
used by all the actions.
In addition to doubling your coding, Struts takes a lot more effort for new developers to learn. I know this because I've written both a Struts course and a JSF course and I've taught them both. Developers pick up JSF easily and struggle with Struts. I believe a lot more forethought went into the design of JSF than Struts. JSF just makes more logical sense; it is intuitive. Struts was collected and evolved. JSF was specified and created. JSF development is simply more productive than Struts development in my book.
This concludes the first article in the JSF series. The next article will pick up where I've left off here. I'll cover the major phases of the JSF request processing lifecycle and point out where the different parts of the sample application fit into the lifecycle. I'll also introduce the concepts of immediate event handling and try to give you a fuller understanding of JSF's component event model, including a discussion about many of the built-in components that ship with the technology. I'll also talk some about combining JavaScript with JSF, so be sure to check back in next month!
| Description | Name | Size | Download method |
|---|---|---|---|
| Source code with JAR files | jsf-simple.zip | 2051 KB | HTTP |
| Source code without JAR files | jsf-simple-no-jars.zip | 33 KB | HTTP |
Information about download methods
- Read also Faheem Khan's "Using JSF for XForms applications" (developerWorks, February 2005).
- Visit the JSF project page to download the JavaServer Faces APIs, custom tag library,
and related documentation.
- You can download Maven from the Apache Maven Project
page.
- Jackwind Li Guojie's "UI
development with JavaServer Faces" (developerWorks, September
2003) is an early-bird's look at the technology.
- Roland Barcia's five-part "Developing JSF Applications using WebSphere
Studio V5.1.1" (developerWorks, January 2004) tutorial is a
hands-on introduction to programming with JSF.
- David Geary's
Core JavaServer Faces
(Prentice Hall, June 2004) is the best possible book-length introduction to JavaServer Faces
technology.
- You might also want to check out the detailed
JSF tutorial from Sun Microsystems.
- You'll find articles about every aspect of Java programming in
the developerWorks Java technology
zone.
- Also see the Java technology zone tutorials page for a complete Listing of
free Java-focused tutorials from developerWorks.
Rick Hightower serves as chief technology officer for ArcMind Inc. He is coauthor of the popular book Java Tools for Extreme Programming, about applying extreme programming to J2EE development, as well as co-author of Professional Struts. Rick worked on JSF QuickStart with Warner Onstine and some of the material in this series is based on examples in that course. Contact Rick at rhightower@arc-mind.com.
Comments (Undergoing maintenance)





