列表< T>上的UISelectMany.导致java.lang.ClassCastException:java.lang.String无法转换为T [英] UISelectMany on a List<T> causes java.lang.ClassCastException: java.lang.String cannot be cast to T

查看:139
本文介绍了列表< T>上的UISelectMany.导致java.lang.ClassCastException:java.lang.String无法转换为T的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在List<Long>上使用 <p:selectCheckboxMenu> :

I am using <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;

提交表单并按以下方式遍历所选项目时,

When submitting the form and looping over the selected items as below,

for (int i = 0; i < selectedItems.size(); i++) {
    Long id = selectedItems.get(i);
    // ...
}

然后我得到一个类强制转换异常:

Then I get a class cast exception:

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属性上的所有其他单选组件中,它都可以正常工作.

The same problem occurs with <p:selectManyCheckbox>, <p:selectManyMenu>, <h:selectManyMenu>, etc. All multiple-selection components basically. It works fine in <p:selectOneMenu> and all other single-selection components on a single value Long property.

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

How is this caused and how can I solve it?

推荐答案

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

Your problem is caused by the following facts:

  1. Java泛型是编译时的语法糖,在运行时完全不存在.
  2. EL表达式在运行时而非编译时运行.
  3. HTTP请求参数为逻辑结果是:EL没有看到任何通用类型信息. EL没有看到List<Long>,但是看到了List.因此,当您未明确指定转换器时,EL将在获取提交的值作为String后,通过List中将其设置为未修改的值. /reflect/"rel =" nofollow noreferrer>反射表示.当您随后尝试在运行时将其强制转换为Long时,显然会遇到ClassCastException.

    Logical consequence is: EL doesn't see any generic type information. EL doesn't see a List<Long>, but a List. So, when you don't explicitly specify a converter, EL will after obtaining the submitted value as String set it unmodified in the List by reflection means. When you attempt to cast it to Long afterwards during runtime, you'll obviously face a ClassCastException.

    解决方案很简单:为StringLong显式指定一个转换器.您可以使用内置的JSF LongConverter 具有转换器ID 此处列出了其他内置的转换器

    The solution is simple: explicitly specify a converter for String to Long. You can use the JSF builtin LongConverter for this which has the converter ID javax.faces.Long. Other builtin converters are listed here.

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

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

    Another solution without the need to explicitly specify the converter is to change List<T> type to a T[]. This way the EL will see the Long typed array and thus perform automatic conversion. But this possibly requires changes elsewhere in the model which may not be desirable.

    private Long[] selectedItems;
    

    如果您使用复杂的对象(javabean,实体,POJO等)作为选择项值,而不是使用JSF内置转换器的标准类型(如Long),则同样的规则也适用.您只需要创建一个自定义Converter并在输入组件的converter属性中显式指定它,或者如果可以使用T[]则依赖于forClass. 转换错误设置中详细说明了如何创建此类转换器.空转换器的值.

    In case you're using a complex object (javabean, entity, POJO, etc) as select item value instead of a standard type like Long for which JSF has builtin converters, then the same rules also apply. You only need to create a custom Converter and explicitly specify it in input component's converter attribute, or rely on forClass if you can use T[]. How to create such a converter is elaborated in Conversion Error setting value for 'null Converter'.

    这篇关于列表&lt; T&gt;上的UISelectMany.导致java.lang.ClassCastException:java.lang.String无法转换为T的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆