Modifica dei parametri del modello Spring con Handler Interceptor

1. Introduzione

In questo tutorial ci concentreremo su Spring MVC HandlerInterceptor. Più specificamente, cambieremo i parametri del modello di Spring MVC prima e dopo la gestione di una richiesta.

Se vuoi leggere le basi di HandlerInterceptor , dai un'occhiata a questo articolo.

2. Dipendenze di Maven

Per utilizzare gli Interceptor , è necessario includere la seguente sezione in una sezione delle dipendenze del file pom.xml :

 org.springframework spring-web 5.2.8.RELEASE  

L'ultima versione può essere trovata qui.

Questa dipendenza copre solo Spring Web, quindi non dimenticare di aggiungere s pring-core e spring-context per un'applicazione web completa e una libreria di registrazione a tua scelta.

3. Implementazione personalizzata

Uno dei casi d'uso di HandlerInterceptor è l'aggiunta di parametri comuni / specifici dell'utente a un modello, che sarà disponibile su ciascuna vista generata.

Nel nostro esempio, utilizzeremo l'implementazione dell'intercettore personalizzato per aggiungere il nome utente dell'utente registrato ai parametri del modello. In sistemi più complessi possiamo aggiungere informazioni più specifiche come: percorso avatar utente, posizione utente, ecc.

Cominciamo con la definizione della nostra nuova classe Interceptor :

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

Estendiamo HandlerInterceptorAdapter , poiché vogliamo implementare solo i metodi preHandle () e postHandle () .

Come accennato in precedenza, vogliamo aggiungere il nome dell'utente registrato a un modello. Prima di tutto, dobbiamo verificare se un utente ha effettuato l'accesso. Potremmo ottenere queste informazioni controllando SecurityContextHolder :

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

Quando viene stabilita una HttpSession , ma nessuno è connesso, un nome utente nel contesto Spring Security è uguale a anonymousUser . Successivamente, procediamo con l'implementazione di preHandle ():

3.1. Metodo preHandle ()

Prima di gestire una richiesta, non possiamo accedere ai parametri del modello. Per aggiungere il nome utente, dobbiamo utilizzare HttpSession per impostare i parametri:

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

Ciò è fondamentale se utilizziamo alcune di queste informazioni prima di gestire una richiesta. Come si vede, stiamo controllando se un utente è loggato e quindi aggiungiamo parametri alla nostra richiesta ottenendone la sessione:

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

Abbiamo utilizzato SecurityContextHolder per ottenere il nome utente registrato . Puoi sovrascrivere l' implementazione di Spring Security UserDetails per ottenere l'email invece di un nome utente standard.

3.2. Metodo p ostHandle ()

Dopo aver gestito una richiesta, i parametri del nostro modello sono disponibili, quindi possiamo accedervi per modificare i valori o aggiungerne di nuovi. Per farlo, utilizziamo il metodo postHandle () sovrascritto :

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

Diamo un'occhiata ai dettagli di implementazione.

Prima di tutto, è meglio verificare se il modello non è nullo. Ci impedirà di incontrare una NullPointerException .

Inoltre, possiamo verificare se una vista non è un'istanza di vista di reindirizzamento .

Non è necessario aggiungere / modificare i parametri dopo che la richiesta è stata gestita e quindi reindirizzata, poiché immediatamente il nuovo controller eseguirà nuovamente la gestione. Per verificare se la visualizzazione viene reindirizzata, stiamo introducendo il seguente metodo:

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

Infine, stiamo controllando di nuovo se un utente è registrato e, in caso affermativo, stiamo aggiungendo parametri al modello 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 ========================="); }

Tieni presente che la registrazione è molto importante, poiché questa logica funziona "dietro le quinte" della nostra applicazione. È facile dimenticare che stiamo modificando alcuni parametri del modello su ciascuna vista senza registrarla correttamente.

4. Configurazione

Per aggiungere il nostro Interceptor appena creato nella configurazione Spring, dobbiamo sovrascrivere il metodo addInterceptors () all'interno della classe WebConfig che implementa WebMvcConfigurer:

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

Possiamo ottenere la stessa configurazione modificando il nostro file di configurazione XML Spring:

Da questo momento, possiamo accedere a tutti i parametri relativi all'utente su tutte le viste generate.

Si noti che se sono configurati più Spring Interceptor , il metodo preHandle () viene eseguito nell'ordine di configurazione mentre i metodi postHandle () e afterCompletion () vengono richiamati nell'ordine inverso.

5. conclusione

Questo tutorial presenta l'intercettazione delle richieste Web utilizzando HandlerInterceptor di Spring MVC per fornire informazioni all'utente.

In questo particolare esempio, ci siamo concentrati sull'aggiunta dei dettagli dell'utente registrato nella nostra applicazione web per modellare i parametri. È possibile estendere questa implementazione di HandlerInterceptor aggiungendo informazioni più dettagliate.

Tutti gli esempi e le configurazioni sono disponibili qui su GitHub.

5.1. Articoli della serie

Tutti gli articoli della serie:

  • Introduzione a Spring MVC Handler Interceptors
  • Modifica dei parametri del modello Spring con Handler Interceptor (questo)