Java 如何将集合属性绑定到 Spring MVC 中的表单
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/284368/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I bind collection attributes to a form in Spring MVC
提问by agnul
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 unordered collection. Doing something like
我正在尝试使用 Spring-MVC 将我的模型对象之一绑定到表单的字段。一切正常,除了模型对象的一个属性是无序集合。做类似的事情
<c:forEach items="${m.items}" var="i" varStatus="itemsRow">
<form:input path="items[${itemsRow.index}]"/>
</c:forEach>
<form:errors path="items" />
would work fine for a List-type property, but for a Set throws an error when, upon submit, it tries to bind input field content to object attributes.
对于 List 类型的属性可以正常工作,但是对于 Set 在提交时尝试将输入字段内容绑定到对象属性时会引发错误。
Is there something in Spring that works out of the box with Sets?
Spring 中是否有一些可以与 Sets 一起开箱即用的东西?
回答by Jacob Mattison
I think it has to be an ordered collection. For example,there's a chartin the Spring reference that talks about how to reference properties. It says:
我认为它必须是一个有序的集合。例如,Spring 参考中有一个图表,讲的是如何引用属性。它说:
account[2] Indicates the third element of the indexed property account. Indexed properties can be of type array, list or other naturally orderedcollection (emphasis theirs)
account[2] 指示索引属性帐户的第三个元素。索引属性可以是数组、列表或其他自然排序的集合类型(强调他们的)
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.
也许一种方法是向您的对象添加一个 getter,而不是返回您的 Set,而是返回 Set.toArray()。然后您的 items 属性将引用该数组。当然,您不能依赖于顺序。
回答by zmf
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" />
回答by zmf
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.
我认为它不适用于 Set 的原因是因为无法保证 Set 的顺序。当您尝试绑定到发布的第一个对象时,它可能不是该列表中要渲染的第一个对象。例如,GET 和 POST 之间的 items[0] 可能不同。
So it should work fine if you use an implementation of Set that is ordered, such as a SortedSet or TreeSet.
因此,如果您使用有序的 Set 实现,例如 SortedSet 或 TreeSet,它应该可以正常工作。
回答by Alex Marshall
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.
您可以尝试编写自己的自定义编辑器来完成这项工作,然后将编辑器注册到表单的控制器中。您不必费心以这种方式对 Set 中的元素进行索引。并且如前所述,如果有一种对元素进行排序的方法,您可以使用 SortedSet 确保它们在集合中的顺序。
回答by Deejay
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.
如果您使用对对象 ID 的数字引用,并且注册了适当的 Converter 实现,则可以使用分号分隔的列表。
POST data leaderboards=1,2
POST 数据排行榜=1,2
Converter implementation (ignore the JSON stuff)
转换器实现(忽略 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());
}
}
回答by sab
found perfect solution here: http://forum.springsource.org/showthread.php?45312-Submitting-arrays
在这里找到了完美的解决方案:http: //forum.springsource.org/showthread.php?45312-Submitting-arrays
general idea - using commons-collections methods to init list:
一般想法 - 使用 commons-collections 方法来初始化列表:
private List someList = LazyList.decorate(new ArrayList(), FactoryUtils.instantiateFactory(com.abc.xyz.SomeClass.class));