I\'m trying to bind one of my model objects to the fields of a form, using Spring-MVC. Everything works fine, except that one of the attributes of the model object is an unorder
found perfect solution here: http://forum.springsource.org/showthread.php?45312-Submitting-arrays
general idea - using commons-collections methods to init list:
private List someList = LazyList.decorate(new ArrayList(), FactoryUtils.instantiateFactory(com.abc.xyz.SomeClass.class));
I am not crystal clear on how exactly this gets bound, but it works for my purposes.
<c:forEach items="${items}" var="i" varStatus="itemsRow">
<input name="items[${itemsRow.index}].fieldName" type="text"/>
</c:forEach>
<form:errors path="items" />
I think it has to be an ordered collection. For example,there's a chart in the Spring reference that talks about how to reference properties. It says:
account[2] Indicates the third element of the indexed property account. Indexed properties can be of type array, list or other naturally ordered collection (emphasis theirs)
Perhaps one approach would be to add a getter to your object that, rather than returning your Set, returns Set.toArray(). Then your items attribute would reference the array. Of course, you can't depend on the ordering.
I think the reason that it doesn't work with a Set is because a the order of a Set is not guaranteed. When you try to bind to the first object on post, it may not have been the first object in that list to render out. For example, items[0] may not be the same between the GET and the POST.
So it should work fine if you use an implementation of Set that is ordered, such as a SortedSet or TreeSet.
You could try writing your own custom Editor to do the job, and then registering the editor with the controller for the form. You wouldn't have to bother with indexing the elements in the Set that way. And as previously mentioned, if there's a way of sorting the elements, you could ensure their order in the set using SortedSet.
You can use a semi-colon-delimited list if you're using numeric references to the IDs of objects, and an appropriate Converter implementation registered.
POST data leaderboards=1,2
Converter implementation (ignore the JSON stuff)
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());
}
}