Spring 绑定集合以形成带有隐藏字段的形式

发布于 2024-12-20 15:11:06 字数 2660 浏览 2 评论 0 原文

我正在尝试编辑产品。表单支持对象非常简单:

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]

但在我的控制器中,表单支持对象有一个空产品列表?

@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 标签时,发布数据contractList [200408, 200417] 没有正确绑定到表单?这是一个错误还是预期的行为。对我来说似乎很奇怪,只是想把它扔在那里,看看我是否做错了,或者它是否可以帮助其他人。

谢谢。

I'm trying to edit a product. The form backing object is pretty simple:

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

...//getters/setter

The part causing the problem is the relatedProductList. I'm trying to put the list on post to display it on a subsequest page. I tried using a hidden field like this in my jsp:

<form:hidden path="relatedProductList"/>

The hidden field appears nicely in the html as you would expect:

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

The post data looks good using firebug:

relatedProductList    [200408, 200417]

But in my controller the form backing object has a null product list??

@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 ;
}

** But the form.getRelatedProductList is null!

I can get around the problem by using a hidden field and setting the value in the jsp, in the loop that shows the related products:

        <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>

This produces the following html:

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

Which seems fine and produces the following post:

relatedProductList    200408
relatedProductList    200417

And suddenly the form.getRelatedProductList() is now populated correctly.

Does anyone know why the post data contractList [200408, 200417] doesn't get bound to the form correctly when using springs form:hidden tag? Is this a bug or the expected behaviour. Seems very strange to me just wanted to throw it out there and see if I'm doing it wrong perhaps, or if it can help anyone else.

Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

濫情▎り 2024-12-27 15:11:06

我知道这已经过时了,但让我简单地回答一下:

您在生成的 HTML latedProductList [200408, 200417] ="hidden" value="[200408, 200417]"/> 只是 latedProductList.toString() 的值,其中依次使用 java.util.AbstractCollection 中的默认实现。格式如下:[..., ..., ...]。 Spring MVC 使用 toString() 方法来获取表单输入字段的表示,这非常简单:它需要一个纯字符串。

这并不能保证它以后能够解析相同的字符串。显然,如果不能,它只是将变量绑定为 null。

你后来所做的(直接使用 )实际上更像是一种 hack,但我习惯了在使用 Spring MVC 时有时不得不做这样的事情,因为有功能上的一些差距。

一般来说,如果有多个同名的表单字段,它们都会嵌入到 POST 数据中。如果检查 POST 数据字符串,您会发现类似 latedProductList=200408&latedProductList=200417 的内容。现在,当 Spring MVC 在解析 POST 数据时发现这种情况时,它会尝试将其映射到手头的目标变量。如果该目标变量是 java.util.Collection(如您的情况),它会使用 POST 数据中的值作为集合元素,这非常直观。

再举一个例子,如果目标变量的类型为String,它将按如下方式填充:"200408,200417"

I know this is old, but let me briefly answer it:

The relatedProductList [200408, 200417] you observed in the generated HTML <input id="relatedProductList" name="relatedProductList" type="hidden" value="[200408, 200417]"/> is simply the value of relatedProductList.toString(), which in turn uses the default implementation from java.util.AbstractCollection. The format is like this: [..., ..., ...]. Spring MVC uses the toString() method for getting a representation for a form input field, which is quite straight forward: It needs a plain string.

This does not guarantee that it's able to parse that same string later. Obviously, if it can't, it just binds the variable to null.

What you later did (using <input type="hidden"> directly) was actually more a hack, but I'm used to having to do such things sometimes when using Spring MVC since there are some gaps in the functionality.

In general, if there are several form fields with the same name, they all get embedded in the POST data. If you check the POST data string, you'll find something like relatedProductList=200408&relatedProductList=200417 there. Now, when Spring MVC discovers this case while parsing the POST data, it tries to map this to the target variable at hand. If that target variable is a java.util.Collection (as in your case), it uses the values from the POST data as collection elements, which is quite intuitive.

If, just to give another example, the target variable is of type String, it will populate it like this: "200408,200417".

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文