Verwenden eines benutzerdefinierten Spring MVC-Handler-Interceptors zum Verwalten von Sitzungen

1. Einführung

In diesem Tutorial konzentrieren wir uns auf den Spring MVC HandlerInterceptor.

Insbesondere werden wir einen fortgeschritteneren Anwendungsfall für die Verwendung von Interceptors zeigen - Wir simulieren eine Session Timeout-Logik , indem Sie benutzerdefinierte Zähler und Tracking-Sitzungen manuell einstellen.

Wenn Sie in Spring etwas über die __HandlerInterceptor-Grundlagen erfahren möchten, lesen Sie diesen Link:/spring-mvc-handlerinterceptor[Artikel]

2. Abhängigkeiten von Maven

Um Interceptors verwenden zu können, müssen Sie den folgenden Abschnitt in einen dependencies -Abschnitt Ihrer pom.xml -Datei aufnehmen:

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

Diese Abhängigkeit gilt nur für Spring Web. Vergessen Sie daher nicht, s _pring-core und spring-context_ für eine vollständige (minimale) Webanwendung hinzuzufügen.

3. Benutzerdefinierte Implementierung von Sitzungszeitüberschreitungen

In diesem Beispiel konfigurieren wir die maximale inaktive Zeit für die Benutzer in unserem System. Nach dieser Zeit werden sie automatisch von der Anwendung abgemeldet.

Diese Logik ist nur ein Beweis des Konzepts - wir können natürlich leicht das gleiche Ergebnis mit Session-Timeouts erzielen - aber das Ergebnis ist hier nicht der Punkt, sondern die Verwendung des Interceptors.

Daher möchten wir sicherstellen, dass die Sitzung ungültig wird, wenn der Benutzer nicht aktiv ist. Wenn ein Benutzer vergessen hat, sich abzumelden, verhindert der inaktive Zeitzähler den Zugriff unberechtigter Benutzer auf das Konto. Dazu müssen wir für die inaktive Zeit eine Konstante setzen:

private static final long MAX__INACTIVE__SESSION__TIME = 5 **  10000;

Wir haben es zu Testzwecken auf 50 Sekunden gesetzt; nicht vergessen, es wird in ms gezählt

Jetzt müssen wir die einzelnen Sitzungen in unserer App verfolgen, sodass wir dieses Spring-Interface hinzufügen müssen:

@Autowired
private HttpSession session;

Fahren wir mit der Methode preHandle () fort.

3.1. preHandle ()

In dieser Methode schließen wir folgende Operationen ein:

  • Einstellen von Timern, um die Bearbeitungszeit der Anforderungen zu prüfen

  • Prüfen, ob ein Benutzer angemeldet ist (mithilfe der UserInterceptor -Methode von)

diesen Link:/spring-model-parameters-with-handler-interceptor[Artikel]) ** Automatische Abmeldung, wenn die inaktive Sitzungszeit des Benutzers überschritten wird

maximal zulässiger Wert

Schauen wir uns die Implementierung an:

@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);
}

In diesem Teil des Codes legen wir startTime für die Ausführung der Verarbeitung fest.

Ab diesem Moment werden wir einige Sekunden zählen, um die Bearbeitung jeder Anfrage abzuschließen. Im nächsten Teil stellen wir Logik für die Sitzungszeit bereit, nur wenn sich jemand während seiner HTTP-Sitzung angemeldet hat:

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;

Zuerst müssen wir die Sitzung von der Anfrage abrufen.

Als Nächstes führen wir eine Konsolenprotokollierung durch. Wer ist angemeldet und wie lange ist vergangen, seitdem der Benutzer einen Vorgang in unserer Anwendung ausführt. Wir können session.getLastAccessedTime () verwenden, um diese Informationen zu erhalten, diese vom aktuellen Zeitpunkt abzuziehen und mit unserem MAX INACTIVE SESSION TIME zu vergleichen.

Wenn die Zeit länger als zulässig ist, löschen Sie den Kontext, melden die Anforderung ab und senden dann (optional) eine Umleitung als Antwort auf die Standard-Abmeldungsansicht, die in der Spring Security-Konfigurationsdatei angegeben ist.

Zur Vervollständigung der Zähler für die Bearbeitung der Zeitbeispiele implementieren wir auch die Methode postHandle () , die im nächsten Unterabschnitt beschrieben wird.

3.2. postHandle ()

Diese Methode dient nur der Implementierung, um Informationen darüber zu erhalten, wie lange es gedauert hat, um die aktuelle Anforderung zu verarbeiten. Wie Sie im vorherigen Code-Snippet gesehen haben, setzen wir im Spring-Modell executionTime . Jetzt ist es an der Zeit, es zu benutzen:

@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);
}

Die Implementierung ist einfach: Wir prüfen die Ausführungszeit und ziehen sie von der aktuellen Systemzeit ab. Denken Sie daran, den Wert des Modells in long umzuwandeln.

Jetzt können wir die Ausführungszeit korrekt protokollieren.

4. Config des Interceptors

Um unseren neu erstellten Interceptor in die Spring-Konfiguration aufzunehmen, müssen wir die addInterceptors () -Methode in der WebConfig -Klasse überschreiben, die WebMvcConfigurer implementiert:

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

Wir können dieselbe Konfiguration erreichen, indem wir unsere XML Spring-Konfigurationsdatei bearbeiten:

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

Außerdem müssen wir Listener hinzufügen, um die Erstellung des ApplicationContext zu automatisieren:

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

5. Fazit

In diesem Lernprogramm wird gezeigt, wie Webanfragen mit dem HandlerInterceptor von Spring MVC abgefangen werden, um die Sitzungsverwaltung/das Zeitlimit manuell auszuführen.

Alle Beispiele und Konfigurationen sind wie üblich hier unter GitHub verfügbar.

5.1. Artikel in der Serie

Alle Artikel der Serie:

  • link:/spring-mvc-handlerinterceptor[Einführung in Spring MVC Handler

Abfangjäger]** link:/spring-model-parameters-with-handler-interceptor[Wechselnde Feder

Modellparameter mit Handler-Interceptor]** der aktuelle Artikel