In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-03-31 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/01 Report--
Editor to share with you how to solve the occasional abnormal problem of MissingServletRequestParameterException, I hope you will gain something after reading this article, let's discuss it together!
Overview
Recently, we have encountered an occasional problem. When making a request to the server, there is an occasional exception. The query String in the request passes parameters, but an exception MissingServletRequestParameterException occurs.
As follows:
41469-[a626f375-7f79-4fd2-88bemurine 1db10a3811cb -] [nio-8080-exec-7] c.s.s.f.ValidationGlobalExceptionHandler: org.springframework.web.bind.MissingServletRequestParameterException: Required long parameter 'xxx' is not present at org.springframework.web.method.annotation.RequestParamMethodArgumentResolver.handleMissingValue (RequestParamMethodArgumentResolver.java:198) at org.springframework.web.method.annotation.AbstractNamedValueMethodArgumentResolver.resolveArgument (AbstractNamedValueMethodArgumentResolver.java:109) at org.springframework .web.method.support.HandlerMethodArgumentResolverComposite.roomveArgument (HandlerMethodArgumentResolverComposite.java:121) at org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues (InvocableHandlerMethod.java:158) at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest (InvocableHandlerMethod.java:128) at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle (ServletInvocableHandlerMethod.java:97) at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod (RequestMappingHandlerAdapter.java:827) at Org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal (RequestMappingHandlerAdapter.java:738) at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle (AbstractHandlerMethodAdapter.java:85) at org.springframework.web.servlet.DispatcherServlet.doDispatch (DispatcherServlet.java:963) at org.springframework.web.servlet.DispatcherServlet.doService (DispatcherServlet.java:897) at org.springframework.web.servlet.FrameworkServlet.processRequest (FrameworkServlet.java:970) at org.springframework.web .servlet.FrameworkServlet.Doget (FrameworkServlet.java:861) at javax.servlet.http.HttpServlet.service (HttpServlet.java:635) at org.springframework.web.servlet.FrameworkServlet.service (FrameworkServlet.java:846) at javax.servlet.http.HttpServlet.service (HttpServlet.java:742) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter (ApplicationFilterChain.java:231) at org.apache.catalina.core.ApplicationFilterChain.doFilter (ApplicationFilterChain.java:166) at org.apache .tomcat.websocket.server.WsFilter.doFilter (WsFilter.java:52)
Obviously with this parameter in the request, I thought I was dizzy at first, so I tried it again, and the interface returned to normal again.
However, now that the error log appears, it can not be easily let go, especially this occasional error, which is full of risks and is very likely to break out at some critical moment. So I decided to take the time to investigate the problem. Next, there is the whole process of investigation.
Investigation process
The specific request is as follows:
Curl-X GET-- header "Accept: * / *" http://localhost:8080/xxx/api/v3/xxx/getXX?param=123456
Param is declared as required=true in the Controller method, that is, a required parameter, which is bound to be passed in front-end interaction.
Since this is an occasional problem, it is not possible to reproduce the problem by manually calling the request over and over again. Here I use Jmeter as the request trigger to repeat requests for 30 times, resulting in a request exception the first time I run.
After running two or three times, the same result has been achieved. Now that the problem has been identified and can be stably reproduced, the next step is how to find the root cause of the problem and solve it.
Because there is a specific exception class, my first idea is to add a breakpoint to the constructor of the exception class to see why the exception is thrown. Through the call stack, the following code snippet is found in RequestParamMethodArgumentResolver (AbstractNamedValueMethodArgumentResolver)
Object arg = resolveName (resolvedName.toString (), nestedParameter, webRequest); / / in RequestParamMethodArgumentResolver, get the normal request parameter if (arg = = null) {if (namedValueInfo.defaultValue! = null) {arg = resolveStringValue (namedValueInfo.defaultValue) directly by calling request.getParameterValues (name). } else if (namedValueInfo.required & &! nestedParameter.isOptional ()) {handleMissingValue (namedValueInfo.name, nestedParameter, webRequest); / / if it is not obtained and there is no default value, an exception will be thrown here. } arg = handleNullValue (namedValueInfo.name, arg, nestedParameter.getNestedParameterType ());} else if (".equals (arg) & & namedValueInfo.defaultValue! = null) {arg = resolveStringValue (namedValueInfo.defaultValue);}
When I saw this, I couldn't help but wonder, is it true that there are no parameters? Or is the parameter lost in the process of passing? Or... Eaten by the frame?!
But doubt is not what I want, the answer is what I want. Since you don't get the desired value in request.getParameterValues, you should find out how this value is set when a normal request is made.
The first thing that comes to mind is to look at the class diagram structure of Request. And the flowchart of the request being processed
So, the original data is stored in the org.apache.coyote.Request class, and by going deep into this class, we can get closer to the answer. So go directly to the service method of Http11Processor to see the specific processing process. First of all, add the breakpoint on line 799 to see what the result is. Since the problem is on parameter, check the various values of parameters in request at this time.
Normal request:
Exception request:
Comparing the two, it is not difficult to find that the queryMB in the abnormal request is the same as that in the normal request, that is, the parameters in our request are passed to the server. But the exception request didQueryParameters is set to true, and it can be seen from the code that this code is actually used to determine whether the query string has been parsed, and when the request processing ends, the recycle method of parameter is called
Public void recycle () {parameterCount = 0; paramHashValues.clear (); / / whether the parsed parameter map didQueryParameters=false; / / has been parsed, set to false encoding=null; decodedQuery.recycle (); parseFailedReason = null;}
Because Request and Response objects are recycled in Tomcat, this is also the time when the entire Request is reset.
So the root cause is that after Parameter is reset, didQueryParameters is set to true again, so that the new request parameters are not parsed correctly and an error is reported (at this time the parameterMap has been reset and empty).
DidQueryParameters is set to true only in one case, that is, when the handleQueryParameters method is called.
HandleQueryParameters is called in multiple scenarios, one of which is getParameterValues, which gets the value of the request parameter.
At this point, you can infer that there may be code in the application, and after the request ends, the parameter values are still obtained through the Request object.
Global search for places that reference HttpServletRequest. Finally, it is found that there is the following code in the burying point class
Async public void buryPoint (long userId, HttpServletRequest request.) {if (request! = null) {xxx = request.getParameter ("xxx");}
Because this logic is executed asynchronously, it is entirely possible to still call the request.getParameter method after the request ends, resulting in the next request parameter not being parsed. Comment out this code, re-use Jmeter to make the request, and the error no longer occurs.
Conclusion
Do not pass HttpServletRequest to any asynchronous methods!
After reading this article, I believe you have a certain understanding of "how to solve the occasional abnormal problem of MissingServletRequestParameterException". If you want to know more about it, you are welcome to follow the industry information channel. Thank you for reading!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 225
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.