我已经将项目从JSFContainer 2.2升级到JSFContainer 2.3
<p:selectManyListbox id="acl" value="#{controller.process.basisList}" >
<f:selectItems value="#{controller.filinglist}" />
</p:selectManyListbox>
filinglist具有类似ob(1L,'data1')的类对象; 通用类型为String
的basicList使用JSFContainer 2.2,CDI 1.2和EL 3.0时。 Long数据已作为String存储在basicList列表中,效果很好。我在下面的网址中了解了这个概念
但是在JSFContainer 2.3,CDI 2.0和EL 3.0中。我收到以下错误
运行代码时
for(String i : basisList) {
System.out.println(i);
}
java.lang.ClassCastException: java.lang.Long cannot be cast to java.lang.String.
我使用以下代码进行调试
for(Object i : basisList) {
System.out.println(i.getClass() + " > " + i);
}
下面得到的输出
class java.lang.Long > 3
答案 0 :(得分:3)
从JSF 2.2升级到JSF 2.3时,此行为是正确的。以前,JSF 2.2和更早版本不会自动转换这些值,而这实际上不是预期的行为。
它在UISelectMany
javadoc for JSF 2.3中指定。
使用以下算法获取
Converter
:
如果组件具有附加的
Converter
,请使用它。如果没有,请寻找
ValueExpression
作为值(如果有)。ValueExpression
必须指向以下内容:
基元数组(例如
int[]
)。在此原始类型中查找注册的类Converter
。对象数组(例如
Integer[]
或String[]
)。在注册的类Converter
中查找基础元素类型。A
< / li>java.util.Collection
。不要转换值。 相反,将提供的一组可用选项完全转换为字符串,就像在渲染响应期间所做的那样,并且对于与提交的值的任何匹配,请将可用选项作为对象添加到集合中。如果由于某种原因找不到
Converter
,则假定类型为String数组。
上述块引用中强调的部分是自JSF 2.3(比较here's the JSF 2.2 variant of UISelectMany
javadoc)以来的新内容。
您需要将basisList
修改为与filinglist
完全相同的类型,否则需要附加一个明确的Converter
。
答案 1 :(得分:1)
您的baseList可能是<Object>
类型,因此当您使用String
创建for循环时,Java会尝试将该值转换为String变量i
。在您的情况下,您似乎有一个列表的一部分,或者完全用原始long
类型填充,这些类型不能仅仅转换为字符串。您可以编写一些支持这两种情况的代码。
List<Object> basisList = new ArrayList<>();
for (Object o : basisList) {
if (o instanceof String) {
System.out.println(o.toString());
} else if(o instanceof Long){
System.out.println(Long.toString((Long) o));
} else {
System.out.println("Some other type = " + o.toString());
}
}