Was ist Dispatcher Servlet im Frühjahr?

195

In diesem Bild (das ich von hier erhalten habe ) sendet die HTTP- Anforderung etwas an das Dispatcher-Servlet.

Geben Sie hier die Bildbeschreibung ein

Meine Frage ist, was macht Dispatcher Servlet ?

Ist es so etwas wie das Abrufen der Informationen von der Webseite und das Übertragen an den Controller?

Kevin
quelle

Antworten:

202

Die Aufgabe des DispatcherServlets besteht darin, einen eingehenden URI zu verwenden und die richtige Kombination von Handlern (im Allgemeinen Methoden für Controller- Klassen) und Ansichten (im Allgemeinen JSPs) zu finden, die zusammen die Seite oder Ressource bilden, die an diesem Speicherort gefunden werden soll.

Ich könnte haben

  • eine Datei /WEB-INF/jsp/pages/Home.jsp
  • und eine Methode für eine Klasse

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

Das Dispatcher-Servlet ist das Bit, das "weiß", diese Methode aufzurufen, wenn ein Browser die Seite anfordert, und ihre Ergebnisse mit der passenden JSP-Datei zu kombinieren, um ein HTML-Dokument zu erstellen.

Wie dies erreicht wird, hängt stark von der Konfiguration und der Spring-Version ab.

Es gibt auch keinen Grund, warum das Endergebnis Webseiten sein müssen. Es kann dasselbe tun, um RMI- Endpunkte zu lokalisieren , SOAP- Anforderungen zu verarbeiten und alles, was in ein Servlet gelangen kann.

Affe
quelle
4
Tolle Antwort, jetzt eine Frage, warum das DispatcherServlet auch den Klassennamen und den Methodennamen identifiziert. Können Sie mir ein Beispiel für eine Konfiguration zeigen, in der ich zwei Klassen und zwei Methodennamen habe und wie DispatcherServlet die richtige Anfrage abfängt?
Kevin
10
Es durchsucht tatsächlich den Klassenpfad beim Start nach dieser Annotation und erstellt eine Zuordnung von "/pages/Home.html" zur Class + -Methode. Wenn Sie zwei Methoden hätten, die beide "/pages/Home.html" ohne weitere Einschränkungen in ihrer Anmerkung hatten, wäre dies ein Fehler und würde Ausnahmen bei Ihnen auslösen. Sie können es auch mit XML verbinden, wenn Sie altmodisch sind.
Affe
2
Benötigen wir eine Dispatcher ServletXML-Datei, wenn wir Annotation Based verwenden @RestController?
Viper
1
@viper in web.xml müssen wir immer das Dispatcher-Servlet konfigurieren, obwohl Sie Anmerkungen oder XML-Konfigurationen verwenden
Mahender Reddy Yasa
Gibt es eine andere Art von Servlet?
Minh Nghĩa
72

In Spring MVC durchlaufen alle eingehenden Anforderungen ein einziges Servlet. Dieses Servlet - DispatcherServlet- ist der Frontcontroller. Der Front-Controller ist ein typisches Entwurfsmuster in der Entwicklung von Webanwendungen. In diesem Fall empfängt ein einzelnes Servlet alle Anforderungen und überträgt sie an alle anderen Komponenten der Anwendung.

Die Aufgabe des DispatcherServletbesteht darin, eine Anforderung an den spezifischen Spring MVC-Controller zu senden.

Normalerweise haben wir viele Controller und DispatcherServletverweisen auf einen der folgenden Mapper, um den Ziel-Controller zu bestimmen:

Wenn keine Konfiguration durchgeführt wird, die DispatcherServletAnwendungen BeanNameUrlHandlerMappingund DefaultAnnotationHandlerMappingstandardmäßig aktiviert .

Wenn der Zielcontroller identifiziert ist, DispatcherServletsendet er eine Anforderung an ihn. Der Controller führt einige Arbeiten gemäß der Anforderung aus (oder delegiert sie an die anderen Objekte) und kehrt DispatcherServletmit dem Modell und dem Namen der Ansicht zu dem zurück.

Der Name der Ansicht ist nur ein logischer Name. Dieser logische Name wird dann verwendet, um nach der tatsächlichen Ansicht zu suchen (um eine Kopplung mit dem Controller und einer bestimmten Ansicht zu vermeiden). Verweist dann DispatcherServletauf ViewResolverund ordnet den logischen Namen der Ansicht der spezifischen Implementierung der Ansicht zu.

Einige mögliche Implementierungen von ViewResolversind:

Wenn der DispatcherServletdie Ansicht bestimmt, in der die Ergebnisse angezeigt werden, wird sie als Antwort gerendert.

Schließlich DispatcherServletgibt das ResponseObjekt an den Client zurück.

HDJEMAI
quelle
47

DispatcherServletist die Implementierung des Front-Controller-Musters durch Spring MVC .

Siehe Beschreibung in den Spring-Dokumenten hier .

Im Wesentlichen handelt es sich um ein Servlet, das die eingehende Anforderung entgegennimmt und die Verarbeitung dieser Anforderung an einen von mehreren Handlern delegiert, deren Zuordnung in der DispatcherServletKonfiguration spezifisch ist .

Skaffman
quelle
Ist es so etwas wie Ereignisse in Flex, bei denen ich Versandereignisse von einer MXML zu einer anderen oder zu einem Server erhalte? Kann ich mehr als ein DispatcherServlet in meiner Anwendung haben? Haben alle Klassendateien ein separates DispatcherServlet?
Kevin
Es gibt normalerweise nur einen Frontcontroller. Dies ist unabhängig von den Modellen und Ansichten, die Sie haben. Es bringt nur bestimmte Modelle und Ansichten zusammen.
BalusC
2
@theband: Sie können mehrere haben DispatcherServlets, wenn Ihre Architektur auf diese Weise sinnvoller ist, aber normalerweise gibt es keinen Grund dafür.
Skaffman
47

Ich weiß, dass diese Frage bereits als gelöst markiert ist, aber ich möchte ein neueres Bild hinzufügen, das dieses Muster ausführlich erklärt (Quelle: Frühling in Aktion 4):

Geben Sie hier die Bildbeschreibung ein

Erläuterung

Wenn die Anforderung den Browser verlässt (1) , enthält sie Informationen darüber, wonach der Benutzer fragt. Zumindest trägt die Anfrage die angeforderte URL. Es kann jedoch auch zusätzliche Daten enthalten, z. B. die vom Benutzer in einem Formular übermittelten Informationen.

Die erste Station auf den Reisen der Anfrage ist das DispatcherServlet von Spring. Wie die meisten Java-basierten Webframeworks leitet Spring MVC Anforderungen über ein einziges Front-Controller-Servlet. Ein Front-Controller ist ein gängiges Webanwendungsmuster, bei dem ein einzelnes Servlet die Verantwortung für eine Anforderung an andere Komponenten einer Anwendung delegiert, um die tatsächliche Verarbeitung durchzuführen. Im Fall von Spring MVC ist DispatcherServlet der Front-Controller. Die Aufgabe des DispatcherServlets besteht darin, die Anforderung an einen Spring MVC-Controller weiterzuleiten. Ein Controller ist eine Spring-Komponente, die die Anforderung verarbeitet. Eine typische Anwendung kann jedoch mehrere Controller haben, und DispatcherServlet benötigt Hilfe bei der Entscheidung, an welchen Controller die Anforderung gesendet werden soll. Das DispatcherServlet konsultiert also eine oder mehrere Handlerzuordnungen (2).um herauszufinden, wo der nächste Stopp der Anfrage sein wird. Bei der Handlerzuordnung wird bei der Entscheidung besonders auf die URL geachtet, die von der Anforderung getragen wird. Sobald ein geeigneter Controller ausgewählt wurde, sendet DispatcherServlet die Anforderung auf seinem fröhlichen Weg an den ausgewählten Controller (3).. Bei der Steuerung gibt die Anforderung ihre Nutzlast (die vom Benutzer übermittelten Informationen) ab und wartet geduldig, während die Steuerung diese Informationen verarbeitet. (Tatsächlich führt eine gut konzipierte Steuerung selbst nur wenig oder gar keine Verarbeitung durch und delegiert stattdessen die Verantwortung für die Geschäftslogik an ein oder mehrere Serviceobjekte.) Die von einer Steuerung ausgeführte Logik führt häufig zu Informationen, auf die zurückgeführt werden muss der Benutzer und im Browser angezeigt. Diese Informationen werden als Modell bezeichnet. Das Zurücksenden von Rohdaten an den Benutzer reicht jedoch nicht aus - sie müssen in einem benutzerfreundlichen Format, normalerweise HTML, formatiert sein. Dazu müssen die Informationen einer Ansicht übergeben werden, normalerweise einer JavaServer Page (JSP). Eines der letzten Dinge, die ein Controller tut, ist das Packen der Modelldaten und das Identifizieren des Namens einer Ansicht, die die Ausgabe rendern soll. Anschließend wird die Anforderung zusammen mit dem Modell- und Ansichtsnamen an das DispatcherServlet zurückgesendet(4) . Damit der Controller nicht an eine bestimmte Ansicht gekoppelt wird, identifiziert der an DispatcherServlet zurückgegebene Ansichtsname eine bestimmte JSP nicht direkt. Dies bedeutet nicht unbedingt, dass es sich bei der Ansicht um eine JSP handelt. Stattdessen enthält es nur einen logischen Namen, der zum Nachschlagen der tatsächlichen Ansicht verwendet wird, die das Ergebnis erzeugt. Das DispatcherServlet konsultiert einen Ansichtsauflöser (5) , um den logischen Ansichtsnamen einer bestimmten Ansichtsimplementierung zuzuordnen, die eine JSP sein kann oder nicht. Nachdem DispatcherServlet nun weiß, in welcher Ansicht das Ergebnis gerendert wird, ist der Auftrag der Anforderung fast abgeschlossen. Die letzte Station ist die Umsetzung der Ansicht (6), normalerweise eine JSP, in der die Modelldaten bereitgestellt werden. Die Aufgabe der Anfrage ist endlich erledigt. Die Ansicht verwendet die Modelldaten, um eine Ausgabe zu rendern, die vom (nicht so fleißigen) Antwortobjekt (7) an den Client zurückgesendet wird .

Eduardo
quelle
Ich habe eine Frage, wie es die Ansicht auswählt, wenn ein JSON-Objekt zurückgegeben wird, das wir im Browser sehen. Kehrt es zu demselben URI zurück, wenn keine logische Ansicht ausgewählt ist?
Nesrin
1
@Nesrin Es ist Ewigkeiten her, seit Sie gefragt haben, aber hier ist eine Antwort: Sie haben eine spezielle Anmerkung direkt über der @Controlleraufgerufenen Methode eingefügt, die @ResponseBodyangibt, dass die zurückgegebene Antwort direkt auf den HTTP-Antworttext geschrieben werden soll, nicht in ein Modell eingefügt oder als Ansicht aufgelöst werden soll .
Dashboard
6

Wir können sagen, dass wir uns DispatcherServletin Spring MVC um alles kümmern.

Beim Start des Webcontainers:

  1. DispatcherServletwird durch Aufrufen der init()Methode geladen und initialisiert
  2. init()of DispatcherServletwird versuchen, das Spring-Konfigurationsdokument mit Namenskonventionen "servlet_name-servlet.xml"zu identifizieren, da dann alle Beans identifiziert werden können.

Beispiel:

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

DispatcherServletErfassen Sie also im Allgemeinen den Anforderungs-URI und übergeben Sie ihn an HandlerMapping. HandlerMappingSearch Mapping Bean mit der Methode des Controllers, wobei der Controller den logischen Namen zurückgibt (Ansicht). Dann wird diese logischen Namen zu senden DispatcherServletdurch HandlerMapping. Dann DispatcherServletsagen ViewResolvervolle Lage Blick zu geben , indem Präfix und Suffix, dann DispatcherServletgibt Ansicht an den Client.

user2663609
quelle
Dies ist eine schöne Erklärung. Ihr Punkt Nummer 2 besagt, dass das DispatcherServlet versucht, das Spring-Konfigurationsdokument mit Namenskonventionen wie "servlet_name-servlet.xml" zu identifizieren. Ich habe jedoch Projekte gesehen, die nur Namen wie "Dispatcher" verwendeten, und es funktioniert gut. Das habe ich auch versucht. Aber ich weiß nicht warum?
Subhasish Bhattacharjee
0

Der Dispatcher-Controller wird in der Abbildung angezeigt. Alle eingehenden Anforderungen werden vom Dispatcher-Servlet abgefangen, das als Front-Controller fungiert. Das Dispatcher-Servlet erhält aus der XML-Datei einen Eintrag für die Handlerzuordnung und leitet die Anforderung an den Controller weiter.

Anjali Shrivas
quelle
-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>
kartik
quelle