• 概述
  • 问题分析
  • 结论
  • 一、概述
  • 最近开发过程中,遇到一个问题,在向Tomcat服务器进行请求时候,发现,偶尔出现异常,但是在前端传递param参数,并且这个参数是required=true,但是出现了MissingServletRequestParameterException报错问题。
  •           由于这个问题并不是经常出现,偶尔出现问题,使用Jmeter 作为模拟器,进行请求模拟,结果在模拟过程中有出现了同样MissingServletRequestParameterException报错信息。
  • 传输参数时候,如果某个参数值并没有写 判断时候应该要 先判断 str==null,在去判断 str.isEmpty()
  • 二、问题分析
  •  直接在这个异常类的函数设置断点,查看其为什么抛出这样的异常:
  •        第一步:查看该异常父类结构图: 从结构中看到其属于ServletRequestBlindingException( 说其是属于Request信息中绑定)
  • 但是在 前端传递参数过程,param是required,说明前端肯定传递参数,说明此参数值在传递过程中是不是被Spring框架给吃了?
  • at org.springframework.web.method.annotation.RequestParamMethodArgumentResolver.handleMissingValue(RequestParamMethodArgumentResolver.java:198)at org.springframework.web.method.annotation.AbstractNamedValueMethodArgumentResolver.resolveArgument(AbstractNamedValueMethodArgumentResolver.java:109)
  • 直接找到handleMissingValue()方法,发现其中并没有解释,直接断点定位到RequestParamMethodArgumentResolver的父类AbstractNamedValueMethodArgumentResolver,
  • 在其父类中我们发现如下代码:
  •  Object arg = resolveName(resolvedName.toString(), nestedParameter, webRequest); //在RequestParamMethodArgumentResolver中,直接通过调用request.getParameterValues(name)来获取普通请求的参数if (arg == null) {if (namedValueInfo.defaultValue != null) {arg = resolveStringValue(namedValueInfo.defaultValue);}else if (namedValueInfo.required && !nestedParameter.isOptional()) {handleMissingValue(namedValueInfo.name, nestedParameter, webRequest); //如果没有获取到且没有默认值,就会在这里抛出异常。}arg = handleNullValue(namedValueInfo.name, arg, nestedParameter.getNestedParameterType());}else if ("".equals(arg) && namedValueInfo.defaultValue != null) {arg = resolveStringValue(namedValueInfo.defaultValue);}
  • 从父类中分析 :request.getParameterValue()里面并没有得到想要值,并且参数是 必须且没有默认的参数值,才会抛出对应异常,因此产生疑问:参数传递过程中难道被框架给吞了????
  • 在此基础上:对Tomcat服务器的源码进行分析:
  • 参考:Tomcat源码分析(四)—— Request和Response处理的全过程
  • 在此博客中写道: 用户的一个Request请求:将最原始的Socket进行一系列的包装,最后到达HttpServletRequest和HttpServletResponse

  • 最原始的数据保存在org.apache.coyote.Request,Tomcat服务器 中HTTP1Process 类通过service方法传递给coyote,定位到Request请求中参数param出现问题;直接跳到:RequestmappingHandlerAdapter 这个类中
  • at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:738)

    设置断点:对于正常请求:didQueryParamters=false

  • 但是在异常请求中 didQueryParamters=true;
  • 这个参数判断query String 是否已经被解析过,并且在结束时候,会调用paramter的recycle方法,
  • 同时查看 其中对应的recyle()方法:当数据被解析之后,发现recycle()方法会将paramter参数进行清空,并且didQueryParameters 参数置为true.
  •    public void recycle() {parameterCount = 0;paramHashValues.clear(); //清空了解析后的parameter mapdidQueryParameters=false; //是否被解析过,置成falseencoding=null;decodedQuery.recycle();parseFailedReason = null;}

    为什么paramters参数值在首次Request中会被解析:

  • Tomcat 中,Request的对象会被循环使用,因此一定是在进入Spring 框架之前被解析过(或者是被异步执行过),因此在一次获取时候发现其出现 空值异常;
    所以根本原因是,在Parameter被重置了之后,didQueryParameters又被置成了true,导致新的请求参数没有被正确解析,就报错了(此时的parameterMap已经被重置,为空)。而didQueryParameters只有在一种情况下才会被置为true,也就是handleQueryParameters方法被调用时。而handleQueryParameters会在多个场景中被调用,其中一个就是getParameterValues,获取请求参数的值
  • 最终通过全局搜索:引用HttpServeletRequest 地方,最终发现buryPoint()方法,这个方法属于异步执行方法,在请求结束之后依然调用Request.getParamter()方法,导致下一次请求解析参数不被解析:
@Asyncpublic void buryPoint(long userId, HttpServletRequest request.....) {if (request != null) {xxx = request.getParameter("xxx");}
  •          

MissingServletRequestParameterException 引发深思相关推荐

  1. 这5条职场心机,句句真实,引发深思

    1.人最难沟通的是说服,十之八九的领导,你越劝效果越不好,肺腑之言说多了,领导反而怀疑你动机,所以说服要有度,提醒一下,点到即可. 2.在职场,如果在不了解事情真相之前,别先急着发表意见.特别是遇到非 ...

  2. 不花一分钱开12家美容院,一年赚3000万,背后商业模式引发深思!

    李姐在深圳经营美容行业多年,同时兼任深圳美业协会的会长,因为属于技术出身,对营销不是很擅长,导致企业经营多年,发展并不是很理想,但是李姐的技术过硬,配套设施.服务都做得非常好. 这两年,因为竞争加剧, ...

  3. 万引大佬自曝这样被MIT拒掉:“系里不喜欢你”,找校长对峙后悟了

    点击上方"视学算法",选择加"星标"或"置顶" 重磅干货,第一时间送达 鱼羊 丰色 发自 凹非寺 量子位 | 公众号 QbitAI 想拿到M ...

  4. [顶]ORACLE PL/SQL编程详解之二:PL/SQL块结构和组成元素(为山九仞,岂一日之功)...

    [顶]ORACLE PL/SQL编程详解之二:PL/SQL块结构和组成元素(为山九仞,岂一日之功) 原文:[顶]ORACLE PL/SQL编程详解之二:PL/SQL块结构和组成元素(为山九仞,岂一日之 ...

  5. 珍惜时间, 珍惜生命

    哈佛老师经常给学生这样的告诫:如果你想在进入社会后,在任何时候任何场合下都能得心应手并且得到应有的评价,那么你在哈佛的学习期间,就没有晒太阳的时间. 作为闻名于世的学府,哈佛大学培养了许多名人,他们中 ...

  6. 你并没有那么去努力 所以你不能怪生活

    美国哈佛大学图书馆凌晨4点座无虚席 --哈佛,看一眼就会明白中国缺什么 日前,两张美国哈佛大学图书馆凌晨4点多学生仍在学习的照片,在网上迅速传播. 照片显示:凌晨4点的哈佛大学图书馆里,灯火通明,座无 ...

  7. 给中国学生的第七封信:21世纪最需要的7种人才(李开复)

    博文 给中国学生的第七封信:21世纪最需要的7种人才 人才的标准从来都不是一成不变的.在东方的战国时代和西方的骑士时代里,最受器重的是力敌万夫的勇士和巧舌善辩的谋臣:在中国的科举时代里,靠着" ...

  8. 普通人卖什么才能赚到人生的第一桶金?

    我们都是平凡人,包括我,也可能包括你!作为平凡人,在没钱.没资源.没产品这三座大山前,如何改变自己,改变命运呢? 改变命运,除了是精神上的,更重要的是能赚到钱,赚到足以让你过的不错的钱.怎么做呢?萃见 ...

  9. 【中国数据创新琅琊榜】数联易康医疗大数据平台,创新健康医疗产业变革的推动者和见证者!

    古之"琅琊榜"让最优秀的青年才俊闻名天下,而"中国数据创新琅琊榜"正是为积极鼓励那些在各自领域不断创新,不断突破的企业,从行业角度出发,对以数据创新驱动业务发展 ...

最新文章

  1. 希望增加的BLOG功能(序)
  2. PowerShell 备份sharepoint站点命令
  3. 【Linux环境部署】最新版 elasticsearch + kibana(7.15.0)安装、配置、启动(多个问题处理 + kibana仪表盘使用)
  4. CodeForces - 1332D Walk on Matrix(构造)
  5. php.ini配置详解 号,php INI配置文件的解析实现分析
  6. 卷积神经网络CNN是靠什么线索学习到深度信息的?
  7. 基础知识之什么是I/O
  8. redis value多大会影响性能_Redis 最常见面试问题
  9. 手机怎么用外嵌字幕_怎么用手机给视频添加字幕?原来方法这么简单,3分钟教你学会...
  10. 软件推荐,强力卸载软件geek uninstaller
  11. 怎么把pdf文件压缩到最小?
  12. Java岗大厂面试百日冲刺 - 日积月累,每日三题【Day29】
  13. 如何写出一篇好文章——不动笔就能学会写文章的训练法
  14. Java Development - String
  15. 大型连锁药店管理系统源码
  16. 睿普康 以太网接口PHY芯片主要替换瑞昱的pin对pin芯片
  17. Stata 转 Excel —— export excel 命令详解
  18. 2020年国内外风电发展规模及风电场建设情况[图]
  19. 从360手机看互联网大佬们混战智能手机市场意欲何为(1)
  20. Abaqus2021关联Solidworks2022成功方法

热门文章

  1. php grpc,PHP配置grpc
  2. 智能车竞赛比赛校赛进展
  3. 神奇的小石子 dfs(深搜) 考核补题
  4. 泛在电力物联网深度报告之一:架构、场景及投资机会
  5. 【§极品网游之我叫mt online电脑版免费中文版§】
  6. 验证码识别打码的常见问题及使用方法
  7. 2022广州电商展,2022广州跨境电商展
  8. 匿名地面站V6.5传输协议
  9. 一个IT从业者的课外读物___经济管理篇
  10. java 自适应屏幕_自适应屏幕的CSS响应式布局设计技巧总结