Ändern der Federmodellparameter mit dem Handler Interceptor

1. Einleitung

In diesem Tutorial konzentrieren wir uns auf den Spring MVC HandlerInterceptor. Insbesondere werden wir die Modellparameter von Spring MVC vor und nach der Bearbeitung einer Anfrage ändern.

Wenn Sie mehr über die Grundlagen von HandlerInterceptor erfahren möchten, lesen Sie diesen Artikel.

2. Maven-Abhängigkeiten

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

 org.springframework spring-web 5.2.8.RELEASE  

Die neueste Version finden Sie hier.

Diese Abhängigkeit gilt nur für Spring Web. Vergessen Sie also nicht, den Pring-Core und den Spring-Kontext für eine vollständige Webanwendung und eine Protokollierungsbibliothek Ihrer Wahl hinzuzufügen .

3. Benutzerdefinierte Implementierung

Einer der Anwendungsfälle von HandlerInterceptor ist das Hinzufügen allgemeiner / benutzerspezifischer Parameter zu einem Modell, die in jeder generierten Ansicht verfügbar sind.

In unserem Beispiel verwenden wir eine benutzerdefinierte Interceptor-Implementierung, um den Benutzernamen des protokollierten Benutzers zu den Modellparametern hinzuzufügen. In komplexeren Systemen können wir spezifischere Informationen hinzufügen, z. B. Benutzer-Avatar-Pfad, Benutzer-Standort usw.

Beginnen wir mit der Definition unserer neuen Interceptor- Klasse:

public class UserInterceptor extends HandlerInterceptorAdapter { private static Logger log = LoggerFactory.getLogger(UserInterceptor.class); ... }

Wir erweitern HandlerInterceptorAdapter , da wir nur die Methoden preHandle () und postHandle () implementieren möchten .

Wie bereits erwähnt, möchten wir einem Modell den Namen des protokollierten Benutzers hinzufügen. Zunächst müssen wir überprüfen, ob ein Benutzer angemeldet ist. Diese Informationen erhalten Sie möglicherweise, indem Sie SecurityContextHolder überprüfen :

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

Wenn eine HttpSession eingerichtet ist, aber niemand angemeldet ist, entspricht ein Benutzername im Spring Security-Kontext anonymem Benutzer . Als nächstes fahren wir mit der Implementierung von preHandle () fort:

3.1. Methode preHandle ()

Vor der Bearbeitung einer Anfrage können wir nicht auf Modellparameter zugreifen. Um einen Benutzernamen hinzuzufügen, müssen wir HttpSession verwenden , um Parameter festzulegen :

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

Dies ist von entscheidender Bedeutung, wenn wir einige dieser Informationen verwenden, bevor wir eine Anfrage bearbeiten. Wie wir sehen, prüfen wir, ob ein Benutzer angemeldet ist, und fügen unserer Anfrage dann Parameter hinzu, indem wir seine Sitzung abrufen:

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 ========================="); }

Wir haben SecurityContextHolder verwendet , um den protokollierten Benutzernamen zu erhalten . Sie können die Implementierung von Spring Security UserDetails überschreiben , um E-Mails anstelle eines Standardbenutzernamens zu erhalten.

3.2. Methode p ostHandle ()

Nach der Bearbeitung einer Anfrage stehen unsere Modellparameter zur Verfügung, sodass wir darauf zugreifen können, um Werte zu ändern oder neue hinzuzufügen. Dazu verwenden wir die überschriebene postHandle () -Methode:

@Override public void postHandle( HttpServletRequest req, HttpServletResponse res, Object o, ModelAndView model) throws Exception { if (model != null && !isRedirectView(model)) { if (isUserLogged()) { addToModelUserDetails(model); } } }

Werfen wir einen Blick auf die Implementierungsdetails.

Zunächst ist es besser zu überprüfen, ob das Modell nicht null ist. Dadurch wird verhindert, dass eine NullPointerException auftritt .

Darüber hinaus können wir prüfen, ob eine Ansicht keine Instanz von Redirect View ist.

Es ist nicht erforderlich, Parameter hinzuzufügen / zu ändern, nachdem die Anforderung verarbeitet und dann umgeleitet wurde, da der neue Controller die Verarbeitung sofort erneut ausführt. Um zu überprüfen, ob die Ansicht umgeleitet wird, führen wir die folgende Methode ein:

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

Schließlich prüfen wir erneut, ob ein Benutzer angemeldet ist, und wenn ja, fügen wir dem Spring-Modell Parameter hinzu:

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 ========================="); }

Bitte beachten Sie, dass die Protokollierung sehr wichtig ist, da diese Logik „hinter den Kulissen“ unserer Anwendung funktioniert. Es ist leicht zu vergessen, dass wir einige Modellparameter in jeder Ansicht ändern, ohne sie ordnungsgemäß zu protokollieren.

4. Konfiguration

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

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

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

Ab diesem Moment können wir in allen generierten Ansichten auf alle benutzerbezogenen Parameter zugreifen.

Beachten Sie, dass bei der Konfiguration mehrerer Spring Interceptors die Methode preHandle () in der Reihenfolge der Konfiguration ausgeführt wird, während die Methoden postHandle () und afterCompletion () in umgekehrter Reihenfolge aufgerufen werden.

5. Schlussfolgerung

In diesem Lernprogramm wird das Abfangen von Webanforderungen mit dem HandlerInterceptor von Spring MVC vorgestellt, um Benutzerinformationen bereitzustellen.

In diesem speziellen Beispiel haben wir uns darauf konzentriert, protokollierte Benutzerdetails in unserer Webanwendung zu Modellparametern hinzuzufügen. Sie können diese HandlerInterceptor- Implementierung erweitern, indem Sie detailliertere Informationen hinzufügen.

Alle Beispiele und Konfigurationen finden Sie hier auf GitHub.

5.1. Artikel in der Reihe

Alle Artikel der Reihe:

  • Einführung in Spring MVC Handler Interceptors
  • Ändern der Federmodellparameter mit dem Handler Interceptor (dieser)