为什么 UISelectMany 不返回通用 属性 上的集合?

Why is UISelectMany not returning a collection on a generic property?

我有一个包含 <h:selectManyMenu> 元素的 JSF 页面。 value 属性指向在子类中定义为类型 ArrayList<String> 的通用对象。根据 java 文档,UISelectMany 应该 return 其转换值作为此具体类型的 Collection。但它被 return 编辑为 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()returns是一个参数化类型T,泛型擦除后会变成Object。换句话说,EL 没有看到它实际上返回了 List 而是 Object,因此将默认为 String[].

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

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

与具体问题无关<f:selectItems>也支持Map<K, V>。直接将 LinkedHashMap 喂给它,而不用将其按摩成 List<SelectItem>。映射键成为选项值,映射值已经成为选项标签。另见 our selectOneMenu wiki page.

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

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}"/>