SpringMVC底层——请求参数处理流程描述
在DispatcherServlet.java的doDispatch方法中,springmvc通过handlermapping里面找哪个handler能处理请求,handler封装了目标方法的信息,
mappedHandler = getHandler(processedRequest);
然后为当前的handler找到一个适配器HandlerAdapter,寻找的过程为:在DispatcherServlet.java的getHandlerAdapter方法中,挨个匹配,判断当前adapter是否支持当前handler,判断方法为只要handler是handlerMethod类型就生效,就支持
HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
if (this.handlerAdapters != null) {
for (HandlerAdapter adapter : this.handlerAdapters) {
if (adapter.supports(handler)) {
return adapter;
}
}
}
找到适配器以后判断当前请求是不是“GET”方法以及“HEAD”,“HEAD”不是服务器真正处理的
适配器HandlerAdapter把(目标方法、request、response)传入handle执行目标方法
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
怎么执行目标方法:
- 先得到handler
return this.handler;
- 再进入内部处理细节RequestMappingHandlerAdapter.java,调用的invokeHandlerMethod就是执行目标方法
mav = invokeHandlerMethod(request,response,handlerMethod);
在RequestMappingHandlerAdapter.java的invokeHandlerMethod方法中,
为invocableMethod方法设置参数解析器argumentResolvers,参数解析器确定将要执行的目标方法的每一个参数的值是什么
当前解析器是否支持解析这种参数
支持就调用 resolveArgument
为invocableMethod方法设置返回值处理器returnValueHandlers
把26个argumentResolvers和15个returnValueHandlers都放入目标方法包装的ServletInvocableHandlerMethod中
然后真正执行目标方法的语句
invocableMethod.invokeAndHandle(WebRequest,mavContainer);
在ServletInvocableHandlerMethod.java的invokeAndHandle方法中,执行了controller
Object returnValue = invokeForRequest(webRequest,mavContainer,proviedArgs);
step into 进入InvocableHandlerMethod.java,确定目标方法每一个参数的值
Object[] agrs = getMethodArgumentValues(request,mavContainer,providerArgs)
在InvocableHandlerMethod.java的getMethodArgumentValues方法中,先获取方法所有的参数声明(详细信息)。
MethodParameter[] parameters = getMethodParameters();
判断参数是否为空,为空则无需确定任何值直接返回;
if (ObjectUtils.isEmpty(parameters)) {
return EMPTY_ARGS;
}
如果有参数列表,new一个Object[],参数列表有多少个Object[]就有多长
Object[] args = new Object[parameters.length];
for (int i = 0; i < parameters.length; i++) {
MethodParameter parameter = parameters[i];
parameter.initParameterNameDiscovery(this.parameterNameDiscoverer);
args[i] = findProvidedArgument(parameter, providedArgs);
先声明args遍历parameters,给args[i]赋值,args[i]的值解析器解析了才有
解析之前,判断26个解析器是不是supportsParamter支持这个参数类型。
this.resolvers.supportsParameter(parameter)
HandlerMethodArgumentResolverComposite.java的getArgumentResolver方法中
获取一个缓存result
result==null,进入增强for循环,逐个确定26个解析器谁能支持这种参数
- supportsParameter方法,传来的参数有没有hasParameterAnnotation标注注解
- 没有就return false
- 如果标了,再判断参数是否map类型,
- return true支持解析
当前resolver支持解析,放到缓存里边,判断成功,进入解析
解析参数
this.resolvers.resolveArgument
- HandlerMethodArgumentResolverComposite.java的resolverArgument方法中,先拿到所有的参数解析器getArgumentResolver
- 调用参数解析器的resolverArgument方法进行解析
- 获取参数名字信息
- 解析参数的名字,placeholderResolved、BeanExpressionResolver解析evaluate计算名字,按照正则匹配的方式
- 解析参数的值
- uriTemlateVars 在request请求域中拿到值;UrlPathHelper会把uri地址里边的所有的路径变量全部解析出来并保存到请求域中
遍历循环所有参数
最终返回args,args就是确定好的值
处理返回结果的时候,把mavContainer传进去,
this.returnValueHandlers.handlerReturnValue
在handlerMethod.java的getReturnValueType方法中获取返回的结果类型
HandlerMethodArgumentResolverComposite.java的handleReturnValue方法中,
找到返回值的处理器
如果返回值是一个字符串,拿到字符串然后保存到mavContainer
返回值处理完以后,getModelAndView
目标方法执行完成
将所有的数据都放在 ModelAndViewContainer;包含要去的页面地址View。还包含Model数据。
从ModelAndViewContainer拿到默认的Model,updateBindingResult,拿到key放到绑定里边,又被封装成ModelAndView,然后返回这个新封装的mav
处理派发结果
processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
拿到所有请求域中的属性,解析得到视图名
渲染页面
view.render(mv.getModelInternal(),request,response);
拿到页面数据
createMergeOutputModel(model,request,response);
创造合并的输出模型
如果model不等于空
mergeModel.putAll(model)//即把数据转移到HashMap
渲染合并输出的模型数据
renderMergedOutputModel(mergedModel, getRequestToExpose(request), response);
把上面的Hashmap传进来了
拿到请求对象,获取的原生的Servletrequest
return originalRequest
暴露模型作为请求域属性
// Expose the model object as request attributes.
exposeModelAsRequestAttributes(model, request);
- 把model里面的东西进行遍历
- 遍历以后每一个request setAttribute
SpringMVC底层——请求参数处理流程描述的更多相关文章
- 16 SpringMVC 的请求参数的绑定与常用注解
1.SpringMVC 绑定请求参数 (1)支持的数据类型 基本类型参数: 包括基本类型和 String 类型POJO 类型参数: 包括实体类,以及关联的实体类数组和集合类型参数: 包括 List 结 ...
- SpringMVC之请求参数的获取方式
转载出处:https://www.toutiao.com/i6510822190219264516/ SpringMVC之请求参数的获取方式 常见的一个web服务,如何获取请求参数? 一般最常见的请求 ...
- SpringMVC处理请求和返回流程
流程描述:一个url请求,找打指定的requestMapping再返回指定的jsp界面 通过url拿到指定的java方法 HandlerExecutionChain mappedHandler = ...
- SpringMVC接受请求参数、
1. 接收请求参数 1.1. [不推荐]通过HttpServletRequest 在处理请求的方法中,添加HttpServletRequest对象作为参数,在方法体中,直接调用参数对象的getPara ...
- SpringMVC RequestMapping & 请求参数
SpringMVC 概述 Spring 为展现层提供的基于 MVC 设计理念的优秀的Web 框架,是目前最主流的 MVC 框架之一 Spring3.0 后全面超越 Struts2,成为最优秀的 MVC ...
- SpringMVC 接受请求参数、作用域传值
目录 原生servlet接收参数 Spring MVC最基础的参数获取 接收基本数据类型参数 方法参数列表和请求参数不一致的处理方式 接收对象引用数据类型 接收复选框这种多个同名的参数 接收obj.f ...
- SpringMVC 获取请求参数
1.获取Request response对象 在SpringMVC的注解开发中,可以选择性的接收Request和Response对象来使用 2.获取request对象请求参数 a.通过request对 ...
- SpringMVC——映射请求参数
Spring MVC 通过分析处理方法的签名,将 HTTP 请求信息绑定到处理方法的相应人参中. @PathVariable @RequestParam @RequestHeader 等) Sprin ...
- SpringMVC获取请求参数-POJO类型参数
1.Controller中的业务方法的POJO参数的属性名与请求参数一致,参数值会自动映射匹配 1.创建POJO类 public class User { private String usernam ...
随机推荐
- 记一次burp suite文件上传漏洞实验
一·文件上传漏洞概念 文件上传漏洞是指 Web 服务器允许用户在没有充分验证文件名称.类型.内容或大小等内容的情况下将文件上传到其文件系统.未能正确执行这些限制可能意味着 即使是基本的图像上传功能也可 ...
- ChCore Lab1 机器启动 实验笔记
本文为上海交大 ipads 研究所陈海波老师等人所著的<现代操作系统:原理与实现>的课程实验(LAB)的学习笔记的第一篇. 书籍官网:现代操作系统:原理与实现,里面有实验的参考指南和代码仓 ...
- 如何使用Docker构建前端项目
原文链接 Docker单独部署前端项目和Node项目是非常便捷的,在这里分享一下Docker的使用,主要聊聊它的部署实践.(我是window10专业版安装Docker) Docker Docker是一 ...
- AC自动机:Tire树+KMP
简介 AC自动机是一个多模式匹配算法,在模式匹配领域被广泛应用,举一个经典的例子,违禁词查找并替换为***.AC自动机其实是Trie树和KMP 算法的结合,首先将多模式串建立一个Tire树,然后结合K ...
- 111_Power Pivot 24小时维度:累计、同比、环比相关
博客:www.jiaopengzi.com 焦棚子的文章目录 请点击下载附件 一.背景 今天有朋友讨论怎么做每天24小时维度的工作量计算(运营类企业,每天24小时都在运营)需求如下: 1.从0时到23 ...
- 从标准输入流中读取并执行shell指定函数
巧妙的ohmytmux配置 看oh my tmux的配置,发现他们很巧妙的将配置和shell函数放到一个文件里 比如切换鼠标模式的相关配置和shell函数, # : << EOF # .. ...
- Fail2ban 配置详解 配置说明
fail2ban的配置主要由基础配置(fail2ban.conf)和监禁配置(jail.conf)两部分组成. fail2ban的配置采用标签块"[块名]"和键值"key ...
- 一些实验中用过的python函数/方法(持续更新)
衡量运行时间 很多时候你需要计算某段代码执行所需的时间,可以使用 time 模块来实现这个功能. import time startTime = time.time() # write your co ...
- Java变量, 常量和作用域
目录 变量 作用域 局部变量 实例变量 类变量 常量 命名规范 视频课程 变量 变量就是可以变化的量 Java是一种强类型的语言, 每个变量都必须声明其类型 Java变量是程序中最基本的存储单元, 其 ...
- AR Engine运动跟踪能力,高精度实现沉浸式AR体验
随着电子产品的普遍应用,AR技术也开始广泛普及,在游戏.电商.家装等领域都有涉及.比如,在室内设计时,我们可以通过AR技术在实际场景中进行虚拟软装的搭配,运用华为AR Engine运动跟踪能力在实际应 ...