4

我正在<p:selectCheckboxMenu>使用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

这是如何引起的,我该如何解决?

4

1 回答 1

9

您的问题是由以下事实引起的:

  1. Java 泛型是编译时语法糖,在运行时完全不存在。
  2. EL 表达式在运行时而不是在编译时运行。
  3. HTTP 请求参数以s 形式获取String

逻辑结果是:EL 看不到任何泛型类型信息。EL 没有看到 a List<Long>,而是看到 a List。因此,当您没有明确指定转换器时,EL 将在通过反射String方式获取提交的值后将其设置为未修改。当您在运行时尝试将其转换为之后时,您显然会面临一个.ListLongClassCastException

String解决方案很简单:为to明确指定转换器LongLongConverter您可以为此使用具有转换器 ID的 JSF 内置函数javax.faces.Long此处列出了其他内置转换器。

<p:selectCheckboxMenu ... converter="javax.faces.Long">

另一种无需明确指定转换器的解决方案是将List<T>类型更改为T[]. 这样,EL 将看到Long类型化数组,从而执行自动转换。但这可能需要在模型的其他地方进行更改,这可能是不可取的。

private Long[] selectedItems;

如果您使用复杂对象(javabean、实体、POJO 等)作为选择项值,而不是像LongJSF 具有内置转换器的标准类型,那么同样的规则也适用。您只需要创建一个自定义Converter并在输入组件的属性中明确指定它converter,或者依赖forClass是否可以使用T[]. 如何创建这样的转换器在Conversion Error setting value for 'null Converter'中有详细说明。

于 2013-11-09T11:13:46.640 回答