JSF 2.3中的List <string>收到的List <long>

时间:2019-02-27 11:10:35

标签: jsf converters jsf-2.3 selectmanycheckbox

我已经将项目从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列表中,效果很好。我在下面的网址中了解了这个概念

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

2 个答案:

答案 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 java.util.Collection。不要转换值。 相反,将提供的一组可用选项完全转换为字符串,就像在渲染响应期间所做的那样,并且对于与提交的值的任何匹配,请将可用选项作为对象添加到集合中。

      < / li>   
  •   
     

如果由于某种原因找不到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());
  }
}