1

我已将我的项目从 JSFContainer 2.2 升级到 JSFContainer 2.3

<p:selectManyListbox id="acl" value="#{controller.process.basisList}" >  
    <f:selectItems value="#{controller.filinglist}" />  
</p:selectManyListbox> 

归档列表有像 ob(1L, 'data1') 这样的类对象;具有泛型字符串的基础列表

使用 JSFContainer 2.2、CDI 1.2 和 EL 3.0 时。工作正常长数据已作为字符串存储在基础列表列表中。我在下面的 URL 中理解了这个概念

Java 反射 API

但是在 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
4

2 回答 2

3

当您从 JSF 2.2 升级到 JSF 2.3 时,此行为是正确的。以前,JSF 2.2 和更早版本没有自动转换这些值,这实际上不是预期的行为。

它在UISelectManyJSF 2.3 的 javadoc 中指定。

Converter使用以下算法获得:

  • 如果组件有一个附加的Converter,使用它。

  • 如果没有,请查找ValueExpressionfor 值(如果有)。必须指向的ValueExpression东西是:

    • 一组基元(例如int[])。查找Converter该原始类型的注册类。

    • 对象数组(例如Integer[]String[])。查找Converter底层元素类型的注册类。

    • 一个java.util.Collection。不要转换值。相反,将提供的一组可用选项转换为字符串,就像在渲染响应期间所做的那样,并且对于与提交值的任何匹配,将可用选项作为对象添加到集合中。

如果由于某种原因Converter无法找到 a,则假定类型为 String 数组。

上述块引用的强调部分是自 JSF 2.3 以来的新内容(为了比较,这里是javadoc的 JSF 2.2 变体UISelectMany)。

您需要将您的 修复basisList为与 完全相同的类型filinglist,否则您需要附加一个明确的Converter.

于 2019-02-28T08:10:40.357 回答
1

您的 basicList 可能是类型<Object>,因此当您使用StringJava 创建 for 循环时,会尝试将该值转换为 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());
  }
}

于 2019-02-27T11:22:43.913 回答