【问题标题】:How do I bind collection attributes to a form in Spring MVC如何将集合属性绑定到 Spring MVC 中的表单
【发布时间】:2010-09-22 00:18:05
【问题描述】:

我正在尝试使用 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 中有什么东西可以与 Sets 开箱即用吗?

【问题讨论】:

  • 我第一次看错了问题,不熟悉使用这样的路径属性。
  • 嘿!不要看我,我只是因为在一些随机的谷歌搜索中发现了它。我正在通过反复试验来学习 spring ;-)

标签: java spring jakarta-ee spring-mvc


【解决方案1】:

我认为它必须是一个有序的集合。例如,Spring 参考中有a chart 讨论如何引用属性。它说:

account[2] 表示第三个元素 指数化的财产账户。 索引属性可以是类型 数组、列表或其他自然排序 收藏(强调他们的)

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

【讨论】:

  • 我可以在模型对象周围使用装饰器...看起来是个好主意。
【解决方案2】:

我认为它不适用于 Set 的原因是因为不能保证 Set 的顺序。当您尝试绑定到 post 上的第一个对象时,它可能不是该列表中要渲染的第一个对象。例如,GET 和 POST 之间的 items[0] 可能不相同。

因此,如果您使用有序的 Set 实现,例如 SortedSet 或 TreeSet,它应该可以正常工作。

【讨论】:

  • 刚刚试了一下。 SortedSet 是一个接口,因此您不能使用它,而且 TreeSet 似乎无法解决问题。
  • 我刚刚遇到了同样的问题,发现了这个问题,将我的表单元素更改为 TreeSet,它可以工作了!感谢您为我节省了大量时间!
【解决方案3】:

在这里找到了完美的解决方案: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));

【讨论】:

    【解决方案4】:

    我不清楚这究竟是如何绑定的,但它适用于我的目的。

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

    【讨论】:

    【解决方案5】:

    您可以尝试编写自己的自定义编辑器来完成这项工作,然后将编辑器注册到表单的控制器。您不必费心以这种方式索引 Set 中的元素。如前所述,如果有一种对元素进行排序的方法,您可以使用 SortedSet 确保它们在集合中的顺序。

    【讨论】:

      【解决方案6】:

      如果您使用对对象 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());
              }
      
      }
      

      【讨论】:

        猜你喜欢
        • 2012-06-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-03-30
        • 2020-11-21
        相关资源
        最近更新 更多