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

1. Вступление

В этом руководстве мы сосредоточимся на __HandlerInterceptor Spring MVC. Более конкретно, мы изменим параметры модели Spring MVC до и после обработки запроса.

Если вы хотите прочитать об основах HandlerInterceptor , проверьте эту ссылку:/spring-mvc-handlerinterceptor[article]

2. Зависимости Maven

Чтобы использовать Interceptors , вам нужно включить следующий раздел в раздел dependencies вашего pom.xml файла:

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-web</artifactId>
    <version>5.0.6.RELEASE</version>
</dependency>

Последнюю версию можно найти по адресу here .

Эта зависимость распространяется только на Spring Web, поэтому не забудьте добавить s _pring-core и spring-context_ для полного веб-приложения и библиотеку журналов на ваш выбор.

3. Индивидуальная реализация

Одним из вариантов использования HandlerInterceptor является добавление общих/пользовательских параметров в модель, которые будут доступны в каждом сгенерированном представлении.

В нашем примере мы будем использовать собственную реализацию перехватчика для добавления имени пользователя зарегистрированного пользователя к параметрам модели. В более сложных системах мы можем добавить более конкретную информацию, например: путь аватара пользователя, местоположение пользователя и т. Д.

Давайте начнем с определения нашего нового класса Interceptor :

public class UserInterceptor extends HandlerInterceptorAdapter {

    private static Logger log = LoggerFactory.getLogger(UserInterceptor.class);

    ...
}

Мы расширяем HandlerInterceptorAdapter , так как мы хотим реализовать только методы preHandle () и postHandle () .

Как мы упоминали ранее, мы хотим добавить имя зарегистрированного пользователя в модель.

Прежде всего, нам нужно проверить, вошел ли пользователь в систему. Мы можем получить эту информацию, проверив SecurityContextHolder :

public static boolean isUserLogged() {
    try {
        return !SecurityContextHolder.getContext().getAuthentication()
          .getName().equals("anonymousUser");
    } catch (Exception e) {
        return false;
    }
}

Когда установлена ​​ HttpSession , но никто не вошел в систему, имя пользователя в контексте Spring Security равно anonymousUser . Далее мы приступаем к реализации preHandle ():

3.1. Метод preHandle ()

Перед обработкой запроса мы не можем получить доступ к параметрам модели. Чтобы добавить имя пользователя, нам нужно использовать HttpSession для установки параметров:

@Override
public boolean preHandle(HttpServletRequest request,
  HttpServletResponse response, Object object) throws Exception {
    if (isUserLogged()) {
        addToModelUserDetails(request.getSession());
    }
    return true;
}

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

private void addToModelUserDetails(HttpSession session) {
    log.info("=============== addToModelUserDetails =========================");

    String loggedUsername
      = SecurityContextHolder.getContext().getAuthentication().getName();
    session.setAttribute("username", loggedUsername);

    log.info("user(" + loggedUsername + ") session : " + session);
    log.info("=============== addToModelUserDetails =========================");
}

Мы использовали SecurityContextHolder для получения loggedUsername . Вы можете переопределить реализацию UserDetails Spring Security для получения электронной почты вместо стандартного имени пользователя.

3.2. Метод p _ostHandle () _

После обработки запроса наши параметры модели становятся доступными, поэтому мы можем получить к ним доступ, чтобы изменить значения или добавить новые. Для этого мы используем переопределенный метод postHandle () :

@Override
public void postHandle(
  HttpServletRequest req,
  HttpServletResponse res,
  Object o,
  ModelAndView model) throws Exception {

    if (model != null && !isRedirectView(model)) {
        if (isUserLogged()) {
        addToModelUserDetails(model);
    }
    }
}

Давайте посмотрим на детали реализации.

Прежде всего, лучше проверить, не является ли модель null. Это предотвратит возникновение NullPointerException .

Кроме того, мы можем проверить, не является ли View экземпляром Redirect _View . _

Нет необходимости добавлять/изменять параметры после обработки запроса и его перенаправления, так как немедленно новый контроллер снова выполнит обработку. Чтобы проверить, перенаправлено ли представление, мы вводим следующий метод:

public static boolean isRedirectView(ModelAndView mv) {
    String viewName = mv.getViewName();
    if (viewName.startsWith("redirect:/")) {
        return true;
    }
    View view = mv.getView();
    return (view != null && view instanceof SmartView
      && ((SmartView) view).isRedirectView());
}

Наконец, мы снова проверяем, вошел ли пользователь в систему, и если да, мы добавляем параметры в модель Spring:

private void addToModelUserDetails(ModelAndView model) {
    log.info("=============== addToModelUserDetails =========================");

    String loggedUsername = SecurityContextHolder.getContext()
      .getAuthentication().getName();
    model.addObject("loggedUsername", loggedUsername);

    log.trace("session : " + model.getModel());
    log.info("=============== addToModelUserDetails =========================");
}

Обратите внимание, что ведение журнала очень важно, так как эта логика работает «за кулисами» нашего приложения. Легко забыть, что мы изменяем некоторые параметры модели для каждого View , не регистрируя его должным образом.

4. Конфигурация

Чтобы добавить наш недавно созданный Interceptor в конфигурацию Spring, нам нужно переопределить метод addInterceptors () внутри класса WebConfig , который реализует WebMvcConfigurer:

@Override
public void addInterceptors(InterceptorRegistry registry) {
    registry.addInterceptor(new UserInterceptor());
}

Мы можем добиться той же конфигурации, отредактировав наш файл конфигурации XML Spring:

<mvc:interceptors>
    <bean id="userInterceptor" class="org.baeldung.web.interceptor.UserInterceptor"/>
</mvc:interceptors>

С этого момента мы можем получить доступ ко всем пользовательским параметрам во всех сгенерированных представлениях.

Обратите внимание: если настроено несколько Spring Interceptors , метод preHandle () выполняется в порядке конфигурации, тогда как методы postHandle () и afterCompletion () вызываются в обратном порядке.

5. Заключение

В этом руководстве представлено перехват веб-запросов с использованием HandlerInterceptor Spring MVC для предоставления информации о пользователях.

В этом конкретном примере мы сконцентрировались на добавлении сведений о зарегистрированном пользователе в нашем веб-приложении к параметрам модели. Вы можете расширить эту реализацию HandlerInterceptor , добавив более подробную информацию.

Все примеры и конфигурации доступны здесь по адресу GitHub .

5.1. Статьи в серии

Все статьи серии:

  • ссылка:/spring-mvc-handlerinterceptor[Введение в Spring MVC Handler

Перехватчики]** Изменение параметров модели пружины с помощью перехватчика обработчика (этот)