当前位置:网站首页>五、请求处理—Rest映射是怎样实现的?
五、请求处理—Rest映射是怎样实现的?
2022-08-05 05:16:00 【呆比特】
五、请求处理—Rest映射是怎样实现的?
这节我们来分析一下,每次收到一个请求,springboot是怎样找到对应的方法处理的?
因为springboot底层还是用的Spring MVC,所以,所有的请求过来,会先来到DispatcherServlet ,DispatcherServlet是处理所有请求的开始。
从源码可以看到,DispatcherServlet继承了FrameworkServlet,FrameworkServlet继承了HttpServletBean,HttpServletBean继承了HttpServlet,所以 DispatcherServlet本质上也是一个Servlet ,是Servlet就必然要重写doGet(),doPost()等方法

查找发现在HttpServletBean中没有doGet(),doPost()等,考虑在它的子类中重写了,再检查它的子类FrameworkServlet,在这个类中找到了这些方法

而且我们发现,不管是doGet()还是doPost()等,里边调用的都是 processRequest(request, response);

所以接下来,我们来看processRequest()这个方法里边做了什么?

我们来继续跟进本类的doService(request, response);

进入doService(request, response)方法发现,这是一个抽象方法,没有实现,所以就来到了它的子类DispatcherServlet,可以看到,最终是在DispatcherServlet中对doService()方法进行实现的。

来到doService()方法,上边的一些获取值代码可以先不看,来到下边有一个 doDispatch(request, response); 方法,从方法名可以猜出他就是用来做转发的
看到这里我们可以得出,每个请求进来,都会调用这个doDispatch()方法,也就是说,要分析SpringMVC的功能,我们都从 DispatcherServlet类中的doDispatch()方法开始 。
找到的分析的入口,接下来我们来debug一下,详细看看doDispatch()方法做了什么?

首先,我们来发送一个@GetMapping(“/user”)请求,下面将debug的过程记录在代码注释
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
//先把原生的request请求进行了包装
HttpServletRequest processedRequest = request;
//执行链后边再说
HandlerExecutionChain mappedHandler = null;
//是否文件上传请求,默认false
boolean multipartRequestParsed = false;
//如果有异步,使用异步管理器,暂时不管
WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);
try {
try {
ModelAndView mv = null;
Object dispatchException = null;
try {
//检查是否文件上传请求
processedRequest = this.checkMultipart(request);
//如果是进行转化
multipartRequestParsed = processedRequest != request;
//这里决定哪个Handler可以处理当前请求,我们要找的就是这里,下边进入该方法
mappedHandler = this.getHandler(processedRequest);
if (mappedHandler == null) {
this.noHandlerFound(processedRequest, response);
return;
}
protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
//HandlerMapping:处理器映射,保存了所有@RequestMapping 和handler的映射规则。
//在应用一启动,spring mvc 自动扫描所有的controller保存的
//循环查找看谁能处理这个请求
//debug部分截图在下边
if (this.handlerMappings != null) {
Iterator var2 = this.handlerMappings.iterator();
while(var2.hasNext()) {
HandlerMapping mapping = (HandlerMapping)var2.next();
HandlerExecutionChain handler = mapping.getHandler(request);
if (handler != null) {
return handler;
}
}
}
return null;
}
HandlerMapping 保存了我们所有的映射,进行循环查找对比,最后找到由哪个controller的哪个类型的方法处理。

到这里,HandlerMapping 映射的原理就分析清楚了,后边还有一大段代码我们还没有看,这节只是分析请求映射原理,后边的下回再说。
总结一下:
● SpringBoot自动配置欢迎页的 WelcomePageHandlerMapping 。访问 “/” 能访问到 index.html
● SpringBoot自动配置了默认 的 RequestMappingHandlerMapping
● 请求进来,挨个尝试所有的HandlerMapping看是否有请求信息
○ 如果有就找到这个请求对应的handler
○ 如果没有就尝试下一个 HandlerMapping
● 另外,我们也可以自己给容器中放HandlerMapping,自定义 HandlerMapping,有兴趣可以试试。
边栏推荐
- 【论文精读】ROC和PR曲线的关系(The relationship between Precision-Recall and ROC curves)
- 沁恒MCU从EVT中提取文件建立MounRiver独立工程
- ECCV2022 | RU&谷歌提出用CLIP进行zero-shot目标检测!
- 大型Web网站高并发架构方案
- CVPR最佳论文得主清华黄高团队提出首篇动态网络综述
- 【shell编程】第二章:条件测试语句
- Comparison and summary of Tensorflow2 and Pytorch in terms of basic operations of tensor Tensor
- AIDL detailed explanation
- [Database and SQL study notes] 9. (T-SQL language) Define variables, advanced queries, process control (conditions, loops, etc.)
- AIDL详解
猜你喜欢
随机推荐
dataframe 常用操作
【ts】typescript高阶:键值类型及type与interface区别
《基于机器视觉测量系统的工业在线检测研究》论文笔记
基于STM32F4的FFT+测频率幅值相位差,波形显示,示波器,时域频域分析相关工程
原来何恺明提出的MAE还是一种数据增强
六步搞定子网划分
全尺度表示的上下文非局部对齐
SQL(1) - Add, delete, modify and search
flink yarn-session的两种使用方式
【ts】typescript高阶:模版字面量类型
如何编写一个优雅的Shell脚本(二)
【ts】typescript高阶:联合类型与交叉类型
初识机器学习
Flink EventTime和Watermarks案例分析
Tensorflow踩坑笔记,记录各种报错和解决方法
Flutter 3.0升级内容,该如何与小程序结合
大型Web网站高并发架构方案
PID详解
ACL 的一点心得
IDEA 配置连接数据库报错 Server returns invalid timezone. Need to set ‘serverTimezone‘ property.









