Search code examples
javajspjstlelscriptlet

JSTL fmt:formatNumber


How do I format a variable with <fmt:formatNumber> ? I'm learning JSTL and converting from old Struts tags. This doesn't work. It can't read the distance variable!

    <%double distance=geo.getDistance(geo.getLatitude(), geo.getLongitude(), lat, lng);%>
    <c:set var="distanceEL" value="${distance}"/>
    ${distance}, 
    <fmt:formatNumber pattern="0.0" value="${distance}"/>, 
    <fmt:formatNumber pattern="0.0" value="${distanceEL}"/>, 
    <fmt:formatNumber pattern="0.0" value="1234.567"/>,
    <%= new java.text.DecimalFormat("0.0").format(distance) %>

It displays as

, , , 1234.6, 19.3

I'm using JSTL 1.2. So far I'm not impressed.


Solution

  • You're mixing oldschool scriptlets with EL and expecting that they share the same variable scope. This is not true. EL (those ${} things) searches in respectively the page, request, session and application scopes for the first non-null attribute matching the given name and returns it. It does not access the scriptlet local scope in any way.

    Basically, to make

    <%double distance=geo.getDistance(geo.getLatitude(), geo.getLongitude(), lat, lng);%>
    

    available as ${distance}, you need to set it in any of the desired EL scopes, e.g. the request scope

    <%
      double distance=geo.getDistance(geo.getLatitude(), geo.getLongitude(), lat, lng);
      request.setAttribute("distance", distance);
    %>
    

    Once done that, then you can just use

    <fmt:formatNumber pattern="0.0" value="${distance}"/>
    

    without the need to massage with <c:set>, by the way.

    Note, a said, mixing scriptlets with EL is not the normal practice. You use the one or the other. In this particular case, that Java code belongs in a preprocessing servlet class.

    Also note that your concrete problem is not specifically related to JSTL. You just pointed it a non-existent variable.