Spring 3 在所有模型属性上错误地绑定请求数据

发布于 2024-11-19 05:35:24 字数 1531 浏览 2 评论 0原文

我有一个提交一些数据的页面。提交的字段包含 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(...); 
}

在我的处理程序方法中(我按如下方式修改该方法)时,绑定发生在两个模型属性(cmdfooBar)上:

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 技术交流群。

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

发布评论

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

评论(1

萌无敌 2024-11-26 05:35:24

您似乎混合了 @ModelAttribute 注释的两个不同用例。

当它用于注释 @RequestMapping 带注释的方法的参数时,此注释会将请求参数绑定到带注释的方法参数(在您的情况下,它将把适用的请求参数绑定到您的两个对象)。

另一方面,如果您想将一些数据作为模型属性公开给视图,只需使用 @ModelAttribute 注释 FooBar 实例的访问器方法就足够了,因为您已经这样做了。但是您不需要(也不应该)在请求处理方法参数中包含 FooBar,因为该类型的 @ModelAttribute 引用传入并且不是传出模型属性。

JavaDoc < code>@ModelAttribute 使区别非常清楚:

可用于将命令对象公开到 Web 视图,使用特定的属性名称,通过注释 RequestMapping 带注释的处理程序方法的相应参数)。

还可以用于通过在控制器类中注释访问器方法来将引用数据公开到 Web 视图,该控制器类基于 RequestMapping 带注释的处理程序方法,此类访问器方法允许具有 RequestMapping 支持的处理程序方法的任何参数,返回要公开的模型属性值。

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) include FooBar 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:

Can be used to expose command objects to a web view, using specific attribute names, through annotating corresponding parameters of a RequestMapping annotated handler method).

Can also be used to expose reference data to a web view through annotating accessor methods in a controller class which is based on RequestMapping annotated handler methods, with such accessor methods allowed to have any arguments that RequestMapping supports for handler methods, returning the model attribute value to expose.

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