把Spring MVC工作流实现完走了一遍后,从DispatcherServlet开始看它的具体实现,前端控制器(或叫分发器)作为整个流程的核心,依靠它完成HTTP请求的拦截和分发处理,翻看了DispatcherServlet的源码,看到它实现了多级继承,于是决定写一篇日志,从上往下一步一步总结每一层的作用和实现,先从Servlet规范开始。
组件之间的通信
前端控制器DispatcherServlet可以说是保证整个Spring MVC工作流的最核心组件,DispatcherServlet根据web.xml中的配置拦截到用户的HTTP请求后,首先初始化,加载springmvc.xml配置文件中的配置,例如各种组件,之后,一个Spring MVC工作流开始。
第一步,DispatcherServlet会去遍历所有的处理器映射器,寻找一个可以处理该HTTP请求的处理器。匹配成功的处理器映射器会向DispatcherServlet返回一个处理器执行链,里面包含了一个处理器。
第二步,DispatcherServlet拿到处理器后,再去遍历所有的处理器适配器,寻找一个支持自己手中处理器的处理器适配器,因为只有处理器适配器才知道如何使用这个处理器处理请求。
第三步,DispatcherServlet将控制权交给处理器适配器,处理器适配器将HTTP请求HttpServletRequest和HTTP响应HttpServletResponse传递给处理器(或者说控制器Controller),控制器完成请求处理后,返回带有数据模型和逻辑视图的ModelAndView对象到处理器适配器,最终由处理器适配器返回给DispatcherServlet。
第四步,DispatcherServlet遍历所有的视图解析器ViewResolver,得到一个确定的视图,并将数据模型传递到视图中,完成数据填充,生成最终返回给用户的界面,通过HTTP响应HttpServletResponse发送给用户。
由此可见,前端控制器DipsatcherServlet是十分关键的组件,它是一个分发器,几乎参与了整个Spring MVC工作流的每一步。
DispatcherServlet的多级继承
作为Spring MVC的入口,DispatcherServlet其实就是一个Servlet,DispatcherServlet经过多级继承,最终继承自符合Servlet规范的HttpServlet。HttpServlet又继承自GenericServlet,GenericServlet最终实现Servlet接口,它们之间的关系如下图:
看到如此多级的继承关系,你可能会有疑问,为什么需要这么多级的继承和实现?实现这样多层次的继承,是为了每一级完成特定的任务,如初始化,请求分发,请求处理,清理资源等。下面就来看看各个类和接口里面都有那些实现,以及它们之间的关系。
HTTP和Servlet规范
HTTP请求中包含了用户信息,URI(统一资源标识符,标识Web上的一种可用资源,例如HTML文档,图片和视频),协议版本protocol,和请求的方法(GET、PUT、POST、DELETE等)。HTTP支持的方法有GET、PUT、POST、DELETE、HEAD、OPTIONS,TRACE。
- GET方法把请求参数放到HTTP请求头中,发送到服务器,请求服务器进行处理并返回HTTP响应。
- PUT方法用来请求将某个资源放在服务器的某一路径下。
- POST方法向服务器传送数据,可以要求服务器对其做处理并返回响应。
- DELETE方法请求删除服务器某一路径下的某个资源。
- HEAD方法用于查找服务器中某个对象的头部信息。
- OPTIONS方法用来查询Servlet中实现的方法信息。
- TRACE方法用于调试操作。
在请求/响应模型下,客户端用户的一个HTTP请求发送到Web容器中后,Web容器就会封装这个HTTP请求,并创建一个HTTP响应,用来回应客户端。Web容器将HTTP请求和自己创建的HTTP响应传递到Servlet的service()方法中。
Servlet是Servlet规范中定义的一个服务器组件接口,所有用于处理用户请求的服务器组件都要实现这个接口。Servlet规范包括一下内容: