javajstlel

jakarta.el.ELException: Cannot convert [1.0] of type [class java.lang.String] to [class java.lang.Long]


I am trying to pass a parameter to a jsp:include. Then I use that parameter in a if statement, here is the jsps:

 <jsp:include page="/Review Score Display.jsp">
      <jsp:param name="Score" value="${reviewScore}"/>
 </jsp:include>

This is Review Score Display:

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<body>
<c:choose>
  <c:when test="${param.Score ge 1}">
    <span class="fa fa-star checked fa-2x"></span>
  </c:when>
  <c:otherwise>
    <span class="fa fa-star fa-2x"></span>
  </c:otherwise>
</c:choose>
<c:choose>
  <c:when test="${param.Score ge 2}">
    <span class="fa fa-star checked fa-2x"></span>
  </c:when>
  <c:otherwise>
    <span class="fa fa-star fa-2x"></span>
  </c:otherwise>
</c:choose>
<c:choose>
  <c:when test="${param.Score ge 3}">
    <span class="fa fa-star checked fa-2x"></span>
  </c:when>
  <c:otherwise>
    <span class="fa fa-star fa-2x"></span>
  </c:otherwise>
</c:choose>
</body>
</html>

But when I run it, I get an error page that indicates an error at line 13 of Review Score Display (the first c:when statement) saying jakarta.el.ELException: Cannot convert [1.0] of type [class java.lang.String] to [class java.lang.Long]

I'm not sure why the Score parameter is considered a string. If I do this: <c:when test="${reviewScore ge 1}"> in the original JSP, it works just fine, so I guess when I pass review score as a parameter in the jsp:include it gets converted into a string?

What can I do to make the comparison work?


Solution

  • When you pass a value using <jsp:param>, it becomes a string inside ${param.Score} - even if the original value was a number

    Then, when JSTL's <c:when> tries to compare it like ${param.Score ge 1}, it expects a number, not a string. Since the value is still a string, it throws an error.

    To fix this, you can pass the value as a request attribute instead of a param. In the parent JSP, set the attribute before including:

    <%
        int score = Integer.parseInt(request.getParameter("reviewScore"));
        request.setAttribute("score", score);
    %>
    

    In "Review Score Display.jsp", just use:

    <c:when test="${score ge 1}">
    

    Besides setting a request attribute manually, there are a few other options - though most are less clean.

    You could parse param.Score using a scriptlet and store it in a new attribute, but mixing scriptlets with JSTL isn't ideal. A better way is to pass the numeric value from your controller directly as a request attribute, avoiding <jsp:param> entirely.

    It's also technically possible to coerce a string to a number using ${param.Score + 0 ge 1}, but this relies on implicit type conversion and can easily break if the parameter is empty or non-numeric.

    If you want to keep your logic inside JSTL and avoid scriptlets, another option is to define your own custom EL function like parseInt(...). Create a static utility class:

    package my.tags;
    
    public class MyFunctions {
        public static int parseInt(String value) {
            return Integer.parseInt(value);
        }
    }
    
    

    Create a TLD file (e.g., my-functions.tld in WEB-INF):

    <?xml version="1.0" encoding="UTF-8"?>
    <taglib xmlns="http://java.sun.com/xml/ns/javaee"
            version="2.1">
        <tlib-version>1.0</tlib-version>
        <short-name>myfn</short-name>
        <uri>http://example.com/myfn</uri>
    
        <function>
            <name>parseInt</name>
            <function-class>my.tags.MyFunctions</function-class>
            <function-signature>int parseInt(java.lang.String)</function-signature>
        </function>
    </taglib>
    
    

    Use it in your JSP:

    <%@ taglib prefix="myfn" uri="http://example.com/myfn" %>
    
    <c:when test="${myfn:parseInt(param.Score) ge 1}">
      <!-- markup -->
    </c:when>
    
    

    This gives you a clean and reusable way to handle string-to-number conversion in JSP. Just make sure the .tld file is placed in WEB-INF and properly registered.