我正在尝试使用Spring-MVC将我的一个模型对象绑定到表单的字段。一切正常,除了模型对象的一个属性是无序集合。做点什么
<c:forEach items="${m.items}" var="i" varStatus="itemsRow">
<form:input path="items[${itemsRow.index}]"/>
</c:forEach>
<form:errors path="items" />
对于List类型的属性可以正常工作,但是对于Set,在提交时会尝试将输入字段内容绑定到对象属性时抛出错误。
Spring中是否有开箱即用的功能?
答案 0 :(得分:5)
我认为它必须是一个有序的集合。例如,Spring引用中的a chart讨论了如何引用属性。它说:
account [2]表示第三个元素 索引的财产帐户。 索引属性可以是类型 数组,列表或其他自然排序 收集(强调他们的)
也许一种方法是在对象中添加一个getter,而不是返回你的Set,返回Set.toArray()。然后您的items属性将引用该数组。当然,你不能依赖订购。
答案 1 :(得分:3)
我认为它不适用于Set的原因是因为无法保证Set的顺序。当您尝试绑定到post上的第一个对象时,它可能不是该列表中要呈现的第一个对象。例如,GET和POST之间的项[0]可能不同。
因此,如果您使用已排序的Set的实现(例如SortedSet或TreeSet),它应该可以正常工作。
答案 2 :(得分:2)
在这里找到了完美的解决方案:http://forum.springsource.org/showthread.php?45312-Submitting-arrays
一般想法 - 使用commons-collections方法初始化列表:
private List someList = LazyList.decorate(new ArrayList(), FactoryUtils.instantiateFactory(com.abc.xyz.SomeClass.class));
答案 3 :(得分:1)
我不清楚这究竟是如何绑定的,但它适用于我的目的。
<c:forEach items="${items}" var="i" varStatus="itemsRow">
<input name="items[${itemsRow.index}].fieldName" type="text"/>
</c:forEach>
<form:errors path="items" />
答案 4 :(得分:1)
您可以尝试编写自己的自定义编辑器来完成工作,然后使用控制器为表单注册编辑器。您不必费心去设置Set中的元素。如前所述,如果有一种排序元素的方法,您可以使用SortedSet确保它们在集合中的顺序。
答案 5 :(得分:-1)
如果您使用对象ID的数字引用,并且注册了适当的Converter实现,则可以使用以分号分隔的列表。
POST数据 排行榜= 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());
}
}