图解 Spring:HTTP 央求的处理流程与机制【3】

3. HTTP 央求在 Web 运用中的处理流程

在穿越了 Web 容器之后,HTTP 央求将被投送到 Web 运用,我们持续以 Tomcat 为例剖析后续流程。Web 容器与 Web 运用的联接是通过配备文件 web.xml 结束的。web.xml 是遵照 Java Servlet 标准标准的配备文件,我们通过这份配备文件定义构成 Web 运用的各种中心组件和初始化配备,这中心还包括:过滤器 Filter、监听器 Listener、伺服器 Servlet 等等。不同组件分别承担不同的功用,在介绍 Web 运用处理 HTTP 央求流程之前,我们按例先来了解一下这些中心组件。

3.1 Web 运用中心组件简介

3.1.1 过滤器 Filter

过滤器 Filter 担任对 HTTP 央求做预处理,接着将央求交给 Servlet 做处理并生成照应,毕竟 Filter 再对照应进行后处理。从 HTTP 央求的处理进程来看,Filter 首要参与以下几个环节:

  • 在 HttpServletRequest 抵达 Servlet 之前,阻挠客户的 HttpServletRequest。
  • 根据需求检查 HttpServletRequest,也可以批改 HttpServletRequest 报文头和数据。
  • 在 Servlet 生成的 HttpServletResponse 抵达客户端之前,阻挠 HttpServletResponse。
  • 根据需求检查 HttpServletResponse,也可以批改 HttpServletResponse 报文头和数据。

过滤器映射 filter-mapping,用于声明 Web 运用将会用到的过滤器,过滤器可被映射到一个 Servlet 或 URL 方式。假设将过滤器映射到一个 Servlet 上,那它就作用于特定 Servlet。假设将过滤器映射到一个 URL 方式,那么它将作用于任何资源,只需该资源的 URL 与 URL 方式匹配。假设对某个资源的央求匹配到多个 Filter,那么在处理 HTTP 央求进程中,Tomcat 将按照过滤器映射 filter-mapping 在配备文件 web.xml 中的先后顺序来实行,在前面的先实行,在后面的后实行,多个过滤器 Filter 可以组成调用链。URL 方式匹配有三种类型规则:

  • 精确匹配:如“/foo.htm”,那只会匹配“foo.htm”这个 URL。
  • 途径匹配:如“/foo/*”,那只会匹配以 foo 为前缀的 URL。
  • 后缀匹配:如“*.htm”,那只会匹配全部以“.htm”为后缀的 URL。
<filter>
<filter-name>encodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>  
</filter-mapping>

3.1.2 监听器 Listener

监听器 Listener 大多数都用在监听 Application、Session、Request 等方针的改动,每当这些方针发生明显的改动就会回调用对应的监听方法。例如:在 Servlet API 中有一个 ServletContextListener 接口,它可以监听 ServletContext 方针的生命周期,实际上就是监听 Web 运用的生命周期。当 Servlet 容器发起或间断Web 运用时,会触发 ServletContextEvent 工作,该工作由 ServletContextListener 来处理。

<listener>
<listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
</listener>

3.1.3 伺服器 Servlet

伺服器 Servlet 担任处理客户端访问动态资源的 HTTP 央求,接口 javax.servlet.Servlet 定义了全部 Servlet 必需求结束的方法。

方法称谓 功用说明
destroy() 由 Servlet 容器调用,用于关闭间断 Servlet 供应的服务
getServletConfig() 获取 Servlet 初始化和发起时参数的配备信息方针 ServletConfig
getServletInfo() 获取 Servlet 的说明信息,包括:作者、版别和版权等等
init() 由 Servlet 容器调用,籍由配备 ServletConfig 结束 Servlet 初始化,发起对外服务
service() 由 Servlet 容器调用,让 Servlet 处理某个 HTTP 央求

从 HTTP 央求的处理进程来看,伺服器 Servlet 首要参与以下几个环节:

  • 接收央求:客户端央求会被封装成 HttpServletRequest 方针,包括报文头参数和报文体等信息。
  • 处理央求:一般调用 Servlet 的方法 service、doPost 或 doGet 等方法处理央求,并进一步调用业务层相应逻辑对其做处理等。
  • 反响照应:处理完央求后,可以转发(forward)、重定向(redirect)到某个视图页面或许直接回来效果数据,转发是 HttpServletRequest 的方法,重定向是 HttpServletResponse 的方法。

在老兵哥的读书年代,Web 运用相对简略,首要是各种信息处理系统。当时 Spring 没有诞生,干流技术栈是 JSP/Servlet,老兵哥我开发 Web 运用时首要编写继承自 HttpServlet 子类,将各种业务逻辑功用分别交由不同的 HttpServlet 子类结束。HttpServlet 继承自 GenericServlet,后者结束了接口 Servlet。跟着数字化和互联网化的不断推进,业务系统逐渐的变凌乱,HttpServlet 子类越写越多,web.xml 配备文件越来越凌乱,这导致系统的扩展维护越来越困难,手工作坊式的开发方法现已跟不上业务展开的脚步了。时势造英雄,Spring 就是在这种布景下呼之而出的,它创造性地发清楚控制反转 IOC 和面向切面编程 AOP,极大地下降凌乱度。如下面配备示例所示,整个 Web 运用只需求配备一个 Servlet 就可以了,它就是 Spring 的前置分发器 DispatcherServlet:

<servlet>
<servlet-name>mvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:mvc-servlet.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>mvc</servlet-name>
<url-pattern>/api</url-pattern>
</servlet-mapping>

3.2 Web 运用处理 HTTP 央求的流程

如下图所示,Web 运用处理 HTTP 央求的流程首要是穿越监听器 Listener 和过滤器链 Filters,毕竟抵达伺服器 Servlet 的进程:
图解 Spring:HTTP 央求的处理流程与机制【3】
原先我们将 Web 运用的凌乱度直接露出给了 Tomcat,现在 Spring 通过控制反转 IOC 和面向切面编程 AOP 等新技术接管了 Web 运用的凌乱度。如前面 Servlet 的配备示例,整个 Web 运用只需求配备 Spring 供应的前置分发器 DispatcherServlet,开发者无需再编写和配备 HttpServlet 子类,全部业务逻辑功用将按照 Spring 的标准标准来开发,从原先的编写 ListenerFilterServlet 改为编写 Spring Component,包括:Controller、Service、Repository 等。

Tomcat 在接收到某个 Web 运用的 Http 央求之后,它会将全部央求都转交给前置分发器 DispatcherServlet,再由 DispatcherServlet 将央求派发给具体业务逻辑做处理。DispatcherServlet 就是从 HttpServlet 派生的子类,它的类图联络如下所示:
图解 Spring:HTTP 央求的处理流程与机制【3】

3.3 Web 运用架构演进进程解析

Web 运用架构的演进进程就像创业孵化进程,开端创业团队打造的产品很简略,我们选用手工作坊方式来快速打造最小化可行产品,这时候团队的组织架构也跟产品相同扁平简略。但跟着产品被逐渐的变多的用户运用,功用逐渐的变凌乱,接着有必要引进新架构才华有用处理凌乱度,一同团队规划的扩展也需求与业务展开匹配的组织架构,这样才华够保证产品的持续不断的展开。Web 运用架构的演化进程跟 Tomcat 系统结构的构成进程类似,老兵哥会常常凭仗“俄罗斯套娃”这个模型来论说架构,Web 容器和 Web 运用这两层的架构原则是类似的,就像大娃娃套着小娃娃相同。

Spring 的 IOC 容器跟 Tomcat 的 Servlet 容器类似,也是通过配备文件等方法来定义组件,然后在发起进程中将这些定义好的组件初始化并添加到容器傍边,后续运用时从容器查找获取。前期 Web 运用首要由许多开发者编写的 FilterListenerServlet 等组件构成,这些中心组件的配备全部都通过 web.xml 配备文件来维护,那么 Web 运用和 Web 容器之间其实不是松耦合的,而引进 Spring 之后就变成只需求配备 DispatcherServlet 等少数组件了,达到了分层架构的要求,更加有利于开发凌乱的 Web 运用。假设选用架构的专业术语来描绘,这就是经典的分层架构方式,层与层之间松耦合,仅通过少量的接口联接,每层内部高内聚。

本文首要价值是帮忙我们梳理出端到端的全流程结构,也就是我们常说的全局视角或许天主视角。有了这个结构之后,我们你们可以根据自己的需求按图索骥找相关节点的资料来研究学习,不至于堕入细节找不到方向。当然,考虑到我们每个人的作业学习情况不同,往常遇到的问题也不同,本文内容无法掩盖全部人遇到的问题,欢迎我们留言提问,也欢迎注重我的博客或公号“IT老兵哥”交流互动,我会竭力从速答复我们提出的问题,谢谢!

本系列其他文章索引如下:

  • 图解 Spring:HTTP 央求的处理流程与机制【1】
  • 图解 Spring:HTTP 央求的处理流程与机制【2】
  • 图解 Spring:HTTP 央求的处理流程与机制【4】
  • 图解 Spring:HTTP 央求的处理流程与机制【5】