以下代码段在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>
但在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)
看起来在Tomcat 7中表达式${abc ne 0}
的方式存在差异。在Tomcat 6中,${abc}
和${0}
都被比较为字符串,但在Tomcat 7中我得到这个例外。我不知道为什么会发生这种情况以及哪个API的哪个类文件对此负责。
这是如何引起的?如何解决?
答案 0 :(得分:2)
这是因为您正在尝试将字符串与int进行比较。根据{{3}},第1.8.2节:
A {==,!=,eq,ne} B
■如果A == B,请应用运算符
■如果A为null或B为null,则为==或eq返回false,对于!=或ne,则返回true ■如果A或B为BigDecimal,则将A和B强制转换为BigDecimal,然后:
■如果运算符为==或eq,则返回A.equals(B)
■如果操作符是!=或ne,则返回!A.equals(B)
■如果A或B为Float或Double将A和B强制为Double,则应用操作员
■如果A或B是BigInteger,则将A和B强制转换为BigInteger,然后执行:
■如果运算符为==或eq,则返回A.equals(B)
■如果操作符是!=或ne,则返回!A.equals(B)
■如果A或B为字节,短,字符,整数或长,则将A和B强制为长,应用运算符
■如果A或B为布尔值,则将A和B强制为布尔值,请应用operato
■如果A或B是枚举,则强制A和B枚举,请应用运算符
■如果A或B是String将A和B强制转换为String,则按词汇顺序进行比较 ■否则,如果在调用A.equals(B)时发生错误,则出现错误
■否则,将运算符应用于A.equals(B)的结果
测试的问题在于您尝试将"$12,345"
(字符串)与0
(整数)进行比较。由于0
是一个整数,因此它属于文档中的粗体 If (上图),其中 A或B 是一个整数。两者都试图强制进入Long,Java不会将String值"$12,345"
转换为long。如果您将代码更改为以下任一项,您将看到它的工作原理:
字符串比较:
<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>
整数比较:
<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>