Java The Many Faces of JavaServer Faces (JSF)

The Many Faces of JavaServer Faces (JSF)

No doubt the name at least is familiar: JavaServer Faces has been
talked about a lot, and much anticipated, with good reason. For years
there have been an ever-expanding choice of ways to take your web
application’s output and get it on a page (or on some other kind of
display). The Servlet API did a lot to enable the first Java web
applications – having created web applications
for Java before Servlets, I can attest to
how much it helped! The first web applications
with Servlets cranked out HTML directly –
pretty much everyone now agrees this was a bad plan, and hard to
maintain to boot. Next came toolkits such as Apache’s Element
Construction Set that generated the HTML for you. A step in the right
direction, but not far enough for most. Then came JSP: A hybrid, in
some ways, between an HTML page and a Servlet.
JSP was a significant step forward from Servlet-generated HTML – If
you use it right (and that’s a critical if), you can enforce a pretty
clean separation of view and application logic. Better still, JSP’s,
particularly once tag libraries came along, were simple enough that
non-programmers could help with the page layout process, particularly
for HTML formatting.


Other UI technologies went in different directions, though:
Apache’s Velocity, similar and to some degree a successor to the
popular WebMacro project, applied a simple but extensible template
language to generating the UI portion of an application, reading
JavaBean properties from the Servlet
context (where the application logic put it). Tea, Maverick,
WebWork2, Scope, Echo, FreeMarker, Barracuda, Cocoon – all took
different, and in some cases radically different, approaches to
getting the data from the application logic to the page.


Sometimes, as in the case of Barracuda, Cocoon, and several
others, XML was involved, and potentially XSL transformations. Many
of these frameworks also delved into the application logic side of
the equation, proving much more than a UI system. Struts is perhaps
the most widely known example, taking the JSP approach to a new level
with a powerful custom tag library, and popularizing the concept and
advantages of Model/View/Controller that Smalltalk old-timers were so
familiar with. Over time, many common elements began to emerge
between such frameworks, and it became clearer what the best
practices were for UI technology in a web environment, what worked
and what didn’t. Developers realized that web applications
that used HTML/HTTP as the basis of their UI were quite different
animals from desktop or "thick" client applications using
Swing or other such toolkits. The user, however, still wanted a rich
and responsive UI experience. There was still a wide gap in the way
the various frameworks produced the display from the data produced
from the application logic, and techniques and UI elements created
for one technology were not portable to the next. You couldn’t take a
custom JSP tag from Struts and use it in an application build with
Scope, for example. You couldn’t take UI components for Echo and
easily apply them to an application built with Cocoon. This meant
that anyone attempting to build tools to make it easier for page/UI
designers to do their job had to back one horse, or write many
different tools, neither of which was a very attractive option. As a
result, Java and J2EE lacked the rich graphical tools to help build
applications by comparison to an up-and-coming rival, .NET. While the
hard-boiled "vi" crowd didn’t see this as a problem, it did
limit the adoption of Java and of many of these different frameworks
in many organizations, where experienced developer resources were not
available for creating Luis. Either the UI
got short shrift – the results of which we can see on the web today
in the many horrifying anti-examples of usability out there – or the
development project went wildly over budget re-inventing the wheel,
because there was no standard wheel to do UI development. The other
choice was to commit to a single UI framework approach, and abandon
any possibility of portability later on.


JSF should change all that – one of it’s goals is to bring a
single common standard that tool-creators can use to build their
tools against, while still allowing many different options for
rendering the finished UI. One JSF-based design tool should be able
to be used on many different JSF implementations, and components
should be portable from one implementation to the next, so that neat
UI gizmo you built for one application
really can be re-used on another.


Sounds great – but where’s the beef? How is JSF going to
accomplish these admittedly lofty goals? Let’s look at JSF from
several different perspectives, and talk about about where the rubber
meets the road – how you’ll be able to apply JSF from a practical
perspective on your development projects, no matter what UI
technology you’re currently backing.


It’s important to realize that JSF is not tied
inextricably to JSP, even though the reference implementation
demonstrates JSF with JSP. JSF defines non-visual UI components,
which sounds like a contradiction in terms
– the idea, however, is to separate the
definition of a UI component from it’s presentation.
Much like dividing up UI and application logic, but at a finer level.
Now we’re talking about dividing up the UI into a non-visual
representation and a rendering – a translation of that
non-visual representation into an actual display. That rendering can
be done in any number of ways, as we will see.

The set of UI components supplied with JSF is extensible – indeed,
the extensions will no doubt outstrip the supplied components in
short order, by extending and combining them into more sophisticated
UI elements. Tool developers can now create UI-paint applications
that manipulate JSF components, as opposed to framework-specific
elements (such as tags or XSL elements), allowing the page designer
to say "place one of this type of component here, bind it to the
following property in the application". JSF components are
associated with a value from the underlying application logic, and
may also be associated with one or more "events" that are
triggered when the component is manipulated by the user. These events
(the equivalent of a "submit"
operation in Servlet terms) trigger a chain
of processing called the JSF life cycle. In
brief, this life cycle applies the request
parameters to the "tree" of non-visual components (creating
one, if necessary), performs necessary validations and type
conversions, then passes the values to the application logic and
triggers the method associated with the event. This life
cycle
can be abbreviated by, for example, validation errors,
causing the page to be re-displayed with all of the values intact (in
addition, likely, to an error message telling the user why the
validation failed). This avoids calling the application logic
entirely, at least for simple validations. Assuming the validations
and conversions were successful, the application did get called, the
"tree" of components associated with this request is cached
for later use, and the application goes on to the next logical step.
Some events will return to the same logical page, so the ability to
cache the page of components and their associated values allows the
page to be modified and then re-displayed: for example, filling in a
customer code might result in the customer name being displayed
alongside it, while the remainder of the page remains the same. This
kind of "state saving" helps build web-based applications
that provide a more "traditional" UI experience for the
user, while not imposing an additional burden on the application
logic.


JSF, therefore, has very little impact on the application logic of
your existing programs, assuming they were written in a fashion that
employs model/view/controller separation.
This allows JSF to be phased-in, as opposed to making it a "rip
and replace" technology.


While some work is required to integrate the JSF life
cycle
into existing frameworks, it’s API is factory and
interface based, allowing just such integration. An effort is already
underway to allow Struts to take advantage of JSF, as they have quite
similar approaches in many ways even now. JSF’s reference
implementation includes a powerful tag
library, where JSP pages can easily be created to pick elements from
the UIView (the response "tree" of non-visual components)
for display in specific locations on the finished page. Like any
other JSP, the "decorative" portion of the page can be
interlaced with these components as necessary to create an
user-friendly layout.


What if you’re not currently using Struts or even JSP, though, are
you out in the cold as far as JSF is concerned? Not at all.


While it has been discussed a few times how it’s quite possible to
generate XML from JSP pages, then transform that XML via XSL, this
many-layered approach has many hardened veterans in the web
application business shaking their heads
over the complexity. We’ll try a more direct approach.


Let’s look at an example of one of my favorite UI frameworks:
Cocoon
(or the UI-handling portion of Cocoon, in any case, as Cocoon of
course can do far more than render a UI). Cocoon does not expose a
Servlet request and response directly to
the application logic (or the controller Servlet)
for manipulation. Instead, it uses the powerful approach of
pipelines, where a pipeline begins (usually) with a generator, passes through one or more transformers, and then into a
serializer. Another way to initiate a pipeline is through an action,
which is the common way in Cocoon to invoke server-side application
logic. This logic then deposits an XML fragment in the session
context, which is in turn extracted by a special Generator, and on to
the normal pipeline flow.


Let’s see (at a high level) how JSF fits into this model:
Pipelines deal (with few exceptions) with XML, so we need a way to
Map the UIView produced by JSF into an XML document. This is the
"RenderKit" portion of JSF – the layer where the non-visual
component begins it’s conversion into a concrete representation on
the screen. Fortunately, the structured and hierarchical
form of a UIView can easily be serialized into XML. With this
approach, the UI does not "pick" elements from the UIView
to be laid out on the page (or other
display device), the entire UIView "tree" is available – so
how do we format it into a user-friendly view? The most common
mechanism for this in Cocoon is XSL transformation: our XML
representation of the whole UIView can be passed through a
stylesheet, taking advantage of the unique and powerful structure of
XSL, to produce a proper rendering of the XML as needed for different
displays. The most common output might be HTML, but nothing prevents
us from applying a stylesheet to produce PDF, SVG, RTF, XSL or any
other format we might care to imagine. Our stylesheets can even be
hierarchical: we can have one "root" stylesheet that knows
how to render all of the common elements, such as UISelectOne’s,
UIText, and so forth, then "import" that stylesheet and
override selectively. On this page we want all UIText fields to have
a green background? No problem, just override that one template. We
can also drive *which* elements we render, doing the same kind of
selective process as we might do in a JSP page, by overriding the
top-level UIView template, then calling render templates one at a
time for explicitly named elements. As you can see, JSF’s power can
easily be linked with a UI mechanism that is not JSP-oriented, while
at the same time preserving the power of it’s standardization.


While we’ve only examined one possible integration of JSF into an
existing UI-rendering technology, there are of course many other
possibilities. Each UI framework so far has had to come up with an
answer to the issues addressed by JSF: how to map application logic
to a non-visual representation, how to lay out components on a page,
how to render a given component in the appropriate display language,
and so forth. Ideally, each of the many different UI approaches can
take advantage of the common backbone of JSF, allowing the goal of
portability to be achieved not only between
systems, but also between entire frameworks, while maintaining the unique
advantages that set them apart from other UI technologies and
approaches. This will require a willingness to set aside any "not
invented here" syndrome in order to reap the advantages of
standardization, thus enabling the entire Java industry to benefit,
as well as the users of any one framework.

About the Author

Michael Nash is the president of JGlobal Limited, a software development, consulting, training and support company specializing in open source Java technologies. He is also a core developer of the Keel meta-framework, the author of two books and a number of articles and papers about next-generation web-application development with Java, and a member of the JSR-127 (JavaServer Faces) Expert Group. He can be reached at [email protected]

Latest Posts

Related Stories