Modification des paramètres du modèle de ressort avec un intercepteur de gestionnaire

1. Introduction

Dans ce didacticiel, nous allons nous concentrer sur l’interrupteur Spring MVC.

Si vous voulez en savoir plus sur les bases de HandlerInterceptor , consultez ce lien:/spring-mvc-handlerinterceptor[article].

2. Dépendances Maven

Pour utiliser Interceptors , vous devez inclure la section suivante dans une section dependencies de votre fichier pom.xml :

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

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

Cette dépendance ne concerne que Spring Web. N’oubliez donc 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 consiste à ajouter des paramètres communs/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 des 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 les méthodes HandlerInterceptorAdapter , car nous souhaitons uniquement implémenter les méthodes preHandle () et postHandle () .

Comme nous l’avons mentionné précédemment, nous souhaitons ajouter le nom de l’utilisateur enregistré à 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 Spring Security est égal à anonymousUser . Ensuite, nous poursuivons avec l’implémentation de preHandle ():

3.1. Méthode preHandle ()

Avant de traiter une demande, 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 nous le voyons, nous vérifions si un utilisateur est connecté, puis nous 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 loggedUsername . Vous pouvez remplacer l’implémentation Spring Security UserDetails pour obtenir un courrier électronique 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 des valeurs ou en ajouter de nouvelles. Pour ce faire, nous utilisons la méthode postHandle () remplacé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 la mise en oeuvre.

Tout d’abord, il est préférable de vérifier si le modèle n’est pas null. Cela nous évitera de rencontrer une NullPointerException .

De plus, nous pouvons vérifier si un View n’est pas une instance de Redirect _View . _

Il n’est pas nécessaire d’ajouter/de modifier les paramètres après le traitement de la demande, puis sa redirection, 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 «en coulisses» de notre application. Il est facile d’oublier que nous modifions certains paramètres de modèle sur chaque View sans les enregistrer correctement.

4. Configuration

Pour ajouter notre Interceptor nouvellement créé à la configuration Spring, nous devons redéfinir la méthode addInterceptors () à l’intérieur de 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 modifiant notre fichier de configuration XML Spring:

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

À 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 invoquées dans l’ordre inverse.

5. Conclusion

Ce didacticiel présente l’interception de requêtes Web à l’aide de HandlerInterceptor de Spring MVC afin de fournir des informations sur les utilisateurs.

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

Tous les exemples et configurations sont disponibles ici à l’adresse GitHub .

5.1. Articles de la série

Tous les articles de la série:

  • link:/spring-mvc-handlerinterceptor[Introduction à Spring MVC Handler

Intercepteurs]** Modification des paramètres de modèle de ressort avec Handler Interceptor (celui-ci)