关于jstl EL用法的注意点(java.lang.NumberFormatException: For input string: "userName")

本文介绍了在使用JSTL标签时遇到的`java.lang.NumberFormatException`问题,特别是当尝试访问集合对象的属性时。错误源于EL表达式将属性名错误地视为数组下标尝试转换为整数。解决方案是理解EL表达式处理list时的规则,并避免直接通过`.`操作符访问可能被视为下标的字符串属性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

借鉴一:【1】

在使用jstl tag <c:forEach var="item" items="${managerPurviewList}" begin="0"> 的时候,一般可以用来在页面上展现集合的数据,但是有一点必须要注意的,就是var 和items的含义的问题。

   查看api文档,上面只是简单的说明了一下,其实在实现该标签的时候,内部是通过items里面指定的这个集合对象来获取一个Iterator 的,这就是ForEachIterator 。也就是说先把你的items属性的那个集合对象拿出来,然后获取其上面的迭代器,通过该迭代器的next方法得到集合中的第一个元素(当然根据是否配置了start  end 和step迭代的方法少有不同),这里就要注意了,获取到第一个元素以后,它会将该元素作为一个通用的object对象赋值给var属性里面指定的那个变量名称,例如你在var属性里面知道var="item",那么这时候i就是一个object对象。

   如果你迭代的是一个list<User>这样的自定义对象的list,那么这时候item会得到一个object,而且该object是一个object【】类型,也就是说,会将list里面的每个user对象的属性值get出来,作为一个object再存放到i所引用的那个object里面去,说到这里,大家就应该明白了,其实该标签在处理list<User>类型的集合的展现问题的时候,是简单的将该集合中的每个具体对象的属性值取出来封装成一个个的object,然后放入item这个object数组中去的,所以,我们在前台jsp页面上展现的时候不能使用$(item.userName)这样的方法来得到对应的值,否则会报java.lang.NumberFormatException: For input string: "userName" 这样的异常的,原因就是因为返回的item是一个object的数组,$(item.userName)这种访问方式是不能用来访问数组的,否则在处理的时候jsp引擎会先将userName这个字符串转换成int以确定数组下标,而在转换的时候就会出现字符串“userName”无法转换成int的异常了。

 

 

借鉴二【2】

最近项目里面 忽然一个页面 暴出 如下异常 

 

 

Stacktrace:
	org.apache.jasper.servlet.JspServletWrapper.handleJspException(JspServletWrapper.java:568)
	org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:470)
	org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:390)
	org.apache.jasper.servlet.JspServlet.service(JspServlet.java:334)
	javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
	com.sinitek.agent.filter.AgentDispatcherFilter.doFilter(AgentDispatcherFilter.java:93)
	org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:78)
	org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:77)
	org.apache.struts2.dispatcher.FilterDispatcher.doFilter(FilterDispatcher.java:413)
	org.apache.struts2.dispatcher.ActionContextCleanUp.doFilter(ActionContextCleanUp.java:99)
root cause

java.lang.NumberFormatException: For input string: "caption"
	java.lang.NumberFormatException.forInputString(NumberFormatException.java:48)
	java.lang.Integer.parseInt(Integer.java:449)
	java.lang.Integer.parseInt(Integer.java:499)
	javax.el.ListELResolver.coerce(ListELResolver.java:163)
	javax.el.ListELResolver.getValue(ListELResolver.java:51)
	org.apache.jasper.el.JasperELResolver.getValue(JasperELResolver.java:104)
	org.apache.el.parser.AstValue.getValue(AstValue.java:183)
	org.apache.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:184)
	org.apache.jasper.runtime.PageContextImpl.proprietaryEvaluate(PageContextImpl.java:967)
	org.apache.jsp.agent.pages.personal_005fagent.productdetail_jsp._jspService(productdetail_jsp.java:481)
	org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
	javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
	org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:432)
	org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:390)
	org.apache.jasper.servlet.JspServlet.service(JspServlet.java:334)
	javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
	com.sinitek.agent.filter.AgentDispatcherFilter.doFilter(AgentDispatcherFilter.java:93)
	org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:78)
	org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:77)
	org.apache.struts2.dispatcher.FilterDispatcher.doFilter(FilterDispatcher.java:413)
	org.apache.struts2.dispatcher.ActionContextCleanUp.doFilter(ActionContextCleanUp.java:99)

一看到这个错 我以为是 fmt:formatNumber 标签 报错,将所有的 fmt:formatNumber 都去除 还是报错!百思不得其解!

 

最后一段一段代码排除,发现是数据问题! 可是还是觉得不可思议,所以今天继续故意把数据搞错,然后分析为啥会报 NumberFormatException 

 

最后看异常栈的信息 

 

java.lang.NumberFormatException: For input string: "caption"
	java.lang.NumberFormatException.forInputString(NumberFormatException.java:48)
	java.lang.Integer.parseInt(Integer.java:449)
	java.lang.Integer.parseInt(Integer.java:499)
	<span style="color:#cc6600;">javax.el.ListELResolver.coerce(ListELResolver.java:163)
	javax.el.ListELResolver.getValue(ListELResolver.java:51)</span>
<span style="color:#ff6600;">	org.apache.jasper.el.JasperELResolver.getValue(JasperELResolver.java:104)</span>
	<span style="color:#ff6600;">org.apache.el.parser.AstValue.getValue(AstValue.java:183)
	org.apache.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:184)</span>
	org.apache.jasper.runtime.PageContextImpl.proprietaryEvaluate(PageContextImpl.java:967)
	org.apache.jsp.agent.pages.personal_005fagent.productdetail_jsp._jspService(productdetail_jsp.java:481)
	org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
	javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
	org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:432)
	org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:390)
	org.apache.jasper.servlet.JspServlet.service(JspServlet.java:334)
	javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
	com.sinitek.agent.filter.AgentDispatcherFilter.doFilter(AgentDispatcherFilter.java:93)
	org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:78)
	org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:77)
	org.apache.struts2.dispatcher.FilterDispatcher.doFilter(FilterDispatcher.java:413)
	org.apache.struts2.dispatcher.ActionContextCleanUp.doFilter(ActionContextCleanUp.java:99)

 

发现  这5行是el 表达式的 解析!

谷歌 找 ListELResovler的源码 

 

public Object More ...getValue(ELContext context,
157                           Object base,
158                           Object property) {
159
160        if (context == null) {
161            throw new NullPointerException();
162        }
163
164        if (base != null && base instanceof List) {
165            context.setPropertyResolved(true);
166            List list = (List) base;
167            int index = toInteger(property);
168            if (index < 0 || index >= list.size()) {
169                return null;
170            } 
171            return list.get(index);
172        }
173        return null;
174    }

现在报错原因知道了,确认是 转换的时候  调用了  LisELResolver t的 转换!

 

但是问题来了 为啥 使用 ListELRsolver 进行转换呢?  猜测是因为 结果集是 list 导致的,最后发现果然是list!

 

 

<common:getDictList var="statu" keyNo="1004"
                                                                  keyValue="${product.productstatus}"/>${statu.caption}
 

 

由于 statu 是一个list 导致  el表达式 认为后面一定跟的是 下标 所以把 capition 转换成 数字 然后异常了!

 

 

<common:getDictList var="statu" keyNo="1004"
                                                                  keyValue="${product.productstatus}"/>${statu[0].caption}

这样就ok了! 

 

 

所以 NumberFormat 异常 不一定是 format 标签的问题!

自己遇到的问题描述

在JSP文件中使用了JSTL EL,发现(java.lang.NumberFormatException: For input string: "CPMC")

前端部分语句

<c:choose>
    <c:when test="${holdProduct eq null}">
        <input type="text"  id="ktransferProdSelect"  class=" input-xlarge text2" name="KEY" placeholder="产品名称">
    </c:when>
    <c:otherwise>
        ${holdProduct.CPMC}
    </c:otherwise>
</c:choose>

后端部分语句   

DataList holdProduct = avicAccountService.holdProducts("5",user.getKHH(),prodId, htid,1,900);
model.addAttribute("holdProduct", holdProduct);

 

解决方案

DataList holdProduct = avicAccountService.holdProducts("5",user.getKHH(),prodId, htid,1,900);
model.addAttribute("holdProduct", holdProduct.getData(0));

说明:在EL中默认list的 “.”后面的是下标会将String强制转换为Integer 有问题

我的项目后端的数据结构是经过二次封装的,所以我去getData(0)相当于在前端写了holdProduct【0】.CPMC

 

[1] 空城丶.关于jstl EL用法的注意点(java.lang.NumberFormatException: For input string: "userName").2014.10.29. https://www.cnblogs.com/csy8fs/p/4059658.html

[2]  ausky . el 表达式 报 java.lang.NumberFormatException: For input string: "xxx" .2014.12.10 .  https://blog.youkuaiyun.com/ouvidia/article/details/41844037

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值