JSTL fmt:formatNumber

21,886

Solution 1

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.

Solution 2

If you want to publish java variable to ${ExpressionLanguage} you must add it to the context. There are application, session, request and page contexts. This is what happens in my test page.

  • Using <% ... %> tags always indicates "heavy weight" java code, variables are not directly visible in JSTL code.
  • introduce java variable to JSTL context such as pagecontext. Now you can use ${xx} EL variables in jsp code.
  • I did not put distance2 to a context, but using it through <%= .. %> embedded java scriptlet. Sometimes its just easiest to do this way.
  • You even can introduce ${EL}- only variable back to heavy weight java side, use jsp:useBean tag to create java variable. Then it can be seen in <%..%> scriptlets.
  • I made a simple math expression inside ${distanceEL3} value as an example.
  • For you information, if use Tomcat look at the tomcat/work/Catalina/localhost/mywebapp/org/apache/jsp/test_jsp.java file. You can see how variables are created like was written java file by hand.

test.jsp

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %><%@ 
    taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %><%@page 
    contentType="text/plain; charset=UTF-8" pageEncoding="ISO-8859-1"
    import="java.text.*"
%><%

double distance=1234.567;
double distance2=3456.789;
pageContext.setAttribute("distance", distance);

%>Test Results

<fmt:setLocale value="en_US" scope="page"/>

<c:set var="distanceEL" value="${distance}" />
distance=${distance}
fmt1=<fmt:formatNumber pattern="0.0" value="${distance}" />
fmt2=<fmt:formatNumber pattern="0.00" value="${distanceEL}" />
fmt3=<fmt:formatNumber pattern="0.0" value="1234.567" />
fmt4=<%= new DecimalFormat("0.0").format(distance) %>

<c:set var="distanceEL2" value="<%= distance2 %>" />
distance2=${distanceEL2}
fmt1=<fmt:formatNumber pattern="0.0" value="<%= distance2 %>" />
fmt2=<fmt:formatNumber pattern="0.00" value="${distanceEL2}" />
fmt4=<%= new DecimalFormat("0.0").format(distance2) %>

<c:set var="distanceEL3" value="${765.432-2.2}" />
<jsp:useBean id="distanceEL3" type="java.lang.Double" />
distance3=${distanceEL3}
fmt1=<fmt:formatNumber pattern="0.0" value="<%= distanceEL3 %>" />
fmt2=<fmt:formatNumber pattern="0.00" value="${distanceEL3}" />
fmt4=<%= new DecimalFormat("0.0").format(distanceEL3) %>
Share:
21,886
Chloe
Author by

Chloe

Updated on July 09, 2022

Comments

  • Chloe
    Chloe almost 2 years

    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.