Почему 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
вики-страница