JSF 2.3 中的列表<String> 已接收列表<Long>

List<String> Received List<Long> in JSF 2.3

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

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

归档列表有 class 个对象,如 ob(1L, 'data1'); 具有通用类型 String

的 basisList

使用 JSFContainer 2.2、CDI 1.2 和 EL 3.0 时。它工作正常 Long 数据已作为字符串存储在 basisList 列表中。我理解下面的这个概念 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

您的 basisList 可能是 <Object> 类型,因此当您使用 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());
  }
}

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

UISelectMany javadoc for JSF 2.3中指定。

Obtain the Converter using the following algorithm:

  • If the component has an attached Converter, use it.

  • If not, look for a ValueExpression for value (if any). The ValueExpression must point to something that is:

    • An array of primitives (such as int[]). Look up the registered by-class Converter for this primitive type.

    • An array of objects (such as Integer[] or String[]). Look up the registered by-class Converter for the underlying element type.

    • A java.util.Collection. Do not convert the values. Instead, convert the provided set of available options to string, exactly as done during render response, and for any match with the submitted values, add the available option as object to the collection.

If for any reason a Converter cannot be found, assume the type to be a String array.

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

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