为什么UISelectMany没有返回通用属性的集合?

时间:2015-07-06 21:23:13

标签: arrays jsf jsf-2 collections selectmanymenu

我有一个包含<h:selectManyMenu>元素的JSF页面。 value属性指向子类中定义的类型为ArrayList<String>的通用对象。根据java文档,UISelectMany应该将转换后的值作为此具体类型的Collection返回。但它作为String[]数组返回。我错过了什么?

<h:selectManyMenu value="#{parameter.value}">
    <f:selectItems value="#{parameter.valueList}"/>
</h:selectManyMenu>
public class Parameter<ArrayList<String>> extends ParentClass
{
  private LinkedHashMap<Object, String> valueList;

  public List<SelectItem> getValueList()
  {
    ArrayList<SelectItem> list = new ArrayList<SelectItem>();
    for (Iterator<Object> i = this.valueList.keySet().iterator(); i.hasNext();)
    {
      Object value = i.next();
      list.add(new SelectItem(value, this.valueList.get(value)));
    }

    return list;
  }
}
public abstract class ParentClass<T>
{
  private T value;

  public T getValue() { return this.value; }
  public void setValue(T t) { this.value = t; }
}

2 个答案:

答案 0 :(得分:1)

这是因为getValue()返回参数化类型T,它将在通用类型擦除后变为Object。换句话说,EL没有看到它实际返回ListObject,因此默认为String[]

您需要在选择组件上明确指定collectionType属性,并将所需集合实现的FQN作为值。

<h:selectManyMenu ... collectionType="java.util.ArrayList">

不相关到具体问题,<f:selectItems>也支持Map<K, V>。只需将LinkedHashMap直接提供给它,而无需将其按到List<SelectItem>。 map键成为选项值,map值已成为选项标签。另请参阅our selectOneMenu wiki page

答案 1 :(得分:0)

我无法让JSF从子类中读取属性的类型定义。指定collectionType属性不起作用,即使在子类中创建@Override方法尝试时,发送到我的bean的支持值仍然是String[]数组。我能够让JSF servlet将此值作为ArrayList<String>返回的唯一方法是在子类中创建另外一对get / set属性方法,并将ArrayList<String>作为其返回和参数类型。

public class Parameter extends ParentClass<ArrayList<String>>
{
  public ArrayList<String> getManyValue() { return super.getValue(); }
  public void setManyValue(ArrayList<String> value) { super.setValue(value); }
}


public abstract class ParentClass<T>
{
  protected T value;
  public T getValue() { return this.value; }
  public void setValue(T value) { this.value = value; }
}


<h:selectManyMenu value="#{parameter.manyValue}"/>