Modification des paramètres du modèle de ressort avec Handler Interceptor

1. Introduction

Dans ce didacticiel, nous allons nous concentrer sur le Spring MVC HandlerInterceptor. Plus précisément, nous modifierons les paramètres du modèle de Spring MVC avant et après le traitement d'une requête.

Si vous souhaitez en savoir plus sur les bases de HandlerInterceptor , consultez cet article.

2. Dépendances de Maven

Pour utiliser les intercepteurs , vous devez inclure la section suivante dans une section des dépendances de votre fichier pom.xml :

 org.springframework spring-web 5.2.8.RELEASE  

La dernière version peut être trouvée ici.

Cette dépendance ne couvre que Spring Web, alors n'oubliez pas d'ajouter s pring-core et spring-context pour une application Web complète et une bibliothèque de journalisation de votre choix.

3. Mise en œuvre personnalisée

L'un des cas d'utilisation de HandlerInterceptor est l'ajout de paramètres communs / spécifiques à l'utilisateur à un modèle, qui seront disponibles sur chaque vue générée.

Dans notre exemple, nous utiliserons une implémentation d'intercepteur personnalisée pour ajouter le nom d'utilisateur de l'utilisateur connecté aux paramètres du modèle. Dans les systèmes plus complexes, nous pouvons ajouter des informations plus spécifiques telles que: le chemin de l'avatar de l'utilisateur, l'emplacement de l'utilisateur, etc.

Commençons par définir notre nouvelle classe Interceptor :

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

Nous étendons HandlerInterceptorAdapter , car nous souhaitons uniquement implémenter les méthodes preHandle () et postHandle () .

Comme nous l'avons mentionné précédemment, nous voulons ajouter le nom de l'utilisateur connecté à un modèle. Tout d'abord, nous devons vérifier si un utilisateur est connecté. Nous pouvons obtenir ces informations en vérifiant SecurityContextHolder :

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

Lorsqu'une HttpSession est établie, mais que personne n'est connecté, un nom d'utilisateur dans le contexte de Spring Security équivaut à anonymousUser . Ensuite, nous procédons à l'implémentation de preHandle ():

3.1. Méthode preHandle ()

Avant de traiter une requête, nous ne pouvons pas accéder aux paramètres du modèle. Afin d'ajouter un nom d'utilisateur, nous devons utiliser HttpSession pour définir les paramètres:

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

Ceci est crucial si nous utilisons certaines de ces informations avant de traiter une demande. Comme on le voit, nous vérifions si un utilisateur est connecté puis ajoutons des paramètres à notre demande en obtenant sa session:

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

Nous avons utilisé SecurityContextHolder pour obtenir logUsername . Vous pouvez remplacer l' implémentation de Spring Security UserDetails pour obtenir un e-mail au lieu d'un nom d'utilisateur standard.

3.2. Méthode p ostHandle ()

Après avoir traité une demande, nos paramètres de modèle sont disponibles, nous pouvons donc y accéder pour modifier les valeurs ou en ajouter de nouvelles. Pour ce faire, nous utilisons la méthode postHandle () surchargée :

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

Jetons un coup d'œil aux détails de l'implémentation.

Tout d'abord, il vaut mieux vérifier si le modèle n'est pas nul. Cela nous empêchera de rencontrer une NullPointerException .

De plus, nous pouvons vérifier si une vue n'est pas une instance de la vue de redirection .

Il n'est pas nécessaire d'ajouter / de modifier les paramètres une fois la demande traitée puis redirigée, car immédiatement, le nouveau contrôleur effectuera à nouveau la gestion. Pour vérifier si la vue est redirigée, nous introduisons la méthode suivante:

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

Enfin, nous vérifions à nouveau si un utilisateur est connecté, et si oui, nous ajoutons des paramètres au modèle 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 ========================="); }

Veuillez noter que la journalisation est très importante, car cette logique fonctionne «dans les coulisses» de notre application. Il est facile d'oublier que nous modifions certains paramètres de modèle sur chaque vue sans les enregistrer correctement.

4. Configuration

Pour ajouter notre Intercepteur nouvellement créé dans la configuration Spring, nous devons remplacer la méthode addInterceptors () dans la classe WebConfig qui implémente WebMvcConfigurer:

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

Nous pouvons obtenir la même configuration en éditant notre fichier de configuration XML Spring:

À partir de ce moment, nous pouvons accéder à tous les paramètres liés à l'utilisateur sur toutes les vues générées.

Veuillez noter que si plusieurs Spring Interceptors sont configurés, la méthode preHandle () est exécutée dans l'ordre de configuration tandis que les méthodes postHandle () et afterCompletion () sont appelées dans l'ordre inverse.

5. Conclusion

Ce didacticiel présente l'interception des requêtes Web à l'aide du HandlerInterceptor de Spring MVC afin de fournir des informations utilisateur.

Dans cet exemple particulier, nous nous sommes concentrés sur l'ajout des détails des utilisateurs enregistrés dans notre application Web aux paramètres du modèle. Vous pouvez étendre cette implémentation de HandlerInterceptor en ajoutant des informations plus détaillées.

Tous les exemples et configurations sont disponibles ici sur GitHub.

5.1. Articles de la série

Tous les articles de la série:

  • Introduction aux intercepteurs Spring MVC Handler
  • Modification des paramètres du modèle de ressort avec Handler Interceptor (celui-ci)