【问题标题】:List<String> Received List<Long> in JSF 2.3JSF 2.3 中的 List<String> 接收 List<Long>
【发布时间】:2019-07-21 02:17:51
【问题描述】:

我已将我的项目从 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 的基础列表

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

Java Reflection 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

【问题讨论】:

标签: jsf converters jsf-2.3 selectmanycheckbox


【解决方案1】:

您的基础列表可能是&lt;Object&gt; 类型,因此当您使用String 创建for 循环时,Java 会尝试将该值转换为字符串变量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());
  }
}

【讨论】:

  • 没有。正如我所提到的,basicList 类型是 。 List baseList = new ArrayList();
  • 不可能,否则你永远不会得到那个类转换异常。您的列表中有 Long 类型。
  • 没有亚当。它在 JSF 2.2 中运行良好。请阅读此链接stackoverflow.com/questions/21446068/…。链接的错误反向发生在我身上。
  • 是的,但是就像答案所说的那样,泛型类型在编译期间消失了,一切都是对象并在运行时转换为不同的类型。该类转换异常向我表明,您认为仅包含 的列表实际上有一些 Long 值。我不熟悉 JSF 在底层是如何工作的,但是如果你在你的方法中添加一些类型检查,你可能能够调试正在发生的事情。
  • @Adam: EL 和从网页传递到服务器可能会导致“列表”被解释为字符串。是的,可能有一些不明确的东西,但它不一定是列表本身。 OP 应该创建一个 minimal reproducible example 并且没有使用 java 标签,因为它不能在普通 jdk 中复制
【解决方案2】:

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

UISelectMany javadoc for JSF 2.3中指定。

使用以下算法获取Converter

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

  • 如果没有,请查找 ValueExpression 的值(如果有)。 ValueExpression 必须指向以下内容:

    • 基元数组(例如int[])。查找已注册的类 Converter 以获取此原始类型。

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

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

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

上述块引用的强调部分是自 JSF 2.3 以来的新内容(比较,here's the JSF 2.2 variant of UISelectMany javadoc)。

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

【讨论】:

    猜你喜欢
    • 2019-07-31
    • 2014-02-22
    • 1970-01-01
    • 2018-05-08
    • 1970-01-01
    • 2015-12-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多