HTTP请求的流转路径,从Tomcat到SpringMVC

news2024/9/20 2:00:01

本文主要讲一下,一个HTTP请求在后端服务的流转路径,Tomcat等一众servlet容器如何定义了Web应用的基础样貌,后来的MVC框架又是如何弱化了servlet的存在,改为自己实现请求派发的。

前些日子我写了十几篇文章来介绍Tomcat的架构,并汇总了一个文章目录:Tomcat文章目录,如果你对Tomcat也感兴趣,可以翻看一下。Tomcat整体架构分为两大块:连接器与容器。连接器负责接收HTTP请求并将其解析为Request对象,然后连接器将Request对象传给容器,四大容器会层层向下寻址子容器,直到找到该请求对应的servlet。

在不谈MVC框架的情况下,一个HTTP请求在Tomcat中是这样流转的

  1. 连接器收到HTTP请求,从“处理线程”的线程池中挑一个线程,将该请求对应的socket连接抛给该线程进行接下来的处理,而连接器主线程则继续等待下一个请求。
  2. 处理线程将HTTP请求拼装成容器需要的Request与Response对象,将两个对象抛给容器进行接下来的处理。
  3. Tomcat中的容器都是一对多的关系,每个父容器都有自己的策略,可以根据request请求来定位到某个子容器。从Engine容器接收到请求开始,就开始层层往下寻找子容器,直到找到一个Wrapper容器,该Wrapper容器包含了能处理该request请求的servlet,接着就调用该servlet的service方法来执行用户自定义逻辑处理该request请求,并拿到结果数据。最后将返回结果层层上抛,处理线程拿到容器给的结果后,回传给客户端,一个HTTP请求的一生就结束了。

所以按照这个流程来说,一个Web应用中应该存在很多个不同的servlet来处理对应的HTTP请求,(这里我暂且叫这种模式为多servlet模式),在servlet编程时代,确实也是这个样子。

但是当MVC框架出来后,这个模式发生了一些改变,MVC框架放弃了多servlet模式,转而用一个servlet来接收所有的HTTP请求,在自己的框架内部再进行请求的分派处理。

MVC为什么这么做呢?我理解MVC这么做是为了减少与Tomcat的耦合度,转为在自身框架内部实现高度的定制化;而且使用单servlet天然的就将请求入口统一了,如果要对请求做一些统一处理就变得很方便。

MVC框架有哪些呢?最初大家使用Struts比较多,在Struts漏洞暴雷后,现在大家基本上都在使用SpringMVC,而且SpringBoot普及后,SpringMVC就成了一个理所应当的选择。接下来就简单看下SpringMVC的设计。

DispatcherServlet

在SpringMVC中那个入口servlet就是DispatcherServlet,它负责配合Tomcat来接收请求。

HandlerMethod

SpringMVC内部怎么表达一个Controller方法呢?答案就是用一个HandlerMethod对象来表示一个Controller方法。

例如下面这个Controller,testGet 与 testPost 两个方法在SpringMVC内部就会被表示成两个 HandlerMethod 对象

@RestController
public class TestController {

    @GetMapping("/test")
    public User testGet(Long userId) {
        User user = new User();
        user.setUserId(userId);
        user.setName("张三");
        user.setAge(18);
        return user;
    }

    @PostMapping("/test")
    public User testPost(Long userId) {
        User user = new User();
        user.setUserId(userId);
        user.setName("张三");
        user.setAge(18);
        return user;
    }

    @Data
    private static class User{
        private Long userId;
        private String name;
        private Integer age;
    }

}

HandlerMethod中存放了该方法的名字,所在类,参数信息,对应的请求uri,以及支持的请求方式(get、post…)等信息。

SpringMVC在启动时就将所有的 HandlerMethod 对象创建好,并为其建立一个索引 <uri,HandlerMethod对象> ,我们将这个索引称为 HandlerMapping。通过 HandlerMapping 就可以根据请求找到指定的 HandlerMethod 。

找到了 HandlerMethod 怎么执行它代表的方法呢?老套路,使用反射,即 method.invoke() 方法。这个反射执行逻辑被放在了一个叫 HandlerAdapter 的组件里。

加入拦截器

在反射执行 HandlerMethod 的方法前,会找到项目中配置的所有与这个请求有关的拦截器,然后在反射调用 method 前后,执行拦截器中的 preHandle、postHandle 及 afterCompletion 方法,拦截器的工作模式就是这样。拦截器的接口定义为 HandlerInterceptor 。

另外,Tomcat传给 DispatcherServlet 的信息为 HttpServletRequest 与 HttpServletResponse两个对象,SpringMVC内部拥有将 HttpServletRequest 转化为 method 的参数对象的组件,也有将method 的返回结果转化为 json 等结构的组件。(这里的method指的就是HandlerMethod对应的method)。

现在,我们再来看下Tomcat与SpringMVC配合时,一个HTTP请求的一生。

HTTP请求在Tomcat中的流转路径不变,最后找到 DispatcherServlet 这个servlet,接下来就进入到了SpringMVC的框架范围了。

SpringMVC根据请求的 HttpServletRequest 对象,找到对应的 HandlerMethod, 再找到会拦截该HanderMethod的拦截器,执行对应拦截器的 preHandle 方法后,再反射调用 HandlerMethod 对应的 method 方法,拿到反射调用的结果后,再按照程序安排执行拦截器的 postHandle 、afterCompletion 方法,拿到最终结果后再抛给Tomcat,Tomcat将结果返回给客户端。

另外在SpringMVC中还存在全局异常处理等机制,代码入口在 DispatcherServlet 的 processDispatchResult 方法中,通过 @RestControllerAdvice 配置的自定义全局异常处理机制就会在这个方法里被触发,感兴趣的自己去翻一下吧。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2038530.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

AI在医学领域:联邦学习 (FL) 在肿瘤学的应用综述

关键词&#xff1a;联邦学习 (Federated Learning, FL)、机器学习 (Machine Learning, ML)、肿瘤学 (Oncology)、数据隐私 (Data Privacy)、精准医疗 (Precision Medicine)、多模态 (Multi-modal) 肿瘤学正在经历快速的变革&#xff0c;这得益于机器学习&#xff08;ML&#xf…

tinymce字体为48px后再设置numlist数字列表导致前面的序号字体不对--【已解决】

问题描述&#xff1a; tinymce选择完大号字体&#xff0c;如48px&#xff0c;再选择数字列表&#xff0c;会导致数字列表的序号字体不对。 解决&#xff1a; 演示效果

【C语言篇】C语言常考及易错题整理DAY3

文章目录 选择题整形提升与算术转换左移右移操作符操作符优先级与结合性后置指针变量基本知识 编程题最大连续1的个数完全数计算单词倒排面试题.珠玑妙算两数之和 选择题 整形提升与算术转换 声明以下变量&#xff0c;则表达式: ch/i (f*d – i) 的结果类型为&#xff08; &…

Fal.ai Flux 1-Pro/Viva.ai/哩布哩布AI:AI绘图部分免费工具+原图提示词Prompt

目录 #1 找软件 #2 懂提示词 #3 更难的一步&#xff0c;会英文 我个人认为&#xff0c;想要玩文生图&#xff0c;你要会3个步骤&#xff1a; #1 找软件 主流文生图软件&#xff1a;Midjourney、Stable Diffusion、Dall-E 3 巧了&#xff0c;我用的都是小众、免费的画笔工…

Linux 错误码

目录 一、概述二、含义三、错误处理函数1、IS_ERR2、strerr、perror 一、概述 在 Linux 系统中&#xff0c;错误码是用来表示操作系统运行过程中发生的错误的数字代码。错误码通常由负数表示&#xff0c;0 表示成功&#xff0c;正数表示警告或其他非致命错误。 为了开发者更好…

查询大数据信用需要收费吗?哪个平台好一点?

随着大数据技术被运用到金融行业&#xff0c;不少申贷人都开始了解自己的大数据信用&#xff0c;在查询大数据信用的时候&#xff0c;查询大数据信用需要钱吗?哪个平台好一点?等问题是很多人都比较关心的问题&#xff0c;下面本文就详细为大家详解一下&#xff0c;希望对你了…

基于python的百度迁徙迁入、迁出数据分析(九)

副标题&#xff1a;从百度迁徙数据看——人口虹吸效应 人口虹吸效应&#xff1a;人口虹吸效应是指大城市或中心城市因其经济、文化、教育、医疗等资源的优势&#xff0c;吸引周边地区的人口、资本和其他资源向其集中的一种现象。这种效应在城市化进程中尤其明显&#xff0c;通…

公司起诉员工泄密难吗?如何搜寻有力的证据?专业审计软件助力,追责之路其实不难!

在企业管理中&#xff0c;员工泄密是一个严重的问题&#xff0c;不仅可能损害企业的商业利益&#xff0c;还可能对企业的声誉造成不可挽回的影响。然而&#xff0c;公司起诉员工泄密并非易事&#xff0c;需要满足严格的法律条件和程序&#xff0c;并面临证据收集与举证、法律程…

10款好用的文件加密软件排行榜,2024企业常用的文件加密软件

在数据安全日益受到重视的今天&#xff0c;文件加密软件已成为保护企业敏感信息的重要工具。以下是2024年企业常用的10款好用的文件加密软件排行榜&#xff0c;帮助你选择适合的工具来保护你的文件和数据。 1. 安秉加密软件 安秉加密软件提供用户友好的界面和强大的加密功能。…

使用 nginx 搭建代理服务器(正向代理 https 网站)指南

简介 正向代理 简介 在企业开发环境中&#xff0c;局域网内的设备通常需要通过正向代理服务器访问互联网。正向代理服务器充当中介&#xff0c;帮助客户端请求外部资源并返回结果。局域网内也就是俗称的内网&#xff0c;局域网外的互联网就是外网&#xff0c;在一些特殊场景内…

unity 画线写字

效果 1.界面设置 2.涉及两个脚本UIDraw.cs和UIDrawLine.cs UIDraw.cs using System; using System.Collections.Generic; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.UI;public class UIDraw : MonoBehaviour, IPointerEnterHandler, IPointerEx…

【大数据】什么是数据架构?

目录 一、什么是数据架构&#xff1f; 二、数据架构的发展历程 1. 早期阶段&#xff08;1960年代-1970年代&#xff09; 2. 关系数据库的兴起&#xff08;1970年代-1980年代&#xff09; 3. 数据仓库和数据挖掘&#xff08;1980年代-1990年代&#xff09; 4. 大数据和NoSQL&…

计算机基础|数据溢出

一、概念 在类似C这样的非高级语言存在数值溢出问题&#xff0c;简单概括&#xff1a;高位数据丢失被低位数据占据位置。 二、举例 2.1 以C语言 for循环为例 /*int8_t value range from -128 to 127*/int8_t input;for (input 124; input < 130; input) {printf("%…

《Unity3D网络游戏实战》深入了解TCP

从TCP到铜线 应用层 应用层功能是应用程序&#xff08;游戏程序&#xff09;提供的功能。在给客户端发送“hello”的例子中&#xff0c;程序把“hello”转化成二进制流传递给传输层&#xff08;传送给send方&#xff09;​。操作系统会对二进制数据做一系列加工&#xff0c;使…

嵌入式八股文-网络编程、多线程和进程

网络编程 1. TCP头部结构 TCP固定头部结构 每个TCP报文段都包含着此报文段的TCP头部信息,用于指定源端端口、目的端端口以及管理TCP连接等。完整的TCP头部结构可分为固定头部结构和头部选项两个部分。 32位端口号:包括了16位源端口号和16位目的端口号。32位序号:假设第一次…

Linux驱动开发基础(Hello驱动)

所学内容来自百问网 目录 1. 文件在内核中的表示 2. 打开字符设备节点时&#xff0c;内核中也有对应的struct file 3. 编写驱动程序步骤 4. 相关知识点 4.1 涉及函数解析 4.2 module_init/module_exit的实现 4.3 register_chrdev的内部实现 4.4 class_destroy/device_…

(Jmeter、Fiddler)脚本转换Loadrunner脚本

背景:公司政治任务、各种体系文档要留档,但有些不在体系内的工具生成的脚本需要转化到体系内以备留档。 一、Loadrunner代理设置 开始录制配置: Record->Remote Application via LoadRunner Proxy LoadRrunner Proxy listens on port-> 8889 (系统建立出入站规则…

解析防蠕动交叉导轨的防蠕动机制

随着工业自动化的不断发展&#xff0c;对机械导轨系统的精度和稳定性要求越来越高。防蠕动交叉导轨作为一种新型导轨系统&#xff0c;能够有效提高设备的运行精度和稳定性&#xff0c;降低维护成本。 蠕动现象通常发生在导轨负载超出其额定范围、表面粗糙度不足或润滑不良等情况…

Python 实现 Excel 文件操作的技术性详解

目录 一、引言 二、Excel 文件格式及库的选择 2.1 Excel 文件格式 2.2 库的选择 三、安装必要的库 四、使用 openpyxl 读取 Excel 文件 4.1 基本步骤 4.2 实战案例 五、使用 pandas 读取 Excel 文件 5.1 基本步骤 5.2 实战案例 六、写入 Excel 文件 6.1 使用 …

【每日刷题】Day100

【每日刷题】Day100 &#x1f955;个人主页&#xff1a;开敲&#x1f349; &#x1f525;所属专栏&#xff1a;每日刷题&#x1f34d; &#x1f33c;文章目录&#x1f33c; 1. 【模板】堆_牛客题霸_牛客网 (nowcoder.com) 2. 【模板】链表_牛客题霸_牛客网 (nowcoder.com) 3…