http://www.developer.com/

Back to article

Is Java Server Faces a Bona Fide Panacea for the Web UI?


May 11, 2006

You will learn about JSF technology (JSR 252), its structure, configuration, pros and, cons. I will talk about the history that led to JSF. I will also discuss industry support both on the vendor and the IDE sides. As of this writing, the JSF is up to version 1.1_01, but the spec for 1.2 is compete and reference implementation should be available shortly. Also, understand that this technology is rather vast and I will cover only the general aspects of it in this article.

The Events Leading to the JSF

In the beginning, there were Plain Old Java Objects (POJOs) and Java Applets. Business programs were supposed to run in the browser. However, IT managers soon realized that most did not have broadband connections and downloading Java Virtual Machine and Applets was time consuming. Around that period (before Just-In-Time [JIT] compiler technologies were introduced), managers also noticed that applications and applets run somehow slower then their cousins written in C/C++, VB, or other natively compiled languages. In addition, users noticed that Applets had restrictions and could not do many things that applications could.

Sun Microsystems stepped up with the Servlet technology and Java moved from running on the client's browsers to running on the servers. Sun also introduced the JIT compilation process, optimized their JVM, and Java applications started to run faster.

And all was good for a while.

But soon, IT managers realized that Servlets disgorge HTML to the clients and HTML pages need to look presentable to provide a better user experience to drive up the revenues. But, programmers who were willing to write all HTML by hand, inside Java code, literally as output statements that would perform dynamic functions and look appealing were very hard to find. Therefore, again Sun stepped up with the Java Server Pages (JSP) technology.

Designers could create HTML pages that look great and Java programmers could take them, spruce them up with tiny Java tags and snippets, and the Java server container would parse and convert them into the HTML to be disgorged to the clients.

And all was good for a while.

But soon, IT managers realized that large applications started to have a lot or Java code mixed in with the HTML, JavaScript, VBScript and anything else that can run on the browser. Developers did not have to produce the appealing HTML, but needed to understand and maintain it along with the large Java sections imbedded in it. The support and maintenance of the Web apps started in some cases to cause ROI decreases.

The "perpetual" solution, or at least part of it, is supposed to be the Java Server Faces (JSF) technology; A sort of RAD (rapid application development) concept from the Visual Basic era. However, I will leave it up to the readers to make the conclusion.

Rapid Application Development (RAD)

The Java Standard Tag Library (JSTL) introduced a couple of years back created a standard way to replace Java snippets with tags. The tag can do almost any business logic and can be re-used throughout many applications. JSTL tags did not address any visual aspects of the applications, but helped to eliminate some of the maintenance problems associated with editing business logic on the pages.

Rapid Application Development (RAD) is sort of a "holy grail" of the GUI Web applications. When working with Java Swing, Visual Basic, or PowerBuilder programs, developers can drag-and-drop GUI components, such as buttons or text fields, and create full-featured interactive applications. With the HTML as the end result of some server operation, the presentation is not linked to the Java backend and RAD is not truly possible.

The HTML editor can be used to create forms, but it cannot add events to buttons or link controls to the backing beans; therefore, a lot of work still needs to be done manually. To accomplish RAD with tags, a new technology needed to be created.

Realizing this need, Sun developed the JSF specification. The JSF technology introduced tags for all HTML elements—such as buttons, tables, and checkboxes—and corresponding Java Objects to hold the state or model of the view. An IDE supporting JSF can allow developers to drag-and-drop tags and create the forms so instead of writing HTML:

<input type="text" id="inputText"/>

One would write the JSF tag:

<h:inputText id="inputText"/>

JSF added the ability to attach converters, validation, and even actions and events to the corresponding Java objects on the server—all expressed as tags, potentially bringing a true RAD feel and Swing development style to Web development.

However, to create fancy professional-looking pages, you need to use a very sophisticated layout; and to design, an HTML editor (for instance, Dreamweaver is one of the best) that will understand all the latest standards in JavaScript, CSS, and so forth, and correctly show the preview in the same split pane. There are no HTML editors on the market that can understand how to preview JSF tags (or any UI Java tags). Besides the fact that Web developers now need to learn an entirely new "HTML," the page design task is moved to the Java IDE. And, very few IDEs can compare their HTML editing abilities with even the most primitive HTML editors.

For example, Borland JBuilder supports JSF tags, but cannot auto preview them, so the Java developers (who now became HTML designers) need to deploy the app on the server and recompile/refresh JSPs page every time they make a visual change. Oracle JDeveloper 10 and Exadel Studio pro do have design/layout and preview capability inside of their IDEs and on-the-fly editing of the dragged-and-dropped JSF components, but their HTML editors are not as mature as Dreamweaver.

Almost all of IDEs that support JSF also offer visual editors for the navigation flow management that eliminates the need to tinker with the XML by hand (see the next section).

JSF as a MVC Framework

The proliferation of Web-based applications, concurrent with the migration of Java from the client to the server and the evolution of the Servlets, JSP, and other Web-based technologies, created numerous development frameworks along the way. I have covered some of the most popular ones in my previous articles.

By design, JSF constitutes a much broader technology then just another MVC framework. One of the aspects of the JSF is that it controls Web application flow. The page navigation is mapped out in the configuration XML file and the main controller Servlet coordinates the flow (among other things). JSF can be considered a full MVC framework because the presentation layer (most commonly a JSP page) is separated from the Java beans or "managed beans" as the JSF identifies them. Depending on the render toolkit used, the view shown to the client can be HTML, WML, SGML, and so on.

Mostly, JSF is marketed as a component framework for the presentation layer, but its MVC characteristics overlap with Struts, Spring, and other popular frameworks. Even though they can co-exist in the same application, architects can design enterprise-level Web sites with only JSF. In fact, JSF navigation rules are very easy to describe, and depending on the tool used, most of the flow and underlining XML configuration can be created visually in very little time. Even describing the managed beans, their properties, validators, and converters in the XML config file is a trivial task with the right tool (such as the free James Holmes' Faces Console or Exadel Studio pro).

Here is a screen shot of the visual navigation rules layout in Oracle JDeveloper 10g:

Here is a similar shot of the visual navigation rule layout in Borland JBuilder 2006:

Industry Support

JSF is a specification; therefore, any vendor can write their own implementation and compete on performance and features. Sun has the reference implementation (RI) and Apache has the MyFaces version.

Currently, JSF is well supported by the industry and companies such as Oracle, IBM, and the Apache Software Foundation are actively developing for it. A lot of Java IDEs on the market directly recognize core JSF tags. Here are the screen shots from JBuilder and JDeveloper, but MyEclipse, Exadel Studio pro, IBM WSAD, BEA Workshop, Sun Studio Creator, and a lot of other tools support this technology as well.

JSF components selectors: JDeveloper left, JBuilder right

Using the JSF

For the purposes of this article, I have developed a very simple application that nevertheless demonstrates key concepts of the JSF. It used tags, managed bean, navigation flow, bindings, and fires an event that changes the model state.

I used Borland JBuilder and WebLogic server to test, but any IDE and any server can be used. On the left is the final project structure.

The project retrieves the weather info based on the user's location. There are only two pages, the input (weather.jsp) and exit.jsp. The user selects the location from the select box and then clicks the button; that submits the form (see screen shots at the end).

To set up the framework, I imported the JSF (and JSTL) libraries into the project, (most IDEs do this automatically).

Next, I added the Faces controller servlet to the standard J2EE web.xml descriptor file and indicated that any request to an extension *.f will be handled by this servlet. Actually, any extension can be used. The JSF will correctly call the JSP, and if I wanted to, I could have called the extension .asp to hide the server technology I use.

<web-app>
   <display-name>JSFWebModule</display-name>
   <servlet>
      <servlet-name>Faces Servlet</servlet-name>
      <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
      <load-on-startup>1</load-on-startup>
   </servlet>
   <servlet-mapping>
      <servlet-name>Faces Servlet</servlet-name>
      <url-pattern>*.f</url-pattern>
   </servlet-mapping>
   <welcome-file-list>
      <welcome-file>weather.f</welcome-file>
   </welcome-file-list>
</web-app>

I created the managed bean (com.jsf.src.BackingBean) to hold the weather information, and added two empty JSP files. (Some IDEs will create the JSPs, bean classes, and their properties from the faces-config wizard) Next, I visually configured the faces-config.xml file to set up the flow and reference to the backing bean.

Here is the screen shot of JBuilder's Faces Config editor:

The end resulting XML looks like this:

<faces-config>

   <navigation-rule>
      <description>Navigation for the weather app.</description>
      <from-view-id>/weather.jsp</from-view-id>
      <navigation-case>
         <from-outcome>success</from-outcome>
         <to-view-id>/exit.jsp</to-view-id>
      </navigation-case>
   </navigation-rule>

   <managed-bean>
      <description>backing weather bean.</description>
      <managed-bean-name>weatherBean</managed-bean-name>
      <managed-bean-class>com.jsf.src.BackingBean
      </managed-bean-class>
      <managed-bean-scope>session</managed-bean-scope>
   </managed-bean>

</faces-config>
Note: I set a navigation rule on "success" to go to exit.jsp. Also, I set the scope of the bean to "session" and its name to be "weatherBean". The scope for JSF managed beans could be application, session, and request.

Then, it was time to put JSF tags into the JSPs.

First, I included the tag libraries "f" and "h" and then used the outputLabel, outputText, selectOneListbox, selectItem, panelGrid, and commandButton tags to render HTML text, selection list box, table, and buttons. Note that all of the JSF tags need to be in enclosed into the <f:view> tag. I also could have included a resource bundle (property file) with all the text messages for the page and set them to be used instead of the hardcoded ones. If the user would request the page with a different locale, the JSF would automatically internationalize (change) all messages, assuming I had them in different languages.

The form tag encases the HTML form, the label is linked to the selectOneListbox by its ID, and selectOneListbox values references the bean's String zipCode properly.

When the selects' box value is submitted to the server, JSF can optionally validate or convert it and then assign it to the bean's field automatically. Note that the value is actually synchronized between the view and the model because I initially set zipCode property in the bean to "90210"; when the page is shown for the first time, the location is already pre-selected to "LA" (see screen shots at the end).

The "message" tag is for validation errors, but because I'm not using any validation tags, nothing will be checked. Automatic error notification is another great feature of JSF.

The panelGrid tag represents an HTML table and it is bound to the UI object HtmlPanelGrid that is the weatherGrid field of the bean. Binding will sync not only the component's value, but also its representation, but more on this later.

I also have two buttons that are represented by the commandButton tags: one with an actionListener, and another with the action and immediate="true" attribute.

The actionListener will fire an event when the form is submitted; this triggers the registered method of the bean. This is similar to the Swing action event/listener technology except the listener is the bean itself and JSF registered it for me. If the form is submitted from the other button, JSF will not fire an event, but directly call the bounded method. Also, because of the immediate attribute, no validation or conversions will be done or events will be fired. The immediate attribute tells JSF to just execute the assigned method and ignore everything else. As its "action" property, the second button can simply have a string "success", that tells JSF to do the navigation case from the faces-config.xml file, but instead I'm calling the "exit" method of the bean that returns "success" to show that some more logic can be done on the exit.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<%@taglib uri="http://java.sun.com/jsf/core" prefix="f" %>
<%@taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
<f:view>
   <html>
   <head>
      <title>Weather JSF Application</title>
   </head>
   <body>
   <h:form id="weatherForm">
      <h:outputText value="Weather JSF application!"/>
      <br/>
      <p>
         <h:outputLabel for="zipCode">
            <h:outputText id="zipLabel"
                          value="Select your location:"/>
         </h:outputLabel>
      <br/>
      <h:message id="errors" for="zipCode" style="color: red"/>
      <br/>
      <h:selectOneListbox id="zipCode"
                          size="3"
                          value="#{weatherBean.zipCode}">
         <f:selectItem itemValue="10041" itemLabel="NY"/>
         <f:selectItem itemValue="90210" itemLabel="LA"/>
      </h:selectOneListbox>
      </p>
      <p>
         <h:panelGrid id="weatherInfoPanel"
                      binding="#{weatherBean.weatherGrid}"
                      columns="1"
                      border="2"
                      cellspacing="2"/>
      </p>
      <h:commandButton id="getWeatherCommand"
                       type="submit"
                       value="Get Weather"
                       actionListener="#{weatherBean.addControls}"/>
      <h:commandButton id="exitCommand"
                       type="submit"
                       value="Exit"
                       action="#{weatherBean.exit}"immediate="true"/>
   </body>
   </html>
</f:view>

The exit JSP is not only simpler then the weather.jsp, it also uses the model and even explicitly indicates the scope to look for the bean in. If the scope is not indicated, the JSF will look in all scopes.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<%@taglib uri="http://java.sun.com/jsf/core" prefix="f"%>
<%@taglib uri="http://java.sun.com/jsf/html" prefix="h"%>
<f:view>
   <html>
   <head>
      <title>Exit page</title>
   </head>
   <body>
   <h:form id="exitForm">
      <p>
         <h:outputText id="exit"
                       value="Thanks for using Weather JSF App"/>
         <br>
         <h:outputText id="mgs"
                       value="You have checked weather in: "/>
         <h:outputText id="location"
                       value="#{sessionScope.weatherBean.zipCode}"/>
      </p>
   </h:form>
   </body>
   </html>
</f:view>

Look at the bean's listener method (bind to the grid tag) and see what will happen when the first button is pressed.

Here is the source for the action Listener method.

public void addControls(ActionEvent actionEvent) {
   UIViewRoot view = FacesContext.getCurrentInstance().getViewRoot();
   Application application =
      FacesContext.getCurrentInstance().getApplication();
   List children = weatherGrid.getChildren();
   children.clear();

   HtmlOutputText output =
      (HtmlOutputText)
      application.createComponent(HtmlOutputText.COMPONENT_TYPE);

   if (zipCode.equals("10041")) {
      output.setValue(" Sunny in NY ");
   }
   else if (zipCode.equals("90210")) {
      output.setValue(" Raining in LA ");
   }

   children.add(output);
}

After the form is submitted, JSF will form a presentation UI tree of objects on the server, validate and convert values, sync bean fields (such as zipCode), and then fire any pending events. An interesting point here is, assuming that and an app has 100 components on one page and 1000 users hit it at one time, does the server generate and keep 100000 objects in memory? What if you have more users/components?

When the method addControls is called, the zipCode is already set to the right value. Because I directly bound it in the tag, I can get access to it and change it in on the server. In this case, I clear the table and then set one data cell with hardcoded value. Of course, in the real application the method can get the value from any data source.

After the JSF framework changes the state of the bean, it traverses through the UI tree, calling the render toolkit to generate HTML and output it to the user.

Here are the screen shots of a running application. Download the WAR file for the complete source of the project here.

Conclusion

In this article, I have covered a lot of ground talking about Java Server Faces. This is a relatively new technology for the RAD development of Java Web applications. JSF also dubs as a MVC framework and allows you to develop an enterprise-scale Web applications with the navigation flow control, drag-and-drop of pre-build components (tags) for UI widgets, validators, converters, and internalization resource bundles, as well as creation of new custom UI widgets, validators, and converters. The specification is very robust with event model on the server side, render toolkits for different client outputs, and fast adoption among the industry leaders and IDE vendors. I will leave it up to the readers to decide the usefulness of this technology, as well as which tool to use to help with the JSF RAD Web development. I would appreciate your comments on this article, so please feel free to drop me a note to the address provided in the "About the Author" section.

References

About the Author

Vlad Kofman is a Senior System Architect. He has implemented enterprise-scale projects for the major Wall Street firms, defense contracts, and the U.S. government. His main interests are object-oriented programming methodologies and design patterns.

Sitemap | Contact Us

Thanks for your registration, follow us on our social networks to keep up-to-date