Qu'est-ce que Dispatcher Servlet au printemps?


195

Dans cette image (que j'ai obtenue d' ici ), la requête HTTP envoie quelque chose à Dispatcher Servlet.

entrez la description de l'image ici

Ma question est de savoir ce que fait Dispatcher Servlet ?

S'agit-il de récupérer les informations de la page Web et de les envoyer au contrôleur?

Réponses:


202

Le travail du DispatcherServlet consiste à prendre un URI entrant et à trouver la bonne combinaison de gestionnaires (généralement des méthodes sur les classes Controller ) et de vues (généralement des JSP) qui se combinent pour former la page ou la ressource qui est censée se trouver à cet emplacement.

je pourrais avoir

  • un fichier /WEB-INF/jsp/pages/Home.jsp
  • et une méthode sur une classe

    @RequestMapping(value="/pages/Home.html")
    private ModelMap buildHome() {
        return somestuff;
    }

Le servlet Dispatcher est le bit qui "sait" pour appeler cette méthode lorsqu'un navigateur demande la page et pour combiner ses résultats avec le fichier JSP correspondant pour créer un document html.

La façon dont il y parvient varie considérablement selon la configuration et la version de Spring.

Il n'y a également aucune raison pour que le résultat final soit des pages Web. Il peut faire la même chose pour localiser les points de terminaison RMI , gérer les requêtes SOAP , tout ce qui peut entrer dans un servlet.


4
Grande riposte, maintenant une question de savoir comment le DispatcherServlet identifie également le nom de classe et le nom de méthode. Pouvez-vous me montrer un exemple de configuration où j'ai deux classes et deux noms de méthode et comment DispatcherServlet intercepte la bonne demande.
Kevin

10
Il scanne en fait le chemin de classe au démarrage pour cette annotation et fait un mappage de "/pages/Home.html" avec la méthode Class +. Si vous aviez deux méthodes qui avaient toutes deux "/pages/Home.html" sans autres restrictions dans leur annotation, ce serait une erreur et cela vous lancerait des exceptions. Vous pouvez également le connecter avec XML si vous êtes oldschool.
Affe

2
Avons-nous besoin d'un Dispatcher Servletfichier xml lors de l'utilisation d'annotations @RestController?
viper

1
@viper dans web.xml, nous devons toujours configurer le servlet du répartiteur même si vous utilisez des annotations ou des configurations xml
Mahender Reddy Yasa

Existe-t-il un autre type de servlet?
Minh Nghĩa

72

Dans Spring MVC, toutes les demandes entrantes passent par une seule servlet. Cette servlet - DispatcherServlet- est le contrôleur frontal. Le contrôleur frontal est un modèle de conception typique dans le développement d'applications Web. Dans ce cas, un seul servlet reçoit toutes les demandes et les transfère à tous les autres composants de l'application.

La tâche du DispatcherServletest d'envoyer la demande au contrôleur Spring MVC spécifique.

Habituellement, nous avons beaucoup de contrôleurs et nous nous DispatcherServletréférons à l'un des mappeurs suivants afin de déterminer le contrôleur cible:

Si aucune configuration n'est effectuée, les DispatcherServletutilisations BeanNameUrlHandlerMappinget DefaultAnnotationHandlerMappingpar défaut.

Lorsque le contrôleur cible est identifié, la DispatcherServletdemande lui est envoyée. Le contrôleur effectue un certain travail en fonction de la demande (ou le délègue aux autres objets), et revient au DispatcherServletavec le modèle et le nom de la vue.

Le nom de la vue n'est qu'un nom logique. Ce nom logique est ensuite utilisé pour rechercher la vue réelle (pour éviter le couplage avec le contrôleur et la vue spécifique). Fait ensuite DispatcherServletréférence à ViewResolveret mappe le nom logique de la vue sur l'implémentation spécifique de la vue.

Quelques implémentations possibles de ViewResolver:

Lorsque le DispatcherServletdétermine la vue qui affichera les résultats, il sera rendu comme réponse.

Enfin, le DispatcherServletretourne l' Responseobjet au client.


47

DispatcherServletest l'implémentation par Spring MVC du modèle de contrôleur frontal .

Voir la description dans les documents Spring ici .

Il s'agit essentiellement d'un servlet qui prend la demande entrante et délègue le traitement de cette demande à l'un des nombreux gestionnaires, dont le mappage est spécifique à la DispatcherServletconfiguration.


Est-ce quelque chose comme des événements dans Flex, où j'obtiens des événements de répartition d'un MXML à un autre ou vers un serveur. Puis-je avoir plus d'un DispatcherServlet dans mon application. Chaque fichier de classe a-t-il un DispatcherServlet distinct?
Kevin

Il n'y a généralement qu'un seul contrôleur frontal. Cela indépendamment des modèles et des vues que vous possédez. Il rassemble simplement des modèles et des vues spécifiques.
BalusC

2
@theband: Vous pouvez en avoir plusieurs DispatcherServlets, si votre architecture est plus logique de cette façon, mais il n'y a généralement aucune raison de le faire.
skaffman

47

Je sais que cette question est déjà marquée comme résolue mais je veux ajouter une image plus récente expliquant ce modèle en détail (source: ressort en action 4):

entrez la description de l'image ici

Explication

Lorsque la demande quitte le navigateur (1) , elle transporte des informations sur ce que l'utilisateur demande. Au moins, la demande portera l'URL demandée. Mais il peut également contenir des données supplémentaires, telles que les informations soumises sous une forme par l'utilisateur.

Le premier arrêt dans les déplacements de la demande est à Spring's DispatcherServlet. Comme la plupart des frameworks Web basés sur Java, Spring MVC achemine les demandes via un seul servlet de contrôleur frontal. Un contrôleur frontal est un modèle d'application Web commun où une seule servlet délègue la responsabilité d'une demande à d'autres composants d'une application pour effectuer un traitement réel. Dans le cas de Spring MVC, DispatcherServlet est le contrôleur frontal. Le travail du DispatcherServlet consiste à envoyer la demande à un contrôleur Spring MVC. Un contrôleur est un composant Spring qui traite la demande. Mais une application typique peut avoir plusieurs contrôleurs, et DispatcherServlet a besoin d'aide pour décider à quel contrôleur envoyer la demande. Le DispatcherServlet consulte donc un ou plusieurs mappages de gestionnaires (2)pour savoir où sera le prochain arrêt de la demande. Le mappage du gestionnaire accorde une attention particulière à l'URL portée par la demande lors de la prise de décision. Une fois qu'un contrôleur approprié a été choisi, DispatcherServlet envoie la demande sur son joyeux chemin au contrôleur choisi (3). Au niveau du contrôleur, la demande abandonne sa charge utile (les informations soumises par l'utilisateur) et attend patiemment pendant que le contrôleur traite ces informations. (En fait, un contrôleur bien conçu exécute peu ou pas de traitement lui-même et délègue plutôt la responsabilité de la logique métier à un ou plusieurs objets de service.) La logique exécutée par un contrôleur entraîne souvent certaines informations qui doivent être renvoyées à l'utilisateur et affiché dans le navigateur. Cette information est appelée modèle. Mais renvoyer des informations brutes à l'utilisateur n'est pas suffisant - il doit être formaté dans un format convivial, typiquement HTML. Pour cela, les informations doivent être fournies à une vue, généralement une page JavaServer (JSP). L'une des dernières actions d'un contrôleur consiste à empaqueter les données du modèle et à identifier le nom d'une vue qui doit restituer la sortie. Il renvoie ensuite la demande, ainsi que le modèle et le nom de la vue, au DispatcherServlet(4) . Pour que le contrôleur ne soit pas couplé à une vue particulière, le nom de la vue renvoyé à DispatcherServlet n'identifie pas directement une JSP spécifique. Cela ne suggère même pas nécessairement que la vue est une JSP. Au lieu de cela, il porte uniquement un nom logique qui sera utilisé pour rechercher la vue réelle qui produira le résultat. Le DispatcherServlet consulte un résolveur de vue (5) pour mapper le nom de la vue logique à une implémentation de vue spécifique, qui peut ou non être un JSP. Maintenant que DispatcherServlet sait quelle vue affichera le résultat, le travail de la demande est presque terminé. Son dernier arrêt est à la mise en œuvre de la vue (6), généralement un JSP, où il fournit les données du modèle. Le travail de la demande est enfin terminé. La vue utilisera les données du modèle pour restituer la sortie qui sera renvoyée au client par l'objet de réponse (pas si dur) (7) .


J'ai une question s'il vous plaît, comment il sélectionne la vue en cas de retour d'un objet JSON que nous voyons dans le navigateur, revient-il au même URI s'il n'y a pas de vue logique sélectionnée?
Nesrin

1
@Nesrin ça fait longtemps que vous ne l'avez pas demandé mais voici une réponse: vous mettez une annotation spéciale juste au-dessus de la @Controllerméthode appelée @ResponseBodyindiquant que la réponse retournée doit être directement écrite sur le corps de la réponse HTTP, ne pas être placée dans un modèle ou être résolue comme vue que ce soit .
tableau de bord

6

On peut dire comme DispatcherServlets'occuper de tout dans Spring MVC.

Au démarrage du conteneur Web:

  1. DispatcherServletsera chargé et initialisé en appelant la init()méthode
  2. init()of DispatcherServletessaiera d'identifier le document de configuration Spring avec des conventions de dénomination comme "servlet_name-servlet.xml"alors tous les beans peuvent être identifiés.

Exemple:

public class DispatcherServlet extends HttpServlet {

    ApplicationContext ctx = null;

    public void init(ServletConfig cfg){
        // 1. try to get the spring configuration document with default naming conventions
        String xml = "servlet_name" + "-servlet.xml";

        //if it was found then creates the ApplicationContext object
        ctx = new XmlWebApplicationContext(xml);
    }
    ...
}

Donc, en général, DispatcherServletcapturez l'URI de la demande et passez-le à HandlerMapping. HandlerMappingbean de mappage de recherche avec la méthode du contrôleur, où le contrôleur renvoie un nom logique (vue). Ensuite, ce nom logique est envoyé DispatcherServletpar HandlerMapping. DispatcherServletDites ensuite ViewResolverde donner l'emplacement complet de la vue en ajoutant le préfixe et le suffixe, puis DispatcherServletdonnez la vue au client.


Ceci est une belle explication. Votre point numéro 2 indique que le DispatcherServlet essaiera d'identifier le document de configuration Spring avec des conventions de dénomination comme "servlet_name-servlet.xml". Cependant, j'ai vu des projets qui utilisaient uniquement le nom comme "dispatcher", et cela fonctionne très bien. Moi aussi, j'ai essayé ça. Mais je ne sais pas pourquoi?
Subhasish Bhattacharjee

0

Le contrôleur de répartiteur est affiché sur la figure, toutes les demandes entrantes sont interceptées par le servlet de répartiteur qui fonctionne comme contrôleur frontal. Le servlet dispatcher obtient une entrée pour le mappage de gestionnaire à partir du fichier XML et forpose la demande au contrôleur.


-1
<?xml version='1.0' encoding='UTF-8' ?>
<!-- was: <?xml version="1.0" encoding="UTF-8"?> -->
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
       http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
        http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
               http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd">

    <bean class="org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping"/>
    <context:component-scan base-package="com.demo" />
    <context:annotation-config />

    <mvc:annotation-driven />


    <bean id="viewResolver"
          class="org.springframework.web.servlet.view.InternalResourceViewResolver"
          p:prefix="/WEB-INF/jsp/"
          p:suffix=".jsp" />

    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="datasource" />
    </bean> 

          <bean id="datasource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver" />  
        <property name="url" value="jdbc:mysql://localhost:3306/employee" />
        <property name="username" value="username" />
        <property name="password" value="password" />
    </bean> 

</beans>
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.