Использование пользовательского перехватчика обработчика Spring MVC для управления сессиями

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

В этом уроке мы сосредоточимся на Spring MVC HandlerInterceptor.

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

Если вы хотите прочитать об основах HandlerInterceptor’s в Spring, перейдите по этой ссылке:/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. Пользовательская реализация тайм-аутов сессий

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

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

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

private static final long MAX__INACTIVE__SESSION__TIME = 5 **  10000;

Мы установили 50 секунд для целей тестирования; не забывайте, это считается в мс.

Теперь нам нужно отслеживать каждую сессию в нашем приложении, поэтому нам нужно включить этот Spring Interface:

@Autowired
private HttpSession session;

Давайте продолжим с методом preHandle () .

3.1. preHandle ()

В этот метод мы включим следующие операции:

  • установка таймеров для проверки времени обработки запросов

  • проверка, вошел ли пользователь в систему (используя метод UserInterceptor из

эта ссылка:/spring-model-parameters-with-handler-interceptor[статья]) ** автоматический выход из системы, если время неактивного сеанса пользователя превышает

максимально допустимое значение

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

@Override
public boolean preHandle(
  HttpServletRequest req, HttpServletResponse res, Object handler) throws Exception {
    log.info("Pre handle method - check handling start time");
    long startTime = System.currentTimeMillis();
    request.setAttribute("executionTime", startTime);
}

В этой части кода мы устанавливаем startTime обработки выполнения.

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

if (UserInterceptor.isUserLogged()) {
    session = request.getSession();
    log.info("Time since last request in this session: {} ms",
      System.currentTimeMillis() - request.getSession().getLastAccessedTime());
    if (System.currentTimeMillis() - session.getLastAccessedTime()
      > MAX__INACTIVE__SESSION__TIME) {
        log.warn("Logging out, due to inactive session");
        SecurityContextHolder.clearContext();
        request.logout();
        response.sendRedirect("/spring-rest-full/logout");
    }
}
return true;

Во-первых, нам нужно получить сессию из запроса.

Затем мы делаем некоторые записи в консоли, о том, кто вошел в систему и сколько времени прошло, так как пользователь выполняет любую операцию в нашем приложении. Мы можем использовать session.getLastAccessedTime () , чтобы получить эту информацию, вычесть ее из текущего времени и сравнить с нашими MAX INACTIVE SESSION TIME.__

Если время больше, чем мы разрешаем, мы очищаем контекст, завершаем запрос и затем (необязательно) отправляем перенаправление в качестве ответа на представление выхода из системы по умолчанию, которое объявлено в файле конфигурации Spring Security.

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

3.2. postHandle ()

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

@Override
public void postHandle(
  HttpServletRequest request,
  HttpServletResponse response,
  Object handler,
  ModelAndView model) throws Exception {
    log.info("Post handle method - check execution time of handling");
    long startTime = (Long) request.getAttribute("executionTime");
    log.info("Execution time for handling the request was: {} ms",
      System.currentTimeMillis() - startTime);
}

Реализация проста - мы проверяем время выполнения и вычитаем его из текущего системного времени. Просто не забудьте привести значение модели к long .

Теперь мы можем правильно записать время выполнения.

4. Конфиг Перехватчика

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

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

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

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

Кроме того, нам нужно добавить слушатель, чтобы автоматизировать создание ApplicationContext :

public class ListenerConfig implements WebApplicationInitializer {
    @Override
    public void onStartup(ServletContext sc) throws ServletException {
        sc.addListener(new RequestContextListener());
    }
}

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

В этом руководстве показано, как перехватывать веб-запросы с помощью HandlerInterceptor в Spring MVC для ручного управления сеансом/тайм-аута.

Как обычно, все примеры и конфигурации доступны здесь по адресу GitHub .

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

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

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

Перехватчики]** ссылка:/spring-модель-параметры-с-обработчиком-перехватчиком[Изменение пружины

Параметры модели с перехватчиком обработчика]** текущая статья