图解 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。
 1 <filter>
 2     <filter-name>encodingFilter</filter-name>
 3     <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
 4     <init-param>
 5         <param-name>encoding</param-name>
 6         <param-value>UTF-8</param-value>
 7     </init-param>
 8     <init-param>
 9         <param-name>forceEncoding</param-name>
10         <param-value>true</param-value>
11     </init-param>
12 </filter>
13 <filter-mapping>
14     <filter-name>encodingFilter</filter-name>
15     <url-pattern>/*</url-pattern>
16 </filter-mapping>
3.1.2 监听器 Listener

监听器 Listener 主要用于监听 Application、Session、Request 等对象的变化,每当这些对象发生变化就会回调用对应的监听方法。例如:在 Servlet API 中有一个 ServletContextListener 接口,它能够监听 ServletContext 对象的生命周期,实际上就是监听 Web 应用的生命周期。当 Servlet 容器启动或终止Web 应用时,会触发 ServletContextEvent 事件,该事件由 ServletContextListener 来处理。

1 <listener>
2     <listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
3 </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:

 1 <servlet>
 2     <servlet-name>mvc</servlet-name>
 3     <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
 4     <init-param>
 5         <param-name>contextConfigLocation</param-name>
 6         <param-value>classpath:mvc-servlet.xml</param-value>
 7     </init-param>
 8     <load-on-startup>1</load-on-startup>
 9 </servlet>
10 <servlet-mapping>
11     <servlet-name>mvc</servlet-name>
12     <url-pattern>/api</url-pattern>
13 </servlet-mapping>

3.2 Web 应用处理 HTTP 请求的流程

如下图所示,Web 应用处理 HTTP 请求的流程主要是穿越监听器 Listener 和过滤器链 Filters,最终抵达伺服器 Servlet 的过程:

原先我们将 Web 应用的复杂度直接暴露给了 Tomcat,现在 Spring 通过控制反转 IOC 和面向切面编程 AOP 等新技术接管了 Web 应用的复杂度。如前面 Servlet 的配置示例,整个 Web 应用只需要配置 Spring 提供的前置分发器 DispatcherServlet,开发者无需再编写和配置 HttpServlet 子类,所有业务逻辑功能将按照 Spring 的标准规范来开发,从原先的编写 Listener\Filter\Servlet 改为编写 Spring Component,包括:Controller、Service、Repository 等。

Tomcat 在接收到某个 Web 应用的 Http 请求之后,它会将所有请求都转交给前置分发器 DispatcherServlet,再由 DispatcherServlet 将请求派发给具体业务逻辑进行处理。DispatcherServlet 就是从 HttpServlet 派生的子类,它的类图关系如下所示:

3.3 Web 应用架构演进过程解析

Web 应用架构的演进过程就像创业孵化过程,最初创业团队打造的产品很简单,大家采用手工作坊模式来快速打造最小化可行产品,这时候团队的组织架构也跟产品一样扁平简单。但随着产品被越来越多的用户使用,功能变得越来越复杂,接着必须引进新架构才能有效管理复杂度,同时团队规模的扩展也需要与业务发展匹配的组织架构,这样才能保证产品的不断发展。

Web 应用架构的演化过程跟 Tomcat 体系结构的形成过程类似,老兵哥会经常借助“俄罗斯套娃”这个模型来阐述架构,Web 容器和 Web 应用这两层的架构原则是类似的,就像大娃娃套着小娃娃一样。

Spring 的 IOC 容器跟 Tomcat 的 Servlet 容器类似,也是通过配置文件等方式来定义组件,然后在启动过程中将这些定义好的组件初始化并添加到容器当中,后续使用时从容器查找获取。早期 Web 应用主要由大量开发者编写的 Filter\Listener\Servlet 等组件构成,这些核心组件的配置全部都通过 web.xml 配置文件来维护,那么 Web 应用和 Web 容器之间其实不是松耦合的,而引进 Spring 之后就变成只需要配置 DispatcherServlet 等少量组件了,达到了分层架构的要求,更加有利于开发复杂的 Web 应用。如果采用架构的专业术语来描述,这就是经典的分层架构模式,层与层之间松耦合,仅通过少量的接口衔接,每层内部高内聚。

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

原文地址:https://www.cnblogs.com/itlaobingge/p/11963311.html

时间: 2024-10-12 17:47:41

图解 Spring:HTTP 请求的处理流程与机制【3】的相关文章

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

5. HTTP 请求处理相关配置文件说明 HTTP 请求穿越的整个空间是分层的,包括:Web 容器.Web 应用.Spring 框架等,它们每层都是通过配置文件配置初始化的,这是一种松耦合的架构设计.现在我们来梳理一下这些配置文件,HTTP 请求最先穿越的就是 Web 容器,它的代表产品 Tomcat 的配置文件是 server.xml. 第二道穿越的是 Web 应用,它由 Listener\Filter\Servlet 等组件构成,主要配置文件是 web.xml. 第三道穿越的是 Spring

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

4. HTTP 请求在 Spring 框架中的处理流程 在穿越了 Web 容器和 Web 应用之后,HTTP 请求将被投送到 Spring 框架,我们继续剖析后续流程.Web 应用与 Spring MVC 的衔接是通过配置文件 mvc-servlet.xml 完成的,我们通过这份配置文件定义构成 Spring MVC 的各种核心组件和初始化配置,其中包括:控制器 Controller.视图解析器 ViewResolver.视图 View 等等.不同组件分别承担不同的功能,在介绍 Spring 框

Spring MVC 处理HTTP请求的整体流程

DispatcherServlet是一个前端控制器,是整个Spring MVC框架的核心组件.它在接收HTTP请求之后,根据请求调用Spring MVC中的各个组件. 常用接口及其含义: 1. Controller:被@Controller修饰的类是控制器类. 2. HandlerMapping:将用户请求映射到控制器. 3. HandlerInterceptor:拦截指定格式的URL请求. 4. ModelAndView:控制器处理完请求后,将视图的逻辑名称和模型数据封装成ModelAndVi

Spring MVC 执行(请求--&gt;响应)流程

*每日一句:*每天起床之前有两个选择,要么继续趴下做你没做完的梦,要么起床完成你没有完成的梦想.-----** ----- 用户想服务器发型请求,请求被Spring的前端控制器DispatcherServlet截获. DispatcherServlet对请求URL(统一资源定位符)进行解析,得到URI(请求资源标识符).然后根据该URI,调用HandlerMapping获得该Handler配置的所有相关的对象,包括Handler对象以及Handler对象对应的拦截器,这些对象会被封装到一个Han

spring mvc控制框架的流程及原理1: 总概及源码分析

主要介绍spring mvc控制框架的流程及原理 Spring Web MVC处理请求的流程 具体执行步骤如下: 首先用户发送请求————>前端控制器,前端控制器根据请求信息(如URL)来决定选择哪一个页面控制器进行处理并把请求委托给它,即以前的控制器的控制逻辑部分:图2-1中的1.2步骤: 页面控制器接收到请求后,进行功能处理,首先需要收集和绑定请求参数到一个对象,这个对象在Spring Web MVC中叫命令对象,并进行验证,然后将命令对象委托给业务对象进行处理:处理完毕后返回一个Model

spring+springmvc+mybatis详细运转流程

spring+springmvc+mybatis详细运转流程 2016-04-14 23:38 1892人阅读 评论(0) 收藏 举报 分类: SSM(7) 最近在整合spring+springmvc+mybatis,网上有很多直接整合好的例子,但是下载过来之后发现对于SSM具体的运转流程还是不太清楚,今天看到一篇关于springmvc的详细处理流程,觉得总结的还可以,不懂springmvc运行流程的童鞋,大家一起来学习学习~~ mvc 处理流程: 1. 首先浏览器发送一个 url请求,比如 h

Spring web flow——披萨订购流程示例(1)

一.Spring web Flow定义 Spring Web Flow(后面简称swf)是一个Web框架,它适用于元素按规定流程运行的程序.Spring Web Flow是Spring MVC的扩展,它支持开发基于流程的应用程序.它将流程的定义于实现流程行为的类和视图分离开来. 下面我们通过生成披萨订单的新Web应用程序.我们会使用Spring Web Flow来定义订单流程. 1.1 swf环境准备 尽管swf是Spring框架的子项目,但它并不是Spring框架的一部分.因此,在构建基于流程

[Spring Batch] 图解Spring Batch原理

找到一副以前学习的图,稻清楚的描述了Spring Batch运行原理: [Spring Batch] 图解Spring Batch原理,布布扣,bubuko.com

Spring基础系列14 -- Spring MVC 请求参数的几种获取方法

Spring MVC 请求参数的几种获取方法 转载:http://www.cnblogs.com/leiOOlei/p/3658147.html 一.      通过@PathVariabl获取路径中的参数 @RequestMapping(value="user/{id}/{name}",method=RequestMethod.GET) public String printMessage1(@PathVariable String id,@PathVariable String n