Spring MVC Spring将集合绑定到具有隐藏字段的窗体

luaexgnf  于 2022-11-14  发布在  Spring
关注(0)|答案(1)|浏览(135)

我正在尝试编辑一个产品。窗体支持对象非常简单:

private Integer           productId;
private String            name;
private Double            price;
private List<Integer>     relatedProductList;  //list of related product ids

...//getters/setter

导致问题的部分是relatedProductList。我尝试将列表放到post上,以便在后续页面上显示它。我尝试在jsp中使用这样的隐藏字段:

<form:hidden path="relatedProductList"/>

隐藏字段在html中的显示效果与预期一致:

<input id="relatedProductList" name="relatedProductList" type="hidden" value="[200408, 200417]"/>

使用Firebug后的数据看起来不错:

relatedProductList    [200408, 200417]

但是在我的控制器中,窗体支持对象的产品列表为空??

@RequestMapping(method = RequestMethod.POST, value = "/edit.do", params = "editRelatedProducts")
public ModelAndView editRelatedProducts(@Valid @ModelAttribute ProductForm form, BindingResult result) {
    if (result.hasErrors()) {    
        ModelAndView view = new ModelAndView(VIEW_PRODUCT);
        setupCreateReferenceData(view , form);
        return view ;
    }

    ModelAndView editView = new ModelAndView(VIEW_EDIT_RELATED);

    //method to lookup the product ids and place product objects on model
    editView.addObject("relatedProducts",populateProductList(form.getRelatedProductList()));

    return editView ;
}

**但表单.getRelatedProductList为空!

我可以通过使用一个隐藏字段并在jsp中设置该值来解决这个问题,在显示相关产品的循环中:

<div>
            <table id="relProductTbl" class="tablesorter">
              <thead>
                 ...
              </thead>
              <tbody>
                  <c:forEach var="prod" items="${relatedProducts}" varStatus="row">
                        <tr>
                            <input id="relatedProductList" name="relatedProductList" type="hidden" value="${prod.productId}"/>
                             ...
                        </tr>
                  </c:forEach>
              </tbody>
            </table>
        </div>

这将生成以下html:

<input id="relatedProductList" name="relatedProductList" type="hidden" value="200408"/>
...
<input id="relatedProductList" name="relatedProductList" type="hidden" value="200417"/>

这看起来很好,并产生以下帖子:

relatedProductList    200408
relatedProductList    200417

突然间,表单.getRelatedProductList()现在被正确填充。
有人知道为什么post data contractList [200408,200417]在使用springs form:hidden tag时不能正确绑定到表单吗?这是一个bug还是预期的行为。对我来说似乎很奇怪,我只是想把它扔出去,看看我是否做错了,或者它是否能帮助其他人。

  • 谢谢-谢谢
toe95027

toe950271#

我 知道 这 是 老生常谈 , 但 让 我 简要 地 回答 一下 :
您 在 生成 的 HTML <input id="relatedProductList" name="relatedProductList" type="hidden" value="[200408, 200417]"/> 中 看到 的 relatedProductList [200408, 200417] 就是 relatedProductList.toString() 的 值 , 它 使用 java.util.AbstractCollection 的 默认 实现 。SpringMVC 使用 toString ( ) 方法 来 获取 表单 输入 字段 的 表示 , 这 非常 简单 :它 需要 一 个 普通 字符 串 。
这 并 不能 保证 它 以后 能够 解析 相同 的 字符 串 , 显然 , 如果 不能 , 它 只是 将 变量 绑定 到 null 。
您 后来 所 做 的 ( 直接 使用 <input type="hidden"> ) 实际 上 更多 的 是 一 种 黑客 行为 , 但 我 已经 习惯 了 在 使用 Spring MVC 时 有时 不得 不 做 这样 的 事情 , 因为 在 功能 上 存在 一些 差距 。
一般 来说 , 如果 有 几 个 表单 字段 具有 相同 的 名称 , 它们 都会 嵌入 到 POST 数据 中 。 如果 您 检查 POST 数据 字符 串 , 您 会 发现 类似 relatedProductList=200408&relatedProductList=200417 的 内容 。 现在 , 当 SpringMVC 在 解析 POST 数据 时 发现 这种 情况 时 , 它 会 尝试 将 其 Map 到 手边 的 目标 变量 。 如果 该 目标 变量 是 java.util.Collection( 就 像 您 的 例子 一样 ) , 它 使用 POST 数据 中 的 值 作为 集合 元素 , 这 非常 直观 。
再 举 一 个 例子 , 如果 目标 变量 的 类型 是 String , 它 将 如下 填充 :"200408,200417" .

相关问题