Spring中的Dispatcher Servlet是什么?


195

在此图像(我从此处获得)中,HTTP请求向Dispatcher Servlet发送了一些内容

在此处输入图片说明

我的问题是Dispatcher Servlet做什么?

是否就像从网页上获取信息并将其扔给控制器一样?

Answers:


202

DispatcherServlet的工作是获取传入的URI,并找到处理程序(通常是Controller类上的方法)和视图(通常是JSP)的正确组合,这些组合在一起以形成应该在该位置找到的页面或资源。

我可能有

  • 一份文件 /WEB-INF/jsp/pages/Home.jsp
  • 和类上的方法

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

调度的servlet是“知道”该位调用该方法,当浏览器请求的页面,其结果与匹配的JSP文件相结合,使HTML文档。

它如何完成此操作因配置和Spring版本而异。

也没有理由最终结果必须是网页。找到RMI端点,处理SOAP请求以及任何可能进入servlet的操作,它都可以做同样的事情。


4
伟大的riposte,现在是一个问题,DispatcherServlet也如何识别类名和方法名。您能告诉我一个配置示例,其中有两个类和两个方法名,以及DispatcherServlet如何捕获正确的请求。
凯文(Kevin)2010年

10
实际上,它会在启动时扫描类路径以查找该批注,并将“ /pages/Home.html”映射到“类+方法”。如果您有两个方法都具有“ /pages/Home.html”,并且其注释中没有其他限制,那将是一个错误,并且会抛出异常。如果您是老式学校,也可以将其与XML连接在一起。
Affe)

2
Dispatcher Servlet使用基于注释时是否需要一个xml文件@RestController
毒蛇

1
即使您使用批注或xml配置,在web.xml中的@viper我们也始终需要配置调度程序servlet
Mahender Reddy Yasa

还有其他类型的servlet吗?
胡志明市NGHIA

72

在Spring MVC中,所有传入请求都通过单个servlet。这个Servlet DispatcherServlet是前端控制器。前端控制器是Web应用程序开发中的典型设计模式。在这种情况下,单个servlet接收所有请求,并将它们传输到应用程序的所有其他组件。

的任务DispatcherServlet是将请求发送到特定的Spring MVC控制器。

通常,我们有很多控制器,并DispatcherServlet引用以下映射器之一来确定目标控制器:

如果不执行任何配置,则默认DispatcherServlet使用BeanNameUrlHandlerMappingDefaultAnnotationHandlerMapping

确定目标控制器后,DispatcherServlet向其发送请求。控制器根据请求执行某些工作(或将其委托给其他对象),并返回到DispatcherServletModel和View的名称。

视图的名称只是一个逻辑名称。然后使用此逻辑名搜索实际的View(以避免与控制器和特定View耦合)。然后DispatcherServletViewResolver并将View的逻辑名称映射到View的特定实现。

的一些可能的实现ViewResolver是:

DispatcherServlet确定要显示结果的视图时,它将作为响应呈现。

最后,DispatcherServletResponse对象返回给客户端。


47

DispatcherServlet是Spring MVC的前端控制器模式的实现。

此处查看Spring文档中的描述。

本质上,它是一个servlet,它接收传入的请求,并将对该请求的处理委托给多个处理程序之一,这些处理程序的映射在DispatcherServlet配置中是特定的。


这是Flex中的事件吗,我将调度事件从一个MXML发送到另一个或服务器。我的应用程序中可以有多个DispatcherServlet吗?每个类文件都有单独的DispatcherServlet吗?
凯文

通常只有一个前端控制器。这与您拥有的模型和视图无关。它只是将特定的模型和视图组合在一起。
BalusC,2010年

2
@theband:如果您的体系结构更有意义,则可以有多个DispatcherServlets,但是通常没有理由。
skaffman 2010年

47

我知道这个问题已被标记为已解决,但是我想添加一个更新的图像来详细解释此模式(来源:spring in action 4):

在此处输入图片说明

说明

当请求离开浏览器(1)时,它携带有关用户要求的信息。至少,请求将带有请求的URL。但它也可能携带其他数据,例如用户以表格形式提交的信息。

请求旅行的第一站是Spring的DispatcherServlet。像大多数基于Java的Web框架一样,Spring MVC通过单个前端控制器servlet进行请求漏斗。前端控制器是一种常见的Web应用程序模式,其中单个servlet将请求的责任委托给应用程序的其他组件以执行实际处理。对于Spring MVC,DispatcherServlet是前端控制器。DispatcherServlet的工作是将请求发送到Spring MVC控制器。控制器是处理请求的Spring组件。但是典型的应用程序可能有多个控制器,DispatcherServlet需要一些帮助来确定将请求发送到哪个控制器。因此DispatcherServlet会查询一个或多个处理程序映射(2)找出请求的下一站将在哪里。处理程序映射在做出决定时特别注意请求所携带的URL。一旦选择了合适的控制器,DispatcherServlet就会以一种快乐的方式将请求发送到所选的控制器(3)。在控制器处,请求释放其有效负载(用户提交的信息),并在控制器处理该信息时耐心等待。(实际上,一个设计良好的控制器本身很少执行处理或不执行任何处理,而是将业务逻辑的责任委托给一个或多个服务对象。)由控制器执行的逻辑通常会导致一些信息需要运回给用户并显示在浏览器中。此信息称为模型。但是,将原始信息发送回用户是不够的,需要将其格式化为用户友好的格式,通常为HTML。为此,需要将信息提供给视图,通常是JavaServer Page(JSP)。控制器要做的最后一件事是打包模型数据并标识应呈现输出的视图的名称。然后,它将请求以及模型和视图名称发送回DispatcherServlet。(4)。为了使控制器不会耦合到特定视图,传递回DispatcherServlet的视图名称不会直接标识特定的JSP。它甚至不一定暗示该视图是JSP。相反,它仅带有一个逻辑名称,该名称将用于查找将产生结果的实际视图。DispatcherServlet咨询视图解析器(5),以将逻辑视图名称映射到特定的视图实现,该实现可以是JSP,也可以不是。现在,DispatcherServlet知道哪个视图将呈现结果,请求的工作几乎结束了。它的最后一站是视图实现(6),通常是JSP,用于传递模型数据。请求的工作终于完成。该视图将使用模型数据来呈现输出,该输出将由(不是很努力的)响应对象(7)运回到客户端。


我有一个问题,在返回我们在浏览器中看到的JSON对象的情况下,它如何选择视图?如果未选择逻辑视图,它会返回相同的URI吗?
Nesrin

1
@Nesrin询问您已经很久了,但是这里有一个答案:您在@Controller称为方法的上方放置了一个特殊的注释,@ResponseBody指示返回的响应应直接写在HTTP响应主体上,而不是放在模型中或以任何视图的形式解析。
仪表板

6

可以说像DispatcherServlet照顾Spring MVC中的所有事情。

在Web容器启动时:

  1. DispatcherServlet将通过调用init()方法加载并初始化
  2. init()of DispatcherServlet将尝试使用命名约定来标识Spring Configuration Document,例如 "servlet_name-servlet.xml"可以标识所有bean。

例:

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

因此,通常DispatcherServlet捕获请求URI并移交给HandlerMappingHandlerMapping使用控制器方法搜索映射bean,其中控制器返回逻辑名(视图)。那么这个逻辑名发送到DispatcherServlet通过HandlerMapping。然后通过附加前缀和后缀来DispatcherServlet告知ViewResolver要提供完整视图的位置,然后DispatcherServlet将视图提供给客户端。


这是一个很好的解释。您的第二点说,DispatcherServlet将尝试使用诸如“ servlet_name-servlet.xml”的命名约定来识别Spring Configuration Document。但是,我看到的项目仅使用了“ dispatcher”之类的名称,并且效果很好。我也尝试过。但是我不知道为什么?
Subhasish Bhattacharjee

0

图中显示了Dispatcher Controller,所有传入的请求都被充当前端控制器的分派器servlet拦截。调度程序servlet从XML文件获取到处理程序映射的条目,并将请求转发到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>
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.