Mixing JSTL and JSF in Web Applications

avaServer Pages Standard Tag Library (JSTL) is a library of standard tags that you can place on JavaServer Pages (JSP). The tags encapsulate functionality commonly used in Web applications. JSTL supports common structural tasks such as iteration, conditional processing, parsing, XSL transformation of XML documents, internationalization and locale-sensitive formatting, and database access. JSTL has become a popular standardized tag library in the market today.

In contrast, JavaServer Faces (JSF) is the “new kid on the block” addition to the Java suite of technologies available for Web development. It is the “Swing for server-side applications.” It brings the popular desktop event-handling metaphor into the world of server-side Java applications. The JSF specification allows for custom rendering of common user interface components intended for different presentation protocols and devices, while also providing extensibility so developers and vendors can create custom user interface widgets. The standardization of this specification has already triggered the development of numerous third-party tools to improve and simplify application development with JSF. Among the early adopters to develop Integrated Development Environment (IDE) support are IBM’s WebSphere Studio (version 5.1.1), Exadel JSF Studio 1.0, and Sun’s Java Studio Creator. At this writing, Java Studio Creator (formerly code-named Project Rave) is available only in pre-release mode, while the other two products are already commercially available.

If you’re not familiar with the evolution of Java as a Web development tool, the coexistence of these two strategies (JSTL and JSF) might seem strange: Why have two separate ways to create Web interfaces? They may not both survive forever, but right now, both are warranted. Current JSTL users get a straightforward migration path, and having both provides choice for developers, who can benefit from using the best features of each.

This article outlines an effective coexistence strategy between these two technologies. It assumes that you already have some basic understanding of JSF and JSTL. There are many resources on the Web that discuss these two technologies independently; but, there is little available information about creating a marriage between the two.

JSF Hides Complexity
JSF-enabled IDE’s simplify development of large Web applications with several data entry screens (Web pages). Painting a JSF screen using the IDE’s drag and drop features eliminates the need to manually code JSP page layouts. Similarly, hooking screen events to server-side Java components through the IDE’s user interface reduces the coding effort required to connect the screens to business logic components. Using JSF, you need to develop applications once that are intended to render through multiple user interface protocols to multiple client types. Subsequently, you need to develop only the necessary custom renderers for the different delivery mechanisms as needed. JSF also brings resemblances of .NET into the Java world. This similarity of concept is an advantage for developers who would like to switch between the two technologies (trust me, there are some who do this).

Programming using JSF with JSF-supported IDEs can hide the complexity and inner workings of JSF from developers. This makes it very important to pay close attention to the performance implications of application design. You must be very careful to avoid overusing event handling on any Web screen. The more JSF events on a screen, the more round trips are required from the client to the server, and the slower the application becomes. As the case is with any new technology, debugging and troubleshooting support for JSF is minimal at this point. You should keep that in mind before diving into the sea of JSF. The built-in data validation support in JSF is not too elaborate, but what’s provided today is a good start, can be extended, and will likely evolve as user support grows. If your application doesn’t have data entry forms and uses simple screen-to-screen navigation for static display of dynamic content, JSF will really be overkill, but is appropriate if the development team is comfortable with JSF and if you’re planning on migrating the application to include form interactivity at some point.

Setting Up the Environment
To develop Web applications using both JSTL and JSF, you need a servlet container, such as Jakarta Tomcat, JSTL tag libraries, and an implementation of JSF. After installing the servlet container, refer to the JSF installation document for details on installing JSTL and JSF. 

Sample Application Design
In the remainder of this article, I’ll walk you through the process to design a mortgage calculator that can perform multiple what-if scenarios using different input values for a mortgage loan. As the user creates the scenarios, the application maintains and displays a list, so users can compare the results easily. Users can then select the scenario they like. This simple Web application will consist of three screens, each of which uses JSF and JSTL in varying degrees.

The directory structure for this application’s code base looks like Figure 1.

 
Figure 1. Directory Structure: The figure shows where in the directory structure you should place the various files in your application.

To deploy the application to Tomcat, compile all source files into WEB-INF/classes and archive the entire Web directory and its subdirectories into a WAR file. Copy the WAR file into the appropriate Tomcat hot deployment directory.

The operations required to create this application are straightforward

  • Create a screen where users can input and submit the values to create a what-if scenario (see Figure 2).
  • Make the calculations on the server, and display results (see Figure 3).
  • Let users accept one of the scenarios, at which point the application shows the final results (see Figure 4).
 
Figure 2: Main Data Entry Screen: The figure shows the main data entry screen for the sample application.

You’ll find the JSP code to display this UI in the file mortgageCalculator.jsp in the sample application download .

This code for this screen uses JSF tags to define the form fields and paint the form. All the tags with a prefix of “h” are JSF tags that represent HTML form elements. All tags with a prefix of “f” represent the core JSF tags. This screen also uses JSF tags for localization. The f:loadBundle tag loads the resource bundle file, Resources.properties, from the mc.bundles package, and then references it using the variable uiBundle in the remainder of the JSP file. The h:panel_grid tag is the JSF tag to define a table. The notation #{uiBundle.principal} causes the page to retrieve a property named principal from the resource bundle. Here’s a brief look at how JSF codes an input field tag:

             

The notation #{MortgageLoanAccount.currentScenario.principal} retrieves the attribute named principal from the currentScenario object contained in a managed bean object called MortgageLoanAccount, on the server. The validator attribute identifies the validator method for this field. Similarly, the line validator=”#{MortgageLoanAccount.currentScenario.validate}” identifies the validate method of the currentScenario object contained in the MortgageLoanAccount bean as the method to use to validate the data entered into the principal field.

The following line defines a command button on the form.

   

The caption displayed on this button comes from a property named anotherButton in the resource bundle. Clicking the button invokes the MortgageLoanAccount bean’s createNewScenario method.

The faces-config.xml file required for every JSF application contains the definition for MortgageLoanAccount. At the bottom of that file is this section:

                        The bean that backs up the            mortgageCalculator Web app              MortgageLoanAccount                           mc.MortgageLoanAccount       session     

The preceding code fragment defines a session object named MortgageLoanAccount of type mc.MortgageLoanAccount (see the file MortgageLoanAccount.java). This is a class that saves the different loan scenarios represented by the class named MortgageLoanScenario.

Defining the Navigation
The faces-config.xml file also defines the navigation rules for the workflow of this application. You do not need to change this file in any way to mix both JSF and JSTL in your application. The following section of this file directs the mortgageCalculator.jsp file to the results.jsp file if the user clicks the Show All Results button.

   /mortgageCalculator.jsp                     showAll      /results.jsp   

The first screen (mortgageCalculator.jsp) uses an h:output_text JSF tag to represent a prompt for a field as follows:

   

If you prefer, you could accomplish the same using JSTL. The equivalent JSTL code to load the resource bundle is:

      <%@ taglib uri="http://java.sun.com/jstl/fmt"       prefix="fmt" %>       

The code loads Resources.properties from the mc.bundles package and sets the variable uiBundleUsingJstl to reference this resource bundle in the rest of the JSP page. If you use this JSTL resource bundle to display the principal prompt, you should use the following code instead of the output_text tag mentioned above.

      

You can easily extend this idea to other field prompts as well. As you can see, both JSF and JSTL provide ways to load and use a resource bundle on a JSP page. Using JSTL over JSF for this purpose, however, really doesn’t provide any advantages. It is best to use JSF for everything it can do unless there is a compelling reason to do otherwise. When you use an IDE to place labels/prompts on a JSF-based Web form, this sort of interleaved JSTL could cause problems when modifying or enhancing the form using the IDE.

Displaying the Results
Figure 3 shows the calculated results returned from the server.

 
Figure 3: The Calculation Result Screen: The figure shows the screen used to display the results of the calculations.

You’ll find the full JSP code to display this UI in the results.jsp file. The first interesting code section in this JSP is:

   <%@ taglib uri="http://java.sun.com/jsf/html"       prefix="h" %>      <%@ taglib uri="http://java.sun.com/jsf/core"          prefix="f" %>            <%@ taglib uri="http://java.sun.com/jstl/core"          prefix="c" %>

The preceding code snippet loads two JSF tag libraries referenced in the JSP using prefixes of ‘h’ and ‘f’. It also loads the JSTL tag library, used with a prefix of ‘c’.

The second interesting code section is the JSTL c:forEach tag:

            

In this code, you can see the use of the JSTL c:forEach tag to iterate through a collection of scenarios. It creates a new row for each scenario and displays the attributes of the scenario object in a separate cell using the JSTL c:out tag. A key point here is that the JSTL tag attribute code items=”${sessionScope.MortgageLoanAccount.allScenarios}” references the managed bean named MortgageLoanAccount, defined by JSF with session scope in the faces-config.xml file as explained earlier. Because the MortgageLoanAccount bean is a session-level object, it’s not limited to JSF?anybody can reference it. The c:forEach tags uses JSTL’s syntax to access the bean. More specifically, it invokes the allScenarios method of that object, which returns a collection of MortgageLoanScenario objects. The loop references each object in the collection using the variable name scenario on this JSP page.

The third interesting code section in results.jsp is:

                                                                      

This preceding code fragment shows all the JSF code required to create the Calculation Result screen. You can see that it’s clearly separated from the JSTL code, which is preferable because:

  • It’s easier to read and understand.
  • It’s easier to debug.
  • It will be easier to maintain using JSF supported IDE tools.

JSF does not really provide a simple solution for iteration like JSTL does. This is one area where the coexistence of JSTL within a JSF application will provide a significant advantage.

You can also contain JSF sections within a JSTL tag. One reason to do this would be to conditionally display a JSF FormA or FormB based on certain criteria within a JSP page, a scenario that truly takes advantage of the strength of both technologies. One can argue that it would be cleaner to have an all-JSF solution to do the same thing; however that requires you to define two different JSP pages?one for each form?and then to navigate conditionally to one page or the other based on navigation rules defined in the faces-config.xml file. The final answer on which technology to use really depends on your situation. If you’re developing a new application from the ground up, an all-JSF solution will definitely be cleaner. If you’re refactoring an existing JSTL application, the JSTL-JSF mix will be faster.

Completing the Application
When the user accepts a loan scenario, the application displays the screen shown in Figure 4.

 
Figure 4: Final Results Screen: Here’s a sample of the text shown on the final results screen, after a user accepts the loan scenario.

The source code for the screen shown is in thankYou.jsp. This screen uses JSTL only. It does not provide for any user interaction. It only displays results. This is perfect for JSTL. There’s no advantage gained by using JSF for such static screens unless you’re creating a brand new application. JSTL gets access to the JSF managed bean by treating it as a session object. For example, the following code accesses the JSF defined MortgageLoanAccount managed bean as a session object and invokes the getter method to retrieve the principal attribute on its acceptedScenario attribute.

The code to accomplish the same thing in JSF is:

   

You’ll find the complete source code in the downloadable source code in the file mortgageCalculator.zip.

JSTL’s SQL tags were intended to be used for prototyping Web applications, and aren’t really appropriate for building modular MVC applications. Hence, they were not included in this article. They can, if necessary, be used to display any content other than form field values on Web pages of a JSF application.

JSTL’s XML tags can be used to transform XML data using XSL. To maintain a clean coexistence of JSF and JSTL, you should use these tags to render content other than a JSF form. For example, visually rendering printable documents originating from an XML source is a perfect way to use the tags. Any other direct parsing of XML data by a JSTL tag violates MVC architecture best practices.

Interweaving JSTL and JSF tags will produce a fiasco, and I don’t recommend that. But as long as you maintain some separation between them, you will be okay. What you’ve seen in this article are some possibilities to get you thinking along the lines of how to use both and still maintain that separation. This article is not comprehensive by any means. It is a preliminary collection of ideas prior to the advent of mature JSF tools?a maturation which may throw a lot of twists into this equation.

JSF is still new; few developers have used it to create business applications yet. In the near future, as tool support for this technology emerges, JSF will attract a lot more attention. After the dust settles, performance issues related to JSF will surface. JSF’s limitations with respect to validation and peaceful coexistence with other current Java technologies will draw more attention. It will be interesting to see which technologies will blend together into a meaningful end result. JSF is here to stay, mainly because of its standardization, while JSTL’s simplicity is its strongest selling point. There’s very little overlap between JSF and JSTL, so it’s quite possible for the two technologies to coexist, as explained in this article. The strategies outlined here provide clean options for application development using the best of both worlds.

Share the Post:
Share on facebook
Share on twitter
Share on linkedin

More From DevX