Spring 3 ошибочно связывает данные запроса со всеми атрибутами модели - PullRequest
0 голосов
/ 10 июля 2011

У меня есть страница, которая представляет некоторые данные. Подзаголованные поля содержат параметр ID.

<form:form modelAttribute="command" action="info.html">
  <form:input path="id"/>
  ...
</form:form>

Мой командный объект - это POJO с таким полем id:

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. Например, боб вроде:

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()
}

Почему это и как я могу это остановить?

Я хочу, чтобы только моя команда была связана с данными, представленными в запросе, а не с каждой моделью, которая имеет имена свойств, совпадающие с тем, что содержится в запросе.

1 Ответ

1 голос
/ 10 июля 2011

Вы, похоже, смешиваете два разных варианта использования аннотации @ModelAttribute.

Когда это используется для аннотирования параметров аннотированного метода @RequestMapping, эта аннотация будет привязывать параметры запроса каргумент аннотированного метода (в вашем случае он свяжет применимые параметры запроса с обоими вашими объектами).

С другой стороны, если вы хотите представить некоторые данные представлению как атрибут модели, достаточно аннотироватьметод доступа вашего FooBar экземпляра с @ModelAttribute, как вы уже сделали.Но вам не нужно (и не следует) включать FooBar в параметры метода обработки запросов, так как этот тип @ModelAttribute относится к входящих , а не исходящих атрибутов модели.

JavaDoc для @ModelAttribute делает различие совершенно ясным:

Может использоваться для предоставления объектов команд веб-представлению с использованием определенных имен атрибутов черезаннотирование соответствующих параметров аннотированного метода-обработчика RequestMapping).

Может также использоваться для предоставления справочных данных веб-представлению посредством аннотирования методов доступа в классе контроллера, который основан на аннотированных методах-обработчиках RequestMapping, с такими методами доступаразрешено иметь любые аргументы, которые RequestMapping поддерживает для методов-обработчиков, возвращая значение атрибута модели для предоставления.

...