Question

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.

Was it helpful?

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.

OTHER TIPS

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) %>

I found it!

<fmt:formatNumber pattern="0.0" value="<%=distance%>"/>

Which is weird, because I tried

<%= geo.getDistance(geo.getLatitude(), geo.getLongitude(), ${lat}, ${lng}) %>

which blew up. It's SO confusing! No where is it explained which has higher precedence, <%%> or ${}

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top