Почему UISelectMany не возвращает коллекцию для универсального свойства?

У меня есть страница JSF, которая содержит <h:selectManyMenu> элемент. Атрибут 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 ответа

Решение

Мне не удалось заставить JSF прочитать определение типа свойства из подкласса. Указание collectionType атрибут не работал и даже при попытке создания @Override методы в подклассе, значение поддержки, отправляемое моему бину все еще String[] массив. Единственный способ, которым я смог заставить сервлет JSF возвращать это значение как ArrayList<String> было создать дополнительную пару методов получения / установки свойств в подклассе с 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}"/>

Это потому что getValue() возвращает параметризованный тип T который после стирания универсального типа станет Object, Другими словами, EL не видел, что он на самом деле вернул List но Object и поэтому по умолчанию будет String[],

Вам нужно явно указать collectionType атрибут в компоненте выбора с FQN требуемой реализации коллекции в качестве значения.

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

Не связанные с конкретной проблемой, <f:selectItems> также поддерживает Map<K, V>, Просто накорми это LinkedHashMap к нему напрямую, не массируя его в List<SelectItem>, Ключ карты становится значением опции, а значение карты уже становится меткой опции. Смотрите также наш selectOneMenu вики-страница

Другие вопросы по тегам