为什么UISelectMany不返回泛型属性的集合?



我有一个包含<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; }
}

这是因为getValue()返回一个参数化类型T,该类型将在泛型擦除后变为Object。换句话说,EL没有看到它实际上返回的是List,而是Object,因此将默认为String[]

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

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

与具体问题无关,<f:selectItems>也支持Map<K, V>。只需将LinkedHashMap直接提供给它,而无需将其按摩到List<SelectItem>。映射键成为选项值,映射值已经成为选项标签。参见selectOneMenu wiki页面

我无法让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}"/>

相关内容

  • 没有找到相关文章

最新更新