c:choose c:when c:otherwise

The JSTL c:if tag has an issue: it misses the "else" part. We have no way of defining alternative branches with it.

As counterpart of the well known if-else / switch-case-default construct, in JSTL we have the c:choose, c:when, c:otherwise tags.

As an example, consider the requisite of printing a different header on a JSP page accordingly with the value stored in a session attribute. If none of the expected values is found, a default header should be generated.

Here an raw first version, implemented using a script in our JSP page, assuming a String has been previously put in the session attribute userPref:
<h2>
<%
    session.setAttribute("userPref", "safety");
    String pref = (String) session.getAttribute("userPref");

    if (pref.equals("performance")) {
        out.println("Now you can stop even if you <em>do</em> drive insanely fast.");
    } else if (pref.equals("safety")) {
        out.println("Our brakes won't lock up, no matter how bad a driver you are.");
    } else if (pref.equals("maintenance")) {
        out.println("Lost your tech job? No problem-" +
            "-you won't have to service these brakes for at least three years.");
    } else {
        // userPref doesn't match those, so print the default headline
        out.println("Our brakes are the best.");
    }
%>
</h2>

<h3>The Brakes</h3>
Our advanced anti-lock brake system (ABS) is engineered to give you the ability
to steer even as you're stopping. We have the best speed sensors of any car this size.
This code would miserably fail when no userPref attribute is available in the session, because the String pref would be set to null, and the subsequent calls to equals() would try to dereference that null. But this is not an issue here. It is more interesting noticing how the different cases are managed accordingly to the attribute value, and how the default case is chosen when no previous option is selected.

Now we rewrite the same code using JSTL tags:
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

<!-- ... -->

<h2>
<c:choose>
    <c:when test="${userPref == 'performance'}">
        Now you can stop even if you <em>do</em> drive insanely fast.
    </c:when>
    <c:when test="${userPref == 'safety'}">
        Our brakes will never lock up, no matter how bad a driver you are.
    </c:when>
    <c:when test="${userPref == 'maintenance'}">
        Lost your tech job? No problem--you won't have to service these brakes
        for at least three years.
    </c:when>
    <c:otherwise>
        Our brakes are the best.
    </c:otherwise>
</c:choose>
</h2>

<!-- ... -->
This code is more readable and also more robust, we have not to worry about null, userPref is automatically converted in a empty string if such an object is not available.

A Java developer could be surprised by the usage of single quotes as string delimiter inside a tag attribute, but remember that there we are not dealing with Java but with JSTL.

I originally wrote this post at the end of 2010 for my more generic blog This Thread, while I was reading Head First Servlet and JSP, chapter nine.

No comments:

Post a Comment