Che cos'è Servlet Dispatcher in primavera?


195

In questa immagine (che ho ottenuto da qui ), la richiesta HTTP invia qualcosa al Servlet Dispatcher.

inserisci qui la descrizione dell'immagine

La mia domanda è cosa fa Servlet Dispatcher ?

È qualcosa come ottenere le informazioni lanciate dalla pagina Web e lanciarle al controller?

Risposte:


202

Il compito di DispatcherServlet è di prendere un URI in entrata e trovare la giusta combinazione di gestori (generalmente metodi su Controller classi ) e viste (generalmente JSP) che si combinano per formare la pagina o la risorsa che dovrebbe essere trovata in quella posizione.

potrei avere

  • un file /WEB-INF/jsp/pages/Home.jsp
  • e un metodo su una classe

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

Il servlet Dispatcher è il bit che "sa" di chiamare quel metodo quando un browser richiede la pagina e di combinare i risultati con il file JSP corrispondente per creare un documento html.

In che modo ciò varia ampiamente con la configurazione e la versione Spring.

Non vi è inoltre alcun motivo per cui il risultato finale debba essere pagine Web. Può fare la stessa cosa per individuare gli endpoint RMI , gestire le richieste SOAP , tutto ciò che può entrare in un servlet.


4
Ottima risposta, ora una domanda su come mai DispatcherServlet identifica anche il nome della classe e il nome del metodo. Potete mostrarmi un esempio di una configurazione in cui ho due classi e due nomi di metodo e come DispatcherServlet riceve la richiesta giusta.
Kevin,

10
Effettua la scansione del percorso della classe all'avvio per quella annotazione e crea una mappatura di "/pages/Home.html" sul metodo Class +. Se avessi due metodi che avevano entrambi "/pages/Home.html" senza altre restrizioni nella loro annotazione, sarebbe un errore e genererebbe eccezioni. Puoi anche collegarlo con XML se sei oldschool.
Affe,

2
È necessario un Dispatcher Servletfile XML quando si utilizza Annotation Based @RestController?
Vipera,

1
@viper in web.xml dobbiamo sempre configurare il servlet dispatcher anche se usi le annotazioni o le configurazioni xml
Mahender Reddy Yasa

C'è qualche altro tipo di servlet?
Minh Nghĩa,

72

In Spring MVC, tutte le richieste in arrivo passano attraverso un unico servlet. Questo servlet - DispatcherServlet- è il controller anteriore. Il front controller è un tipico modello di progettazione nello sviluppo di applicazioni web. In questo caso, un singolo servlet riceve tutte le richieste e le trasferisce a tutti gli altri componenti dell'applicazione.

Il compito di DispatcherServletè inviare una richiesta al controller Spring MVC specifico.

Di solito abbiamo molti controller e ci si DispatcherServletriferisce a uno dei seguenti mappatori per determinare il controller di destinazione:

Se non viene eseguita alcuna configurazione, gli DispatcherServletusi BeanNameUrlHandlerMappinge DefaultAnnotationHandlerMappingper impostazione predefinita.

Quando viene identificato il controller di destinazione, DispatcherServletinvia la richiesta ad esso. Il controller esegue alcuni lavori in base alla richiesta (o delegarlo agli altri oggetti) e ritorna al DispatcherServletcon il Modello e il nome della Vista.

Il nome della vista è solo un nome logico. Questo nome logico viene quindi utilizzato per cercare la vista effettiva (per evitare l'accoppiamento con il controller e la vista specifica). Quindi DispatcherServletfa riferimento a ViewResolvere mappa il nome logico della vista all'implementazione specifica della vista.

Alcune possibili implementazioni di ViewResolversono:

Quando DispatcherServletdetermina la vista che visualizzerà i risultati, verrà visualizzato come risposta.

Infine, DispatcherServletrestituisce l' Responseoggetto al client.


47

DispatcherServletè l'implementazione di Spring MVC del modello di controller frontale .

Vedi la descrizione nei documenti di primavera qui .

In sostanza, è un servlet che accetta la richiesta in arrivo e delega l'elaborazione di quella richiesta a uno dei numerosi gestori, la cui mappatura è specifica nella DispatcherServletconfigurazione.


È qualcosa di simile agli eventi in Flex, in cui ottengo eventi di invio da un MXML all'altro o al server. Posso avere più di un DispatcherServlet nella mia richiesta. Ogni file di classe ha un DispatcherServlet separato.
Kevin,

Di solito c'è solo un controller frontale. Questo è indipendentemente dai modelli e dalle viste che hai. Riunisce solo modelli e viste specifici.
BalusC,

2
@theband: puoi averne più DispatcherServlets, se la tua architettura ha più senso in questo modo, ma di solito non c'è motivo.
skaffman,

47

So che questa domanda è già contrassegnata come risolta, ma voglio aggiungere un'immagine più recente che spieghi questo schema in dettaglio (fonte: primavera in azione 4):

inserisci qui la descrizione dell'immagine

Spiegazione

Quando la richiesta lascia il browser (1) , contiene informazioni su ciò che l'utente chiede. Almeno, la richiesta porterà l'URL richiesto. Ma può anche contenere dati aggiuntivi, come le informazioni inviate in un modulo dall'utente.

La prima fermata nei viaggi della richiesta è Spring's DispatcherServlet. Come la maggior parte dei framework Web basati su Java, le richieste Spring MVC tramite una servlet del front controller anteriore. Un front controller è un modello di applicazione Web comune in cui un singolo servlet delega la responsabilità di una richiesta ad altri componenti di un'applicazione per eseguire l'elaborazione effettiva. Nel caso di Spring MVC, DispatcherServlet è il controller anteriore. Il compito di DispatcherServlet è di inviare la richiesta a un controller Spring MVC. Un controller è un componente Spring che elabora la richiesta. Ma un'applicazione tipica può avere diversi controller e DispatcherServlet ha bisogno di aiuto per decidere a quale controller inviare la richiesta. Quindi DispatcherServlet consulta uno o più mapping dei gestori (2)per capire dove sarà la prossima fermata della richiesta. La mappatura del gestore presta particolare attenzione all'URL trasportato dalla richiesta quando prende la sua decisione. Una volta scelto un controller appropriato, DispatcherServlet invia la richiesta nel modo giusto al controller scelto (3). Nel controller, la richiesta abbandona il suo payload (le informazioni inviate dall'utente) e attende pazientemente mentre il controller elabora tali informazioni. (In realtà, un controller ben progettato esegue poca o nessuna elaborazione stessa e delega invece la responsabilità della logica aziendale a uno o più oggetti di servizio.) La logica eseguita da un controller spesso porta ad alcune informazioni che devono essere riportate a l'utente e visualizzato nel browser. Questa informazione è denominata modello. Ma l'invio di informazioni non elaborate all'utente non è sufficiente: deve essere formattato in un formato intuitivo, in genere HTML. A tale scopo, è necessario fornire le informazioni a una vista, in genere una pagina Java Server (JSP). Una delle ultime cose che un controller fa è impacchettare i dati del modello e identificare il nome di una vista che dovrebbe rendere l'output. Invia quindi la richiesta, insieme al modello e al nome della vista, al DispatcherServlet(4) . In modo che il controller non venga accoppiato a una vista particolare, il nome della vista restituito a DispatcherServlet non identifica direttamente un JSP specifico. Non suggerisce nemmeno necessariamente che la vista sia un JSP. Al contrario, porta solo un nome logico che verrà utilizzato per cercare la vista effettiva che produrrà il risultato. DispatcherServlet consulta un risolutore di viste (5) per mappare il nome della vista logica su un'implementazione specifica della vista, che può essere o meno un JSP. Ora che DispatcherServlet sa quale vista renderà il risultato, il lavoro della richiesta è quasi finito. La sua fermata finale è all'implementazione della vista (6) , in genere un JSP, in cui fornisce i dati del modello. Il lavoro della richiesta è finalmente terminato. La vista utilizzerà i dati del modello per eseguire il rendering dell'output che verrà riportato al client dall'oggetto di risposta (non così laborioso) (7) .


Ho una domanda, per favore, come seleziona la vista in caso di restituzione di un oggetto JSON che vediamo nel browser, ritorna allo stesso URI se non è selezionata alcuna vista logica?
Nesrin,

1
@Nesrin sono passati anni da quando lo hai chiesto, ma ecco una risposta: hai messo un'annotazione speciale appena sopra il @Controllermetodo chiamato @ResponseBodyindicando che la risposta restituita dovrebbe essere scritta direttamente sul corpo della risposta HTTP, non essere inserita in un Modello o essere risolta come vista di sorta .
cruscotto

6

Possiamo dire come DispatcherServletprendersi cura di tutto in Spring MVC.

All'avvio del contenitore Web:

  1. DispatcherServletverrà caricato e inizializzato mediante il init()metodo call
  2. init()of DispatcherServletproverà a identificare il documento di configurazione di Spring con convenzioni di denominazione come "servlet_name-servlet.xml"allora tutti i bean possono essere identificati.

Esempio:

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

Quindi, in genere DispatcherServletacquisisci l'URI della richiesta e passa a HandlerMapping. HandlerMappingcerca il bean di mappatura con il metodo del controller, in cui il controller restituisce il nome logico (vista). Quindi questo nome logico viene inviato DispatcherServletda HandlerMapping. Quindi DispatcherServletdire ViewResolverdi dare la posizione completa della vista aggiungendo prefisso e suffisso, quindi DispatcherServletdare vista al client.


Questa è una bella spiegazione Il punto numero 2 indica che DispatcherServlet tenterà di identificare il documento di configurazione di Spring con convenzioni di denominazione come "nome_ servlet-servlet.xml". Tuttavia, ho visto progetti che utilizzavano solo il nome "dispatcher" e funziona perfettamente. Anch'io ci ho provato. Ma non so perché?
Subhasish Bhattacharjee,

0

Il controller del dispatcher viene visualizzato nella figura in cui tutta la richiesta in arrivo viene intercettata dal servlet del dispatcher che funge da front controller. Il servlet dispatcher ottiene una voce per la mappatura del gestore dal file XML e invia la richiesta al controller.


-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>
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.