JSF EL表达式调用List.get方法触发类型转换错误问题咨询
转换错误触发原因
该错误是MyFaces 2.0.17版本EL表达式解析器处理带参方法调用时的token解析缺陷,结合Websphere Application Server(WAS)8.5.5的上下文透传逻辑触发。
触发的报错日志如下:
PrimeExceptio E /pages/MyView.xhtml at line 566 and column 50 value="#{bean.myList.get(bean.listIndex).someAttr}": Cannot convert get of type class java.lang.String to class java.lang.Integer
报错信息里的Cannot convert get of type class java.lang.String to class java.lang.Integer,指的是解析器拆分表达式token时出现错位,错误将方法名字符串get识别为传入List.get()方法的第一个参数,尝试把字符串转成方法要求的Integer类型时抛出异常,并非定义的listIndex属性本身存在类型错误。listIndex为会话Bean中存储的int类型索引,对应get/set方法逻辑本身无问题:
public void setListIndex(int listIndex) { this.listIndex = listIndex; } public int getListIndex() { return listIndex; }
两种写法的核心原理差异
两种写法在EL规范中走完全独立的解析分支,兼容性表现存在本质区别:
- 方括号索引写法
#{bean.myList[bean.listIndex].someAttr}
这是EL规范原生定义的集合、数组标准访问语法,解析器对该语法做了专项适配:识别到操作对象是List或数组类型时,会自动将方括号内的表达式返回值做原生类型匹配,直接对接List.get(int index)方法签名,全程不经过通用方法反射匹配的参数解析流程,不会出现token错位问题,所有EL实现版本对该语法的兼容性都有明确保障,也是实际开发中访问集合元素的推荐写法。
可正常运行的写法示例:<h:inputHidden id="hidMyData" value="#{bean.myList[bean.listIndex].someAttr}" immediate="true"/> - 直接调用get方法写法
#{bean.myList.get(bean.listIndex).someAttr}
这是EL 2.2版本新增支持的自定义方法调用语法,解析器走通用方法反射匹配流程:先拆分表达式token识别方法名、参数数量,再根据传入参数的实际类型匹配目标方法签名。MyFaces 2.0.17版本对该流程的实现存在已知bug:在WAS 8.5.5的普通Web上下文环境中,解析器拆分带类属方法调用的表达式时会出现位置偏移,错误将方法名get作为第一个入参,原本应该传入的bean.listIndex参数错位,最终触发类型转换错误。
触发报错的写法示例:<h:inputHidden id="hidMyData" value="#{bean.myList.get(bean.listIndex).someAttr}" immediate="true"/>
跨环境表现差异的原因
两个运行环境虽然都采用MyFaces 2.0.17实现、Primefaces 6.2.27组件库,但IBM Portal 7的Portlet上下文对EL解析逻辑做了自定义封装,会提前修正方法调用表达式的token拆分结果,刚好绕过了MyFaces原生解析器的缺陷;而WAS 8.5.5的普通Web上下文没有做这层兼容处理,直接调用原生MyFaces解析逻辑,因此触发报错。
在无法升级MyFaces版本的场景下,使用方括号索引的标准集合访问语法是最稳定的兼容方案。
内容的提问来源于stack exchange,提问作者peterremec
相关产品推荐
相关产品推荐

