DispatcherServlet 作为 Spring MVC 的核心,承担着接收请求、路由请求、调用 Handler、解析视图、返回响应等关键职责。下面详细分解 DispatcherServlet 在这些环节中的具体工作:
1. 接收请求 (Receiving Requests):
- Servlet 容器:
DispatcherServlet本身是一个 Servlet,它部署在 Servlet 容器(如 Tomcat、Jetty 等)中。 - web.xml 或 Java 配置:
DispatcherServlet在web.xml文件中配置(或通过 Servlet 3.0+ 的 Java 配置方式),并映射到特定的 URL 模式。- 例如,
<url-pattern>/</url-pattern>表示拦截所有请求。 - 例如,
<url-pattern>*.do</url-pattern>表示拦截所有以.do结尾的请求。
- 例如,
- HTTP 请求: 当客户端(如浏览器)发送一个 HTTP 请求到 Servlet 容器,并且请求的 URL 匹配
DispatcherServlet的映射规则时,Servlet 容器会将请求交给DispatcherServlet处理。
2. 路由请求 (Routing Requests) - 使用 HandlerMapping:
- HandlerMapping 列表:
DispatcherServlet维护了一个HandlerMapping列表(可以配置多个)。 - 遍历 HandlerMapping:
DispatcherServlet遍历HandlerMapping列表,调用每个HandlerMapping的getHandler()方法。 getHandler()方法:HandlerMapping的getHandler()方法根据请求的 URL、HTTP 方法、请求头等信息,查找匹配的HandlerExecutionChain。HandlerExecutionChain包含:- Handler(处理器): 通常是一个 Controller 中的方法。
- Interceptors(拦截器): 一组拦截器,用于在请求处理前后执行特定逻辑。
- 返回 HandlerExecutionChain: 如果
HandlerMapping找到了匹配的HandlerExecutionChain,就将其返回给DispatcherServlet。 - 未找到匹配项: 如果所有
HandlerMapping都没有找到匹配的HandlerExecutionChain,DispatcherServlet会返回 404 错误。
3. 调用 Handler (Invoking Handler) - 使用 HandlerAdapter:
- HandlerAdapter 列表:
DispatcherServlet维护了一个HandlerAdapter列表(可以配置多个)。 - 遍历 HandlerAdapter:
DispatcherServlet遍历HandlerAdapter列表,查找支持当前 Handler 类型的HandlerAdapter。HandlerAdapter的supports()方法用于判断是否支持给定的 Handler 类型。
handle()方法: 找到合适的HandlerAdapter后,DispatcherServlet调用其handle()方法来执行 Handler。handle()方法的职责:- 执行拦截器 preHandle(): 在调用 Handler 之前,执行
HandlerExecutionChain中所有拦截器的preHandle()方法。 - 参数解析: 解析 Handler 方法的参数,从请求中获取参数值,并进行类型转换。
- 方法调用: 通过反射调用 Handler 方法(即 Controller 中的方法),并将解析后的参数值传入。
- 返回值处理: 处理 Handler 方法的返回值(
ModelAndView、String、void、@ResponseBody等)。 - 执行拦截器 postHandle(): 在 Handler 方法执行完成后,但在视图渲染之前,执行所有拦截器的
postHandle()方法。
- 执行拦截器 preHandle(): 在调用 Handler 之前,执行
4. 解析视图 (View Resolution) - 使用 ViewResolver:
- 判断是否需要解析视图:
- 如果 Handler 方法返回的是
ModelAndView对象,或者返回的是一个 String(表示视图名称),则需要进行视图解析。 - 如果 Handler 方法使用了
@ResponseBody注解,或者直接操作了HttpServletResponse,则不需要视图解析,直接返回响应。
- 如果 Handler 方法返回的是
- ViewResolver 列表:
DispatcherServlet维护了一个ViewResolver列表(可以配置多个)。 - 遍历 ViewResolver:
DispatcherServlet遍历ViewResolver列表,调用每个ViewResolver的resolveViewName()方法。 resolveViewName()方法:ViewResolver的resolveViewName()方法根据视图名称和配置的视图解析规则,查找对应的View对象。- 返回 View: 如果
ViewResolver找到了匹配的View对象,就将其返回给DispatcherServlet。 - 未找到匹配项: 如果所有
ViewResolver都没有找到匹配的View对象,DispatcherServlet会抛出异常。
5. 返回响应 (Returning Response):
- 视图渲染 (View Rendering):
- 如果需要进行视图渲染,
DispatcherServlet调用View对象的render()方法。 render()方法将模型数据(Model)渲染到视图模板中,生成最终的 HTML 响应。
- 如果需要进行视图渲染,
- 直接响应:
- 如果 Handler 方法使用了
@ResponseBody注解,或者直接操作了HttpServletResponse,则直接将数据作为响应内容返回。
- 如果 Handler 方法使用了
- 执行拦截器 afterCompletion(): 在整个请求完成后,执行所有 HandlerInterceptor 的 afterCompletion()
- 返回给客户端:
DispatcherServlet将生成的响应内容(HTML、JSON、XML 等)返回给客户端(浏览器)。
总结:
DispatcherServlet 是 Spring MVC 的核心,它通过以下步骤处理请求:
- 接收请求: 接收来自客户端的 HTTP 请求。
- 路由请求: 使用
HandlerMapping查找匹配的HandlerExecutionChain。 - 调用 Handler: 使用
HandlerAdapter执行HandlerExecutionChain中的 Handler(Controller 方法),并处理拦截器。 - 解析视图: 如果需要,使用
ViewResolver将视图名称解析成View对象。 - 返回响应: 调用
View对象的render()方法渲染视图,或直接返回响应内容,并在最后执行拦截器的afterCompletion()。
DispatcherServlet 通过委派给不同的组件(HandlerMapping、HandlerAdapter、ViewResolver 等)来完成请求处理的不同阶段,实现了松耦合、高可配置的架构。
1704

被折叠的 条评论
为什么被折叠?



