我正在尝试编辑产品。表单支持对象非常简单:
private Integer productId;
private String name;
private Double price;
private List<Integer> relatedProductList; //list of related product ids
...//getters/setter
导致问题的部分是relatedProductList。我正在尝试将列表放在帖子上以将其显示在子请求页面上。我尝试在我的 jsp 中使用这样的隐藏字段:
<form:hidden path="relatedProductList"/>
正如您所期望的那样,隐藏字段在 html 中显示得很好:
<input id="relatedProductList" name="relatedProductList" type="hidden" value="[200408, 200417]"/>
使用 firebug 后的数据看起来不错:
relatedProductList [200408, 200417]
但是在我的 Controller 中,表单支持对象的产品列表为空??
@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 ;
}
** 但是 form.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
突然之间 form.getRelatedProductList() 现在被正确填充。
有谁知道为什么在使用 springs form:hidden 标签时,post data contractList [200408, 200417] 没有正确绑定(bind)到表单?这是错误还是预期的行为。对我来说似乎很奇怪只是想把它扔在那里,看看我是否做错了,或者它是否可以帮助其他人。
谢谢。
最佳答案
我知道这是旧的,但让我简要回答一下:
您在生成的 HTML relatedProductList [200408, 200417]
中观察到的 <input id="relatedProductList" name="relatedProductList" type="hidden" value="[200408, 200417]"/>
只是 relatedProductList.toString()
的值,它反过来使用 java.util.AbstractCollection
的默认实现。格式如下: [..., ..., ...]
。 Spring MVC 使用 toString() 方法来获取表单输入字段的表示,这非常简单:它需要一个普通字符串。
这并不能保证以后能够解析相同的字符串。显然,如果不能,它只是将变量绑定(bind)到 null。
你后来所做的(直接使用 <input type="hidden">
)实际上更像是一种黑客行为,但我习惯于在使用 Spring MVC 时有时不得不做这样的事情,因为在功能上存在一些差距。
一般来说,如果有多个同名的表单域,它们都会被嵌入到 POST 数据中。如果您检查 POST 数据字符串,您会在那里找到类似 relatedProductList=200408&relatedProductList=200417
的内容。现在,当 Spring MVC 在解析 POST 数据时发现这种情况时,它会尝试将其映射到手头的目标变量。如果该目标变量是 java.util.Collection
(如您的情况),它使用来自 POST 数据的值作为集合元素,这非常直观。
再举一个例子,如果目标变量的类型是 String
,它会像这样填充它: "200408,200417"
。
关于spring-mvc - Spring 绑定(bind)集合以形成带有隐藏字段的表单,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/8435414/