¿Qué es el servlet Dispatcher en primavera?

195

En esta imagen (que obtuve de aquí ), la solicitud HTTP envía algo al Dispatcher Servlet.

ingrese la descripción de la imagen aquí

Mi pregunta es ¿qué hace Disletcher Servlet ?

¿Es algo así como obtener la información lanzada desde la página web y lanzarla al controlador?

Kevin
fuente

Respuestas:

202

El trabajo del DispatcherServlet es tomar un URI entrante y encontrar la combinación correcta de controladores (generalmente métodos en clases de Controlador ) y vistas (generalmente JSP) que se combinan para formar la página o recurso que se supone que se encuentra en esa ubicación.

puede que tenga

  • un archivo /WEB-INF/jsp/pages/Home.jsp
  • y un método en una clase

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

El servlet Dispatcher es el bit que "sabe" llamar a ese método cuando un navegador solicita la página y combinar sus resultados con el archivo JSP correspondiente para crear un documento html.

La forma en que se logra esto varía ampliamente con la configuración y la versión de Spring.

Tampoco hay razón para que el resultado final sea páginas web. Puede hacer lo mismo para ubicar puntos finales RMI , manejar solicitudes SOAP , cualquier cosa que pueda entrar en un servlet.

Affe
fuente
44
Gran respuesta, ahora una pregunta de cómo el DispatcherServlet identifica el nombre de la clase y el nombre del método también. ¿Me puede mostrar un ejemplo de una configuración donde tengo dos clases y dos nombres de métodos y cómo DispatcherServlet capta la solicitud correcta?
Kevin
10
En realidad, escanea la ruta de clase en el inicio para esa anotación y realiza una asignación de "/pages/Home.html" al Método de Class +. Si tuviera dos métodos que tenían "/pages/Home.html" sin otras restricciones en su anotación, eso sería un error y generará excepciones. También puedes conectarlo con XML si eres de la vieja escuela.
Affe
2
¿Necesitamos un Dispatcher Servletarchivo xml cuando utilizamos Anotación basada @RestController?
Viper
1
@viper en web.xml siempre necesitamos configurar el servlet del despachador aunque use anotaciones o configuraciones xml
Mahender Reddy Yasa
¿Hay algún otro tipo de servlet?
Minh Nghĩa
72

En Spring MVC, todas las solicitudes entrantes pasan por un único servlet. Este servlet - DispatcherServlet- es el controlador frontal. El controlador frontal es un patrón de diseño típico en el desarrollo de aplicaciones web. En este caso, un solo servlet recibe todas las solicitudes y las transfiere a todos los demás componentes de la aplicación.

La tarea del DispatcherServletes enviar una solicitud al controlador Spring MVC específico.

Por lo general, tenemos muchos controladores y se DispatcherServletrefiere a uno de los siguientes mapeadores para determinar el controlador de destino:

Si no se realiza ninguna configuración, los DispatcherServletusos BeanNameUrlHandlerMappingy DefaultAnnotationHandlerMappingpor defecto.

Cuando se identifica el controlador de destino, le DispatcherServletenvía la solicitud. El controlador realiza un trabajo de acuerdo con la solicitud (o lo delega a los otros objetos), y regresa al DispatcherServletmodelo y al nombre de la vista.

El nombre de la Vista es solo un nombre lógico. Este nombre lógico se usa para buscar la Vista real (para evitar el acoplamiento con el controlador y la Vista específica). Luego se DispatcherServletrefiere a ViewResolvery asigna el nombre lógico de la Vista a la implementación específica de la Vista.

Algunas posibles implementaciones del ViewResolverson:

Cuando DispatcherServletdetermina la vista que mostrará los resultados, se representará como respuesta.

Finalmente, DispatcherServletdevuelve el Responseobjeto al cliente.

HDJEMAI
fuente
47

DispatcherServletes la implementación de Spring MVC del patrón del controlador frontal .

Vea la descripción en los documentos de Spring aquí .

Esencialmente, es un servlet que toma la solicitud entrante y delega el procesamiento de esa solicitud a uno de varios manejadores, cuya asignación es específica en la DispatcherServletconfiguración.

skaffman
fuente
¿Es algo así como eventos en Flex, donde obtengo eventos de envío de un MXML a otro o al servidor? ¿Puedo tener más de un DispatcherServlet en mi aplicación? ¿Cada archivo de clase tiene un DispatcherServlet separado?
Kevin
Por lo general, solo hay un controlador frontal. Esto es independientemente de los modelos y vistas que tenga. Simplemente reúne modelos y puntos de vista específicos.
BalusC
2
@theband: puede tener múltiples DispatcherServlets, si su arquitectura tiene más sentido de esa manera, pero generalmente no hay razón para hacerlo.
skaffman
47

Sé que esta pregunta ya está marcada como resuelta, pero quiero agregar una imagen más nueva que explique este patrón en detalle (fuente: spring in action 4):

ingrese la descripción de la imagen aquí

Explicación

Cuando la solicitud abandona el navegador (1) , lleva información sobre lo que el usuario solicita. Por lo menos, la solicitud llevará la URL solicitada. Pero también puede contener datos adicionales, como la información presentada en un formulario por el usuario.

La primera parada en los viajes de la solicitud es en Spring's DispatcherServlet. Como la mayoría de los frameworks web basados ​​en Java, Spring MVC canaliza las solicitudes a través de un único servlet de controlador frontal. Un controlador frontal es un patrón de aplicación web común en el que un solo servlet delega la responsabilidad de una solicitud a otros componentes de una aplicación para realizar el procesamiento real. En el caso de Spring MVC, DispatcherServlet es el controlador frontal. El trabajo del DispatcherServlet es enviar la solicitud a un controlador Spring MVC. Un controlador es un componente Spring que procesa la solicitud. Pero una aplicación típica puede tener varios controladores, y DispatcherServlet necesita ayuda para decidir a qué controlador enviar la solicitud. Entonces DispatcherServlet consulta una o más asignaciones de manejadores (2)para averiguar dónde será la próxima parada de la solicitud. La asignación del controlador presta especial atención a la URL que lleva la solicitud al tomar su decisión. Una vez que se ha elegido un controlador apropiado, DispatcherServlet envía la solicitud de forma alegre al controlador elegido (3). En el controlador, la solicitud deja caer su carga útil (la información presentada por el usuario) y espera pacientemente mientras el controlador procesa esa información. (En realidad, un controlador bien diseñado realiza poco o ningún procesamiento en sí mismo y, en su lugar, delega la responsabilidad de la lógica de negocios a uno o más objetos de servicio). La lógica realizada por un controlador a menudo da como resultado cierta información que debe llevarse de vuelta a el usuario y se muestra en el navegador. Esta información se conoce como el modelo. Pero enviar información sin procesar al usuario no es suficiente, debe formatearse en un formato fácil de usar, generalmente HTML. Para eso, la información debe darse a una vista, generalmente una página JavaServer (JSP). Una de las últimas cosas que hace un controlador es empaquetar los datos del modelo e identificar el nombre de una vista que debería representar la salida. Luego envía la solicitud, junto con el modelo y el nombre de la vista, de vuelta al DispatcherServlet(4) . Para que el controlador no se acople a una vista en particular, el nombre de la vista pasado a DispatcherServlet no identifica directamente un JSP específico. Ni siquiera sugiere necesariamente que la vista sea un JSP. En cambio, solo lleva un nombre lógico que se utilizará para buscar la vista real que producirá el resultado. El DispatcherServlet consulta una resolución de vista (5) para asignar el nombre de la vista lógica a una implementación de vista específica, que puede o no ser un JSP. Ahora que DispatcherServlet sabe qué vista representará el resultado, el trabajo de la solicitud casi ha terminado. Su última parada está en la implementación de la vista (6), generalmente un JSP, donde entrega los datos del modelo. El trabajo de la solicitud finalmente está hecho. La vista utilizará los datos del modelo para representar la salida que será transportada al cliente por el objeto de respuesta (no tan trabajador) (7) .

Eduardo
fuente
Tengo una pregunta, por favor, ¿cómo selecciona la vista en caso de devolver el objeto JSON que vemos en el navegador? ¿Vuelve al mismo URI si no hay una vista lógica seleccionada?
Nesrin
1
@Nesrin han pasado años desde que preguntaste, pero aquí hay una respuesta: colocas una anotación especial justo encima del @Controllermétodo llamado @ResponseBodyque indica que la respuesta devuelta debe escribirse directamente en el cuerpo de respuesta HTTP, no debe colocarse en un Modelo ni resolverse como una vista. .
tablero
6

Podemos decir como DispatcherServletcuidar todo en Spring MVC.

En el inicio del contenedor web:

  1. DispatcherServletse cargará e inicializará llamando al init()método
  2. init()de DispatcherServlettratará de identificar el documento de configuración de primavera con las convenciones de nomenclatura, como "servlet_name-servlet.xml"a continuación todos los granos pueden ser identificados.

Ejemplo:

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

Por lo tanto, en general, DispatcherServletURI de solicitud de captura y entrega a HandlerMapping. HandlerMappingfrijol de mapeo de búsqueda con el método del controlador, donde el controlador devuelve el nombre lógico (ver). Entonces este nombre lógico es enviado a DispatcherServletpor HandlerMapping. Luego DispatcherServletdiga ViewResolverque proporcione la ubicación completa de la vista agregando el prefijo y el sufijo, luego DispatcherServletdé la vista al cliente.

usuario2663609
fuente
Esta es una buena explicación. Su punto número 2 dice que DispatcherServlet intentará identificar el Documento de configuración de Spring con convenciones de nomenclatura como "servlet_name-servlet.xml". Sin embargo, he visto proyectos que solo usaban el nombre como "despachador", y funciona bien. Yo también lo he intentado. ¿Pero no sé por qué?
Subhasish Bhattacharjee
0

El controlador del despachador se muestra en la figura en la que todas las solicitudes entrantes son interceptadas por el servlet del despachador que funciona como controlador frontal. El servlet del despachador obtiene una entrada para la asignación del controlador del archivo XML y envía la solicitud al controlador.

Anjali Shrivas
fuente
-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
fuente