String to Long compares throws "ELException: Can not convert" in Tomcat 7, works in Tomcat 6

The following snippet works fine in Tomcat 6,

<c:set var="abc" value="$12,345" /> <c:choose> <c:when test="${abc ne 0}"> <c:out value="PASS"></c:out> </c:when> <c:otherwise> <c:out value="FAIL"></c:out> </c:otherwise> </c:choose> 

but throws an exception in Tomcat 7.

 javax.el.ELException: Cannot convert $1,2345 of type class java.lang.String to class java.lang.Long at org.apache.el.lang.ELSupport.coerceToNumber(ELSupport.java:304) at org.apache.el.lang.ELSupport.coerceToNumber(ELSupport.java:283) at org.apache.el.lang.ELSupport.equals(ELSupport.java:143) at org.apache.el.parser.AstNotEqual.getValue(AstNotEqual.java:40) at org.apache.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:185) at org.apache.jasper.runtime.PageContextImpl.proprietaryEvaluate(PageContextImpl.java:1026) at org.apache.jsp.WEB_002dINF.jsp.web.statussummary.status_005fsummary_jsp._jspx_meth_c_005fwhen_005f0(status_005fsummary_jsp.java:290) 

There seems to be a difference in how the expression ${abc ne 0} is called in Tomcat 7. In Tomcat 6, both ${abc} and ${0} compared as strings, but in Tomcat 7 I get this exception. I do not know why this should happen, and what class file the API is responsible for.

How is this caused and how can I solve it?

+5
source share
1 answer

This is because you are trying to compare a string with an int. In EL docs , section 1.8.2:

A {== ,! =, eq, ne} B
■ If A == B, apply the operator ■ If A is null or B is null, return false for == or eq, true for! = Or ne.
■ If A or B is BigDecimal, force both A and B to BigDecimal, and then:
■ If the operator is == or eq, return A.equals (B)
■ If the operator is! = Or ne, return! A.equals (B)
■ If A or B is a Float or Double, force A and B to Double, apply the statement
■ If A or B is BigInteger, force both A and B to BigInteger, and then:
■ If the operator is == or eq, return A.equals (B)
■ If the operator is! = Or ne, return! A.equals (B)
If A or B is a byte, short, character, integer, or long, forcing both A and B to Long, apply the operator
■ If A or B is a logical coercion of both A and B to Boolean, apply operato ■ If A or B is an enumeration, force A and B to enumerate, apply the operator ■ If A or B is a string that forces both A, so and B to String, compare lexically
■ Otherwise, if an error occurs when calling A.equals (B), the error ■ Otherwise, apply the operator to the result of A.equals (B)

The problem with your test is that you are trying to compare "$12,345" (String) with 0 (Integer). Since 0 is an integer, it ends up in bold If in its docs (above), where A or B is an integer. Both are trying to force a nest in Long, which Java will not convert the String value of "$12,345" to long. If you change your code to one of the following, you will see that it works:

String Comparison:

 <c:set var="abc" value="$12,345" /> <c:choose> <c:when test="${abc ne '0'}"> <!-- Change Integer to String --> <c:out value="PASS"></c:out> </c:when> <c:otherwise> <c:out value="FAIL"></c:out> </c:otherwise> </c:choose> 

Integer comparison:

 <c:set var="abc" value="12345" /> <!-- Change String to Integer --> <c:choose> <c:when test="${abc ne 0}"> <c:out value="PASS"></c:out> </c:when> <c:otherwise> <c:out value="FAIL"></c:out> </c:otherwise> </c:choose> 
+2
source

Source: https://habr.com/ru/post/1200164/


All Articles