我在用<p:selectCheckboxMenu> on a List<Long>
:
<p:selectCheckboxMenu value="#{bean.selectedItems}">
<f:selectItems value="#{bean.availableItems}" />
</p:selectCheckboxMenu>
private List<Long> selectedItems;
private Map<String, Long> availableItems;
提交表单并循环选择的项目时,如下所示,
for (int i = 0; i < selectedItems.size(); i++) {
Long id = selectedItems.get(i);
// ...
}
然后我得到一个类强制转换异常:
java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Long
at com.example.Bean.submit(Bean.java:42)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at org.apache.el.parser.AstValue.invoke(AstValue.java:278)
at org.apache.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:274)
at com.sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:105)
at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:87)
... 27 more
同样的问题发生在<p:selectManyCheckbox>
, <p:selectManyMenu>
, <h:selectManyMenu>
等等。基本上都是多选组件。它工作得很好<p:selectOneMenu>
以及单个值上的所有其他单选组件Long
财产。
这是如何引起的以及如何解决?
您的问题是由以下事实引起的:
- Java 泛型是编译时语法糖,在运行时完全不存在。
- EL 表达式在运行时运行,而不是在编译时运行。
- HTTP请求参数为obtained as
String
s.
逻辑结果是:EL 看不到任何泛型类型信息。 EL 没有看到List<Long>
, but a List
。因此,当您没有显式指定转换器时,EL 将在获取提交的值后将其转换为String
将其设置为未修改的List
by 反射方法。当您尝试将其投射到Long
之后在运行时,你显然会面临ClassCastException
.
解决方案很简单:显式指定一个转换器String
to Long
。您可以使用 JSF 内置LongConverter对于这个有转换器ID的javax.faces.Long。列出了其他内置转换器here.
<p:selectCheckboxMenu ... converter="javax.faces.Long">
无需显式指定转换器的另一种解决方案是更改List<T>
键入一个T[]
。这样 EL 将看到Long
类型化数组,从而执行自动转换。但这可能需要对模型的其他地方进行更改,这可能是不可取的。
private Long[] selectedItems;
如果您使用复杂对象(javabean、实体、POJO 等)作为选择项值而不是标准类型,例如Long
对于 JSF 有内置转换器的情况,同样的规则也适用。您只需要创建一个自定义的Converter
并在输入组件中明确指定它converter
属性,或依赖forClass
如果你可以使用T[]
。如何创建这样的转换器在“null Converter”的转换错误设置值.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)