Browse DevX
Sign up for e-mail newsletters from DevX


Mixing JSTL and JSF in Web Applications : Page 3

Even though the JavaServer Pages Standard Tag Library (JSTL) and the newer JavaServer Faces (JSF) technology are very different, they're not totally incompatible. Find out how and when you might want to consider mixing the two to achieve a blend that's smoother than either one alone.




Building the Right Environment to Support AI, Machine Learning and Deep Learning

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.

<from-view-id>/mortgageCalculator.jsp</from-view-id> <navigation-case> <description> </description> <from-outcome>showAll</from-outcome> <to-view-id>/results.jsp</to-view-id> </navigation-case>

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

<h:output_text value="#{uiBundle.principal}" />

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

<!-- Define the JSTL tag lib used for localization --> <%@ taglib uri="http://java.sun.com/jstl/fmt" prefix="fmt" %> <!-- Load the resource bundle --> <fmt:setBundle basename="mc.bundles.Resources" var="uiBundleUsingJstl" scope="session"/>

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.

<!-- Display the prompt --> <fmt:message key="principal" bundle="${uiBundleUsingJstl}"/>

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" %> <!-- JSTL TagLibs --> <%@ 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:

<table> <c:forEach items="${sessionScope.MortgageLoanAccount.allScenarios}" var="scenario"> <tr> <td><c:out value="${scenario.id}"/></td> <td><c:out value="${scenario.principal}"/></td> <td><c:out value="${scenario.interestRate}"/></td> <td><c:out value="${scenario.term}"/></td> <td><c:out value="${scenario.monthlyPayment}"/></td> </tr> </c:forEach> </table>

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:

<f:view> <h:form id="resultsForm" > <h:panel_grid columns="3"> <h:output_text value="#{uiBundle.scenarioToAccept}" /> <h:input_text id="acceptedScenarioId" value="#{MortgageLoanAccount.acceptedScenarioId}" /> <h:command_button id="acceptScenario" action="acceptScenario" value="#{uiBundle.acceptButton}" /> <h:command_button id="startOver" action="startOver" value="#{uiBundle.startOver}" /> </h:panel_grid> </h:form> </f:view>

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.

Comment and Contribute






(Maximum characters: 1200). You have 1200 characters left.



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