如何在Spring MVC中将集合属性绑定到表单?

17

我正在尝试使用Spring-MVC将我的一个模型对象绑定到表单的字段上。除了模型对象的其中一个属性是无序集合之外,其他都运行良好。类似下面这样的操作:

    <c:forEach items="${m.items}" var="i" varStatus="itemsRow">
      <form:input path="items[${itemsRow.index}]"/>
    </c:forEach>
    <form:errors path="items" />

对于列表类型的属性,这将运行良好;但是对于集合类型,当它尝试将输入字段内容绑定到对象属性时,提交时会抛出错误。

在Spring中是否有适用于Set的开箱即用解决方案?


我第一次误读了问题,并不熟悉如何使用路径属性。 - zmf
嘿!别看我,我只是因为在一些随机的谷歌搜索中发现了它才尝试过。我正在通过试错学习Spring ;-) - agnul
6个回答

5
我认为它必须是一个有序的集合。例如,在Spring参考文档中有一张图表,介绍如何引用属性。其中说到:

account[2]表示索引属性account中的第三个元素。索引属性可以是数组、列表或其他自然有序的集合(强调他们的)。

也许一种方法是在您的对象中添加一个getter方法,该方法不返回Set,而是返回Set.toArray()。然后,您的items属性将引用该数组。当然,您不能依赖于顺序。

1
我可以在模型对象周围使用一个装饰器...看起来是个好主意。 - agnul

4
我认为它不能与Set一起使用的原因是因为Set的顺序不被保证。当您尝试在提交时绑定到第一个对象时,它可能不是渲染出的列表中的第一个对象。例如,items [0] 可能在GET和POST之间不同。
因此,如果您使用有序的Set实现,例如SortedSet或TreeSet,它应该可以正常工作。

刚试了一下。SortedSet是一个接口,所以你不能用它,而TreeSet似乎也无法解决这个问题。 - James McMahon
我之前也遇到了同样的问题,看到了这个问题,把我的表单元素改成了TreeSet,现在它可以正常工作了!感谢你节省了我很多时间! - nont

2

1
你可以尝试编写自己的自定义编辑器来完成这项工作,然后将编辑器注册到表单控制器中。这样就不必通过索引集合中的元素了。另外,如果有一种排序元素的方法,你可以使用SortedSet来确保它们在集合中的顺序。

1

我并不十分清楚这个绑定是如何实现的,但它对我的目的来说是有效的。

 <c:forEach items="${items}" var="i" varStatus="itemsRow">
        <input name="items[${itemsRow.index}].fieldName" type="text"/>
    </c:forEach>
 <form:errors path="items" />

这种行为的原因在这里解释:http://viralpatel.net/blogs/spring-mvc-multi-row-submit-java-list/ - Alex

-1

如果您正在使用对象ID的数字引用,并且已注册适当的转换器实现,则可以使用分号分隔的列表。

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());
        }

}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接