Как связать атрибуты коллекции с формой в Spring MVC
Я пытаюсь привязать один из моих объектов модели к полям формы, используя Spring -MVC. Все работает отлично, за исключением того, что один из атрибутов объекта модели является неупорядоченной коллекцией. Выполнение чего-то типа
<c:forEach items="${m.items}" var="i" varStatus="itemsRow">
<form:input path="items[${itemsRow.index}]"/>
</c:forEach>
<form:errors path="items" />
будет отлично работать для свойства List-type, но для Set вызывает ошибку, когда при отправке пытается связать содержимое входного поля с атрибутами объекта.
Есть ли что-то в Spring, которое работает из коробки с помощью Sets?
Ответы
Ответ 1
Я думаю, что это должна быть упорядоченная коллекция. Например, диаграмма в ссылке Spring, в которой говорится о том, как ссылаться на свойства. В нем говорится:
account [2] Указывает на третий элемент учетной записи с индексированным имуществом. Индексированные свойства могут быть типа массив, список или другие естественно упорядоченные сбор (выделение их)
Возможно, один из подходов заключался бы в том, чтобы добавить получателя к вашему объекту, который вместо возврата в Set возвращает Set.toArray(). Тогда атрибут ваших элементов будет ссылаться на массив. Конечно, вы не можете зависеть от порядка.
Ответ 2
Я думаю, причина, по которой он не работает с Set, состоит в том, что порядок набора не гарантируется. Когда вы пытаетесь привязать первый объект к сообщению, это, возможно, не первый объект в этом списке для визуализации. Например, элементы [0] могут быть не одинаковыми между GET и POST.
Поэтому он должен работать нормально, если вы используете реализацию упорядоченного Set, например SortedSet или TreeSet.
Ответ 3
найдено идеальное решение здесь: http://forum.springsource.org/showthread.php?45312-Submitting-arrays
общая идея - использование методов коллективных коллекций для списка инициализации:
private List someList = LazyList.decorate(new ArrayList(), FactoryUtils.instantiateFactory(com.abc.xyz.SomeClass.class));
Ответ 4
Я не совсем понимаю, как именно это связано, но оно работает для моих целей.
<c:forEach items="${items}" var="i" varStatus="itemsRow">
<input name="items[${itemsRow.index}].fieldName" type="text"/>
</c:forEach>
<form:errors path="items" />
Ответ 5
Вы можете попробовать написать свой собственный редактор для выполнения задания, а затем зарегистрировать редактор с помощью контроллера для формы. Вам не придется беспокоиться об индексировании элементов в наборе таким образом. Как уже упоминалось, если есть способ сортировки элементов, вы можете обеспечить их порядок в наборе с помощью SortedSet.
Ответ 6
Вы можете использовать список с разделителями с запятой, если вы используете числовые ссылки на идентификаторы объектов и зарегистрированную реализацию конвертера.
Данные POST Leaderboards = 1,2
Реализация конвертера (игнорируйте материал JSON)
public final class LeaderboardConverter extends JsonDeserializer<Leaderboard> implements Converter<String, Leaderboard>
{
public Leaderboard convert(String source) throws IllegalArgumentException
{
Leaderboard activity = new Leaderboard();
activity.setId(new Integer(source));
return activity;
}
public Leaderboard deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException
{
return convert(jp.getText());
}
}