web.xml vs Initializer avec Spring

1. Vue d'ensemble

Dans cet article, nous couvrirons trois approches différentes de la configuration d'un DispatcherServlet disponibles dans les versions récentes de Spring Framework:

  1. Nous allons commencer par une configuration XML et un fichier web.xml
  2. Ensuite, nous migrerons la déclaration Servlet du fichier web.xml vers la configuration Java, mais nous laisserons toute autre configuration en XML
  3. Enfin, dans la troisième et dernière étape du refactoring, nous aurons un projet 100% configuré en Java

2. Le DispatcherServlet

L'un des concepts de base de Spring MVC est le DispatcherServlet . La documentation Spring le définit comme:

Un répartiteur central pour les gestionnaires / contrôleurs de requêtes HTTP, par exemple pour les contrôleurs d'interface utilisateur Web ou les exportateurs de services à distance basés sur HTTP. Envois aux gestionnaires enregistrés pour le traitement d'une requête Web, offrant des fonctionnalités pratiques de mappage et de gestion des exceptions.

Fondamentalement, DispatcherServlet est le point d'entrée de chaque application Spring MVC . Son but est d'intercepter les requêtes HTTP et de les envoyer vers le bon composant qui saura le gérer.

3. Configuration avec w eb.xml

Si vous traitez avec des projets Spring hérités , il est très courant de trouver une configuration XML et jusqu'à Spring 3.1, la seule façon de configurer DispatcherServlet était avec le fichier WEB-INF / web.xml . Dans ce cas, deux étapes sont nécessaires.

Voyons un exemple de configuration - la première étape est la déclaration du servlet:

 dispatcher  org.springframework.web.servlet.DispatcherServlet   contextConfigLocation /WEB-INF/spring/dispatcher-config.xml  1 

Avec ce bloc de XML, nous déclarons un servlet qui:

  1. Est nommé « répartiteur »
  2. Est une instance de org.springframework.web.servlet.DispatcherServlet
  3. Sera initialisé avec un paramètre nommé contextConfigLocation qui contient le chemin d'accès au XML de configuration

load-on-startup est une valeur entière qui spécifie l'ordre de chargement de plusieurs servlets. Donc, si vous avez besoin de déclarer plusieurs servlets, vous pouvez définir dans quel ordre ils seront initialisés. Les servlets marqués avec des entiers inférieurs sont chargés avant les servlets marqués avec des entiers plus élevés.

Maintenant, notre servlet est configuré. La deuxième étape consiste à déclarer un mappage de servlet :

 dispatcher / 

Avec le mappage de servlet, nous le limitons par son nom à un modèle d' URL qui spécifie quelles requêtes HTTP seront traitées par lui.

4. Configuration hybride

Avec l'adoption de la version 3.0 des API Servlet , le fichier web.xml est devenu facultatif et nous pouvons désormais utiliser Java pour configurer le DispatcherServlet .

Nous pouvons enregistrer un servlet implémentant un WebApplicationInitializer . C'est l'équivalent de la configuration XML ci-dessus:

public class MyWebAppInitializer implements WebApplicationInitializer { @Override public void onStartup(ServletContext container) { XmlWebApplicationContext context = new XmlWebApplicationContext(); context.setConfigLocation("/WEB-INF/spring/dispatcher-config.xml"); ServletRegistration.Dynamic dispatcher = container .addServlet("dispatcher", new DispatcherServlet(context)); dispatcher.setLoadOnStartup(1); dispatcher.addMapping("/"); } }

Dans cet exemple, nous sommes:

  1. Implémentation de l' interface WebApplicationInitializer
  2. En remplaçant la méthode onStartup , nous créons un nouveau XmlWebApplicationContext configuré avec le même fichier passé en tant que contextConfigLocation au servlet dans l' exemple XML
  3. Ensuite, nous créons une instance de DispatcherServlet avec le nouveau contexte que nous venons d'instancier
  4. Et enfin, nous enregistrons le servlet avec un modèle d' URL de mappage

Nous avons donc utilisé Java pour déclarer le servlet et le lier à un mappage d'URL, mais nous avons conservé la configuration dans un fichier XML séparé : dispatcher-config.xml .

5. Configuration 100% Java

Avec cette approche, notre servlet est déclaré en Java , mais nous avons toujours besoin d'un fichier XML pour le configurer. Avec WebApplicationInitializer, vous pouvez obtenir une configuration 100% Java .

Voyons comment nous pouvons refactoriser l'exemple précédent.

La première chose à faire est de créer le contexte d'application pour le servlet.

Cette fois, nous utiliserons un contexte basé sur les annotations afin de pouvoir utiliser Java et les annotations pour la configuration et supprimer le besoin de fichiers XML comme dispatcher-config.xml :

AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();

Ce type de contexte peut ensuite être configuré en enregistrant une classe de configuration:

context.register(AppConfig.class);

Ou définir un package entier qui sera analysé pour les classes de configuration:

context.setConfigLocation("com.example.app.config");

Maintenant que notre contexte d'application est créé, nous pouvons ajouter un écouteur au ServletContext qui chargera le contexte:

container.addListener(new ContextLoaderListener(context));

La prochaine étape consiste à créer et à enregistrer notre servlet de répartiteur:

ServletRegistration.Dynamic dispatcher = container .addServlet("dispatcher", new DispatcherServlet(context)); dispatcher.setLoadOnStartup(1); dispatcher.addMapping("/");

Maintenant, notre WebApplicationInitializer devrait ressembler à ceci:

public class MyWebAppInitializer implements WebApplicationInitializer { @Override public void onStartup(ServletContext container) { AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext(); context.setConfigLocation("com.example.app.config"); container.addListener(new ContextLoaderListener(context)); ServletRegistration.Dynamic dispatcher = container .addServlet("dispatcher", new DispatcherServlet(context)); dispatcher.setLoadOnStartup(1); dispatcher.addMapping("/"); } }

Java and annotation configuration offers many advantages. Usually it leads to shorter and more concise configuration and annotations provide more context to declarations, as it's co-located with the code that they configure.

But this is not always a preferable or even possible way. For example some developers may prefer keeping their code and configuration separated, or you may need to work with third party code that you can't modify.

6. Conclusion

In this article we covered different ways to configure a DispatcherServlet in Spring 3.2+ and it's up to you to decide which one to use based on your preferences. Spring will accommodate to your decision whatever you choose.

You can find the source code from this article on Github here and here.