我正在尝试编辑一个产品。窗体支持对象非常简单:
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还是预期的行为。对我来说似乎很奇怪,我只是想把它扔出去,看看我是否做错了,或者它是否能帮助其他人。
- 谢谢-谢谢
1条答案
按热度按时间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"
.