Spring 3 在所有模型属性上错误地绑定请求数据
我有一个提交一些数据的页面。提交的字段包含 ID 参数。
<form:form modelAttribute="command" action="info.html">
<form:input path="id"/>
...
</form:form>
我的 comand 对象是一个具有这样一个 id 字段的 POJO:
public class MyCommand {
private Integer id;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
....
}
这在控制器中注释如下:
@ModelAttribute("command")
public MyCommand initializeCommand() {
return new MyCommand(...);
}
虽然我的处理程序方法看起来像这样:
public void handle(@ModelAttribute("command") MyCommand cmd, ...)
当我提交表单时,Spring 将参数绑定到命令目的。但它还将参数绑定到模型中找到的每个具有 id 属性的对象(所有模型属性)。例如,像这样的 bean:
public class FooBar {
private Integer id;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
....
}
设置如下:
@ModelAttribute("fooBar")
public FooBar initializeFooBar() {
return new FooBar(...);
}
在我的处理程序方法中(我按如下方式修改该方法)时,绑定发生在两个模型属性(cmd
和 fooBar
)上:
public void handle(@ModelAttribute("command") MyCommand cmd,
@ModelAttribute("fooBar") FooBar fooBar, ...) {
// when i submit my form the following values are equal:
// fooBar.getId() is the same as cmd.getId()
}
这是为什么?我该如何阻止它?
我只希望我的命令与请求提交的数据绑定,而不是每个具有与请求中的内容匹配的属性名称的模型。
I have a page which submits some data. The submited fields include an ID parameter.
<form:form modelAttribute="command" action="info.html">
<form:input path="id"/>
...
</form:form>
My comand object is a POJO with such an id
field:
public class MyCommand {
private Integer id;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
....
}
This is annotated in the controller like this:
@ModelAttribute("command")
public MyCommand initializeCommand() {
return new MyCommand(...);
}
While my handler method looks something like this:
public void handle(@ModelAttribute("command") MyCommand cmd, ...)
When I submit the form, Spring binds the parameters to the command object. But it also binds the parameters to every object found in the model (to all model attributes) that has an id
property. For example, a bean like:
public class FooBar {
private Integer id;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
....
}
set up like:
@ModelAttribute("fooBar")
public FooBar initializeFooBar() {
return new FooBar(...);
}
When in my handler method, which I modify like the following, the binding occurs on both model attributes (cmd
and fooBar
):
public void handle(@ModelAttribute("command") MyCommand cmd,
@ModelAttribute("fooBar") FooBar fooBar, ...) {
// when i submit my form the following values are equal:
// fooBar.getId() is the same as cmd.getId()
}
Why is this and how can I stop it?
I want only my command to be binded with the request submited data, not every model that has matching property names with what comes on the request.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您似乎混合了 @ModelAttribute 注释的两个不同用例。
当它用于注释
@RequestMapping
带注释的方法的参数时,此注释会将请求参数绑定到带注释的方法参数(在您的情况下,它将把适用的请求参数绑定到您的两个对象)。另一方面,如果您想将一些数据作为模型属性公开给视图,只需使用
@ModelAttribute
注释FooBar
实例的访问器方法就足够了,因为您已经这样做了。但是您不需要(也不应该)在请求处理方法参数中包含FooBar
,因为该类型的@ModelAttribute
引用传入并且不是传出模型属性。JavaDoc < code>@ModelAttribute 使区别非常清楚:
You seem to be mixing the two distinct use-cases of the
@ModelAttribute
annotation.When it's used to annotate parameters of a
@RequestMapping
annotated method, this annotation will bind the request parameters to the annotated method argument (in your case, it will bind the applicable request parameters to both your objects).On the other hand, if you want to expose some data to the view as model attribute, it's enough to annotate the accessor method of your
FooBar
instance with@ModelAttribute
, as you already did. But you need not (and shouldn't) includeFooBar
among the request handling method parameters, as that type of@ModelAttribute
refers to incoming and not outgoing model attributes.The JavaDoc for
@ModelAttribute
makes the distinction quite clear: