Подтвердить что ты не робот

Добавить атрибуты в модель всех контроллеров в Spring 3

Каждый вид в моем приложении Spring 3 имеет набор атрибутов, на которые они могут положиться. Итак, первая строка каждого контроллера - это что-то вроде:

ControllerHelper.addDefaultModel(model, personManager, request);

Там я добавлю

  • пользовательский объект и полное имя, полученное из базы данных, если пользователь зарегистрирован
  • набор переменных, которые обычно устанавливаются один раз (например, imagesHost)
  • набор языков, на которые посетитель может перейти на
  • текущий язык
  • некоторые статистические данные (например, общее количество людей в нашей системе)

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

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

И во-вторых, я бы ДЕЙСТВИТЕЛЬНО любил не иметь строку ControllerHelper выше, как первую строку в каждом контроллере. На самом деле это не всегда первая строка, иногда я сначала проверяю, нужно ли мне перенаправлять в этом контроллере, потому что я не хочу тратить ресурсы, заполняющие модель, без причины. Может быть, фильтр или аннотация или какой-либо механизм обратного вызова Spring мог бы удостовериться, что код ControllerHelper называется после, контроллер закончен, но правый до визуализирован вид, пропуская это, если было возвращено перенаправление?

4b9b3361

Ответ 1

Вы можете написать org.springframework.web.servlet.HandlerInterceptor. (или его удобный подкласс HandlerInterceptorAdapter)

@See: Spring Справочная глава: 15.4.1. Запросы перехвата - интерфейс HandlerInterceptor

Он имеет способ:

void postHandle(HttpServletRequest request,
                HttpServletResponse response,
                Object handler,
                ModelAndView modelAndView) throws Exception;

Этот метод вызывается после выполнения контроллера и перед визуализацией представления. Поэтому вы можете использовать его, чтобы добавить некоторые свойства в ModelMap

Пример:

/**
 * Add the current version under name {@link #VERSION_MODEL_ATTRIBUTE_NAME}
 * to each model. 
 * @author Ralph
 */
public class VersionAddingHandlerInterceptor extends HandlerInterceptorAdapter {

    /**
     * The name under which the version is added to the model map.
     */
    public static final String VERSION_MODEL_ATTRIBUTE_NAME =
                "VersionAddingHandlerInterceptor_version";

    /**        
     *  it is my personal implmentation 
     *  I wanted to demonstrate something usefull
     */
    private VersionService versionService;

    public VersionAddingHandlerInterceptor(final VersionService versionService) {
        this.versionService = versionService;
    }

    @Override
    public void postHandle(final HttpServletRequest request,
            final HttpServletResponse response, final Object handler,
            final ModelAndView modelAndView) throws Exception {

        if (modelAndView != null) {
            modelAndView.getModelMap().
                  addAttribute(VERSION_MODEL_ATTRIBUTE_NAME,
                               versionService.getVersion());
        }
    }
}

webmvc-config.xml

<mvc:interceptors>
    <bean class="demo.VersionAddingHandlerInterceptor" autowire="constructor" />
</mvc:interceptors>

Ответ 2

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

@ModelAttribute("version")
public String getVersion() {
   return versionService.getVersion();
}

Это добавит его для всех сопоставлений запросов в контроллере. Если вы поместите это в суперкласс, он может быть доступен для всех контроллеров, которые его расширяют.

Ответ 3

Вы можете использовать класс контроллера, аннотированный с помощью @ControllerAdvice

"@ControllerAdvice был введен в 3.2 для методов @ExceptionHandler, @ModelAttribute и @InitBinder, общих для всех или подмножества контроллеров."

для получения некоторой информации об этом просмотрите эту часть видео, записанную во время SpringOne2GX 2014 http://www.youtube.com/watch?v=yxKJsgNYDQI&t=6m33s

Ответ 4

Существует одна проблема, возникающая при перенаправлении при использовании подхода @ModelAttribute или HandlerInterceptor. Когда обработчик возвращает представление "Перенаправление", атрибуты модели, добавленные таким образом, добавляются в качестве параметров запроса.

Другим способом справиться с этой ситуацией является создание bean с сессионным ограничением, которое может быть автоматически добавлено в базовый контроллер приложения или явно в каждом контроллере, где необходим доступ.

Подробные сведения о доступных областях и использовании можно найти здесь.

Ответ 5

если вам нужно добавить некоторые глобальные переменные, которые каждое представление может разрешить эти переменные, почему бы не определить свойства или карту? затем используйте spring DI, обратитесь к распознавателю вида bean. он очень полезен, например, статический, например, resUrl

<property name="viewResolvers">
        <list>
            <bean
        class="org.springframework.web.servlet.view.InternalResourceViewResolver">
                <property name="viewClass"
                    value="org.springframework.web.servlet.view.JstlView" />
                <property name="attributes" ref="env" />
                <property name="exposeContextBeansAsAttributes" value="false" />
                <property name="prefix" value="${webmvc.view.prefix}" />
                <property name="suffix" value="${webmvc.view.suffix}" />
            </bean>
        </list>
    </property>