Ошибки с set_add и set_contains

Аннотации @ModelAttribute в этом случае используются для идентификации объекта, который Spring должен добавить в качестве атрибута модели. Атрибуты модели - это абстракция от атрибутов HttpServletRequest. В основном, это объекты, определенные некоторым ключом, которые найдут свой путь в атрибутах HttpServletRequest. Вы можете сделать это, вручную добавив атрибут с Model#addAttribute(String, Object), иметь аннотированный метод @ModelAttribute или аннотировать параметр метода с помощью @ModelAttribute.

То, что вам нужно понять, - это то, как Spring решает параметры метода обработчика и вводить аргументы. Для этого используется интерфейс HandlerMethodArgumentResolver . Существует несколько классов реализации (см. Javadoc), и каждый из них несет ответственность за resolveArgument(), возвращая аргумент, который Spring будет использовать для invoke() метода вашего обработчика посредством отражения. Spring будет вызывать только метод resolveArgument(), если метод HandlerMethodArgumentResolver supportsParameter() возвращает true для конкретного параметра.

Реализация HandlerMethodArgumentResolver, о которой идет речь, - ServletModelAttributeMethodProcessor , которая продолжается от ModelAttributeMethodProcessor , которая гласит

Разрешает аргументы метода, аннотированные с помощью @ModelAttribute, и обрабатывает возвращаемые значения из методов, аннотированных с помощью @ModelAttribute.

blockquote>

Spring (3.2) будет зарегистрировать этот HandlerMethodArgumentResolver и другие

private List getDefaultArgumentResolvers() {
        List resolvers = new ArrayList();

    // Annotation-based argument resolution
    resolvers.add(new RequestParamMethodArgumentResolver(getBeanFactory(), false));
    resolvers.add(new RequestParamMapMethodArgumentResolver());
    resolvers.add(new PathVariableMethodArgumentResolver());
    resolvers.add(new ServletModelAttributeMethodProcessor(false));
    resolvers.add(new RequestResponseBodyMethodProcessor(getMessageConverters()));
    resolvers.add(new RequestPartMethodArgumentResolver(getMessageConverters()));
    resolvers.add(new RequestHeaderMethodArgumentResolver(getBeanFactory()));
    resolvers.add(new RequestHeaderMapMethodArgumentResolver());
    resolvers.add(new ServletCookieValueMethodArgumentResolver(getBeanFactory()));
    resolvers.add(new ExpressionValueMethodArgumentResolver(getBeanFactory()));

    // Type-based argument resolution
    resolvers.add(new ServletRequestMethodArgumentResolver());
    resolvers.add(new ServletResponseMethodArgumentResolver());
    resolvers.add(new HttpEntityMethodProcessor(getMessageConverters()));
    resolvers.add(new RedirectAttributesMethodArgumentResolver());
    resolvers.add(new ModelMethodProcessor());
    resolvers.add(new MapMethodProcessor());
    resolvers.add(new ErrorsMethodArgumentResolver());
    resolvers.add(new SessionStatusMethodArgumentResolver());
    resolvers.add(new UriComponentsBuilderMethodArgumentResolver());

    // Custom arguments
    if (getCustomArgumentResolvers() != null) {
        resolvers.addAll(getCustomArgumentResolvers());
    }

    // Catch-all
    resolvers.add(new RequestParamMethodArgumentResolver(getBeanFactory(), true));
    resolvers.add(new ServletModelAttributeMethodProcessor(true));

    return resolvers;
}

Когда Spring нужно вызвать метод обработчика, он будет перебирать типы параметров и через приведенный выше список и использовать первый, который supportsParameter().

Обратите внимание, что добавляются два экземпляра ServletModelAttributeMethodProcessor (один после комментария //catch all). Поле ModelAttributeMethodProcessor имеет поле annotationNotRequired, в котором говорится, что он должен искать @ModelAttribute или нет. Первый экземпляр должен искать @ModelAttribute, второй - нет. Spring делает это так, что вы можете зарегистрировать свои собственные экземпляры HandlerMethodArgumentResolver, см. Комментарий // Custom arguments.


В частности

@RequestMapping(value = "/", method = RequestMethod.POST)
public String sayHello(Person person, Model model) {
    model.addAttribute("person", person);
    return "home";
}

В этом случае не имеет значения, аннотирован ли ваш параметр Person или нет. A ModelAttributeMethodProcessor разрешит его и свяжет поля формы, т. Е. параметры запроса, в поля экземпляра. Вам не нужно даже добавлять его к model, поскольку класс ModelAttributeMethodProcessor будет обрабатывать это.

В вашем методе showHelloPage()

model.addAttribute("person", new Person());

необходимо использовать

taglib. Вот как он разрешает свои поля input.


Итак, мой вопрос: в чем заключается использование anonnatation ModelAttribute?

blockquote>

Чтобы автоматически добавить указанный параметр (или возвращаемое значение метода) в модель.

Можно ли опустить атрибут «modelAttribute» в форме?

blockquote>

Нет, привязка form ищет объект в Model и связывает его поля с элементами html input.

И вторая часть, каков способ (возможно, аннотация) для создания формы, автоматически связывает значения входов с собственными свойствами bean (которые будут объявлены как параметр метода)? Без необходимости добавления пустого компонента перед отправкой формы (как я должен сделать это сейчас).

blockquote>

Тег Spring защелкивается на объект атрибута модели и использует его поля для создайте элементы input и label. Неважно, как объект оказался в модели до тех пор, пока он это сделал. Если он не может найти атрибут модели с указанным вами именем (ключом), он выдает исключения, как вы видели.

 

Альтернативой предоставлению пустого компонента является создание html самостоятельно. Вся команда Spring использует имена полей bean для создания элемента input. Таким образом, это


    First name
    

Создает что-то вроде


    

Spring связывает параметры запроса с полями экземпляра, используя атрибут name.

0
задан IndentationFaulter 26 February 2015 в 13:20
поделиться