Guide des mappages Spring Handler

1. Introduction

Dans Spring MVC, le DispatcherServlet agit en tant que contrôleur frontal - recevant toutes les requêtes HTTP entrantes et les traitant.

En termes simples, le traitement se produit en passant les requêtes au composant concerné à l'aide de mappages de gestionnaires .

HandlerMapping est une interface qui définit un mappage entre les requêtes et les objets de gestionnaire. Alors que le framework Spring MVC fournit des implémentations prêtes à l'emploi, l'interface peut être implémentée par les développeurs pour fournir une stratégie de cartographie personnalisée.

Cet article décrit certaines des implémentations fournies par Spring MVC, à savoir BeanNameUrlHandlerMapping , SimpleUrlHandlerMapping , ControllerClassNameHandlerMapping , leur configuration et les différences entre eux.

2. BeanNameUrlHandlerMapping

BeanNameUrlHandlerMapping est l' implémentation HandlerMapping par défaut . BeanNameUrlHandlerMapping mappe les URL de requête sur des beans portant le même nom.

Ce mappage particulier prend en charge la correspondance directe de nom et également la correspondance de modèle en utilisant le modèle «*».

Par exemple, une URL entrante «/ foo» correspond à un bean appelé «/ foo» . Un exemple de mappage de modèles est le mappage des requêtes vers «/ foo *» vers des beans dont les noms commencent par «/ foo» comme «/ foo2 /» ou «/ fooOne /» .

Configurons cet exemple ici et enregistrons un contrôleur de bean qui gère les requêtes à «/ beanNameUrl» :

@Configuration public class BeanNameUrlHandlerMappingConfig { @Bean BeanNameUrlHandlerMapping beanNameUrlHandlerMapping() { return new BeanNameUrlHandlerMapping(); } @Bean("/beanNameUrl") public WelcomeController welcome() { return new WelcomeController(); } }

C'est l'équivalent XML de la configuration basée sur Java ci-dessus:

Il est important de noter que dans ces deux configurations, la définition d'un bean pour BeanNameUrlHandlerMapping n'est pas requise car elle est fournie par Spring MVC. La suppression de cette définition de bean ne posera aucun problème et les requêtes seront toujours mappées vers leurs beans de gestionnaire enregistrés.

Désormais, toutes les requêtes adressées à «/ beanNameUrl» seront transmises par DispatcherServlet à « WelcomeController ». WelcomeController renvoie un nom de vue appelé « bienvenue ».

Le code suivant teste cette configuration et s'assure que le nom de vue correct est renvoyé:

public class BeanNameMappingConfigTest { // ... @Test public void whenBeanNameMapping_thenMappedOK() { mockMvc.perform(get("/beanNameUrl")) .andExpect(status().isOk()) .andExpect(view().name("welcome")); } }

3. SimpleUrlHandlerMapping

Ensuite, SimpleUrlHandlerMapping est l' implémentation HandlerMapping la plus flexible . Il permet un mappage direct et déclaratif entre les instances de bean et les URL ou entre les noms de bean et les URL.

Mappons les requêtes «/ simpleUrlWelcome» et «/ * / simpleUrlWelcome» au bean «welcome» :

@Configuration public class SimpleUrlHandlerMappingConfig { @Bean public SimpleUrlHandlerMapping simpleUrlHandlerMapping() { SimpleUrlHandlerMapping simpleUrlHandlerMapping = new SimpleUrlHandlerMapping(); Map urlMap = new HashMap(); urlMap.put("/simpleUrlWelcome", welcome()); simpleUrlHandlerMapping.setUrlMap(urlMap); return simpleUrlHandlerMapping; } @Bean public WelcomeController welcome() { return new WelcomeController(); } }

Sinon, voici la configuration XML équivalente:

   /simpleUrlWelcome=welcome /*/simpleUrlWelcome=welcome    

Il est important de noter que dans la configuration XML, un mappage entre la balise «» doit être effectué sous une forme acceptée par la classe java.util.Properties et doit suivre la syntaxe: path = Handler_Bean_Name .

L'URL doit normalement être précédée d'une barre oblique, cependant, si le chemin ne commence pas par un, Spring MVC l'ajoute automatiquement.

Une autre façon de configurer l'exemple ci-dessus en XML consiste à utiliser la propriété «props» au lieu de «value» . Les accessoires ont une liste de balises «prop» où chacune définit un mappage où «clé» fait référence à l'URL mappée et la valeur de la balise est le nom du bean.

   welcome welcome   

Le scénario de test suivant garantit que les requêtes adressées à «/ simpleUrlWelcome » sont gérées par « WelcomeController» qui renvoie un nom de vue appelé «welcome» :

public class SimpleUrlMappingConfigTest { // ... @Test public void whenSimpleUrlMapping_thenMappedOK() { mockMvc.perform(get("/simpleUrlWelcome")) .andExpect(status().isOk()) .andExpect(view().name("welcome")); } }

4. ControllerClassNameHandlerMapping (supprimé au printemps 5)

Les ControllerClassNameHandlerMapping cartes URL à un grain de contrôleur enregistré (ou un contrôleur annoté avec l' @Controller annotation) qui a, ou commence avec le même nom.

Cela peut être plus pratique dans de nombreux scénarios, en particulier pour les implémentations de contrôleur simples qui gèrent un seul type de demande. La convention utilisée par Spring MVC est d'utiliser le nom de la classe et de supprimer le suffixe «Controller» , puis de changer le nom en minuscules et de le renvoyer comme le mappage avec un «/» en tête .

Par exemple, «WelcomeController» reviendrait sous forme de mappage à «/ welcome *» , c'est-à-dire à toute URL commençant par «welcome» .

Configurons ControllerClassNameHandlerMapping :

@Configuration public class ControllerClassNameHandlerMappingConfig { @Bean public ControllerClassNameHandlerMapping controllerClassNameHandlerMapping() { return new ControllerClassNameHandlerMapping(); } @Bean public WelcomeController welcome() { return new WelcomeController(); } }

Notez que ControllerClassNameHandlerMapping est obsolète à partir de Spring 4.3 au profit des méthodes de gestion des annotations.

Une autre remarque importante est que les noms de contrôleurs seront toujours retournés en minuscules (moins le suffixe «Contrôleur»). Donc, si nous avons un contrôleur appelé « WelcomeBaeldungController », il ne traitera que les requêtes adressées à «/ welcomebaeldung» et non à «/ welcomeBaeldung» .

Dans la configuration Java et la configuration XML ci-dessous, nous définissons le bean ControllerClassNameHandlerMapping et enregistrons les beans pour les contrôleurs que nous utiliserons pour gérer les requêtes. Nous enregistrons également un bean de type «WelcomeController» et ce bean gérera toutes les requêtes commençant par «/ welcome» .

Voici la configuration XML équivalente:

Lors de l'utilisation de la configuration ci-dessus, les demandes à «/ welcome » seront traitées par le « WelcomeController ».

Le code suivant garantira que les requêtes adressées à «/ welcome *» telles que «/ welcometest » sont gérées par «WelcomeController» qui renvoie un nom de vue appelé « welcome »:

public class ControllerClassNameHandlerMappingTest { // ... @Test public void whenControllerClassNameMapping_thenMappedOK() { mockMvc.perform(get("/welcometest")) .andExpect(status().isOk()) .andExpect(view().name("welcome")); } }

5. Configuration des priorités

Le framework Spring MVC permet plusieurs implémentations de l' interface HandlerMapping en même temps.

Créons une configuration et enregistrons deux contrôleurs, tous deux mappés sur l'URL «/ welcome», en utilisant uniquement un mappage différent et en renvoyant des noms de vue différents:

@Configuration public class HandlerMappingDefaultConfig { @Bean("/welcome") public BeanNameHandlerMappingController beanNameHandlerMapping() { return new BeanNameHandlerMappingController(); } @Bean public WelcomeController welcome() { return new WelcomeController(); } }

En l'absence de mappeur de gestionnaire explicite enregistré, un BeanNameHandlerMapping par défaut sera utilisé. Affirmons ce comportement avec le test:

@Test public void whenConfiguringPriorities_thenMappedOK() { mockMvc.perform(get("/welcome")) .andExpect(status().isOk()) .andExpect(view().name("bean-name-handler-mapping")); } 

Si nous enregistrons explicitement un mappeur de gestionnaire différent, le mappeur par défaut sera remplacé. Cependant, il est intéressant de voir ce qui se passe lorsque deux mappeurs sont explicitement enregistrés:

@Configuration public class HandlerMappingPrioritiesConfig { @Bean BeanNameUrlHandlerMapping beanNameUrlHandlerMapping() { BeanNameUrlHandlerMapping beanNameUrlHandlerMapping = new BeanNameUrlHandlerMapping(); return beanNameUrlHandlerMapping; } @Bean public SimpleUrlHandlerMapping simpleUrlHandlerMapping() { SimpleUrlHandlerMapping simpleUrlHandlerMapping = new SimpleUrlHandlerMapping(); Map urlMap = new HashMap(); urlMap.put("/welcome", simpleUrlMapping()); simpleUrlHandlerMapping.setUrlMap(urlMap); return simpleUrlHandlerMapping; } @Bean public SimpleUrlMappingController simpleUrlMapping() { return new SimpleUrlMappingController(); } @Bean("/welcome") public BeanNameHandlerMappingController beanNameHandlerMapping() { return new BeanNameHandlerMappingController(); } }

Pour obtenir le contrôle sur le mappage utilisé, les priorités sont définies à l'aide de la méthode setOrder (int order) . Cette méthode prend un paramètre int où une valeur inférieure signifie une priorité plus élevée.

Dans la configuration XML, vous pouvez configurer les priorités en utilisant une propriété appelée «ordre» :

Ajoutons des propriétés de commande aux beans de mappage de gestionnaires, via les beanNameUrlHandlerMapping.setOrder (1) et simpleUrlHandlerMapping.setOrder (0). La valeur inférieure de la propriété order reflète une priorité plus élevée. Affirmons un nouveau comportement avec le test:

@Test public void whenConfiguringPriorities_thenMappedOK() { mockMvc.perform(get("/welcome")) .andExpect(status().isOk()) .andExpect(view().name("simple-url-handler-mapping")); }

Lors du test de la configuration ci-dessus, vous voyez que les requêtes à «/ welcome» seront gérées par le bean SimpleUrlHandlerMapping qui appelle un SimpleUrlHandlerController et renvoie une vue simple-url-handler-mapping . Nous pouvons facilement configurer le BeanNameHandlerMapping pour qu'il prenne la priorité en ajustant en conséquence les valeurs de la propriété order .

6. Conclusion

Dans cet article, nous avons expliqué comment le mappage d'URL est géré dans le framework Spring MVC en explorant les différentes implémentations dans le framework.

Le code accompagnant cet article se trouve à l'adresse over sur GitHub.