In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-27 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/03 Report--
This article mainly explains the "in-depth understanding of SpringMVC parameter parser", the content of the article is simple and clear, easy to learn and understand, now please follow the editor's train of thought slowly in depth, together to study and learn "in-depth understanding of SpringMVC parameter parser" bar!
1. Parameter parser
HandlerMethodArgumentResolver is what we call a parameter parser, and it has quite a number of implementation classes, because each type of parameter corresponds to a parameter parser:
For ease of understanding, we can divide these parameter parsers into four categories:
XxxMethodArgumentResolver: this is a normal parameter parser.
XxxMethodProcessor: can be used not only as a parameter parser, but also as a return value of the corresponding type.
XxxAdapter: this is an adapter that does not do parameter parsing and is only used as a parameter parser of type WebArgumentResolver.
HandlerMethodArgumentResolverComposite: this is known by name as a composite parser, which is a proxy for other working parameter parsers.
Generally speaking, it can be divided into these four categories, of which the first two are of course the most important.
two。 Overview of parameter parser
Next, let's take a look at what these parameter parsers are used for.
MapMethodProcessor
This is used to handle parameters of type Map/ModelMap and returns model when parsing is complete.
PathVariableMethodArgumentResolver
This is used to handle parameters that use the @ PathVariable annotation and the parameter type is not Map. If the parameter type is Map, PathVariableMapMethodArgumentResolver is used.
PathVariableMapMethodArgumentResolver
See you.
ErrorsMethodArgumentResolver
This is used to handle Error parameters, such as BindingResult when we do parameter verification.
AbstractNamedValueMethodArgumentResolver
This handles parameters of type key/value, such as request header parameters, parameters annotated with @ PathVariable, Cookie, and so on.
RequestHeaderMethodArgumentResolver
This is used to handle parameters that use the @ RequestHeader annotation and whose parameter type is not Map (use RequestHeaderMapMethodArgumentResolver if the parameter type is Map).
RequestHeaderMapMethodArgumentResolver
See you.
RequestAttributeMethodArgumentResolver
This is used to handle parameters that use the @ RequestAttribute annotation.
RequestParamMethodArgumentResolver
This function is more extensive. Parameters that use the @ RequestParam annotation, the type of file upload MultipartFile, or some basic types that do not use any annotations (Long, Integer), String, etc., all use this parameter parser. It is important to note that if the parameter type of the @ RequestParam annotation is Map, the annotation must have a name value, otherwise the parsing will be done by RequestParamMapMethodArgumentResolver.
RequestParamMapMethodArgumentResolver
See you.
AbstractCookieValueMethodArgumentResolver
This is a parent class that handles parameters that use the @ CookieValue annotation.
ServletCookieValueMethodArgumentResolver
This process uses the parameters of the @ CookieValue annotation.
MatrixVariableMethodArgumentResolver
This process uses the @ MatrixVariable annotation and the parameter type is not a parameter of Map. If the parameter type is Map, use MatrixVariableMapMethodArgumentResolver to handle it.
MatrixVariableMapMethodArgumentResolver
See you.
SessionAttributeMethodArgumentResolver
This is used to handle parameters that use the @ SessionAttribute annotation.
ExpressionValueMethodArgumentResolver
This is used to handle parameters that use the @ Value annotation.
ServletResponseMethodArgumentResolver
This handles parameters of ServletResponse, OutputStream, and Writer types.
ModelMethodProcessor
This is used to handle Model type parameters and return model.
ModelAttributeMethodProcessor
This is used to handle parameters that use the @ ModelAttribute annotation.
SessionStatusMethodArgumentResolver
This is used to handle parameters of type SessionStatus.
PrincipalMethodArgumentResolver
This is used to handle Principal type parameters, which Songge introduced in the previous article (how to customize the parameter parser in SpringBoot?).
AbstractMessageConverterMethodArgumentResolver
This is a parent class, and when you use HttpMessageConverter to parse requestbody type parameters, the related processing classes inherit from it.
RequestPartMethodArgumentResolver
This is used to handle parameters that use the @ RequestPart annotation, MultipartFile, and Part types.
AbstractMessageConverterMethodProcessor
This is a utility class that does not undertake the task of parameter parsing.
RequestResponseBodyMethodProcessor
This is used to handle parameters with @ RequestBody annotations added.
HttpEntityMethodProcessor
This is used to handle parameters of HttpEntity and RequestEntity types.
ContinuationHandlerMethodArgumentResolver
AbstractWebArgumentResolverAdapter
This does not do parameter parsing and is only used as an adapter for a parameter parser of type WebArgumentResolver.
ServletWebArgumentResolverAdapter
This provides request for the parent class.
UriComponentsBuilderMethodArgumentResolver
This is used to handle parameters of type UriComponentsBuilder.
ServletRequestMethodArgumentResolver
This handles parameters of WebRequest, ServletRequest, MultipartRequest, HttpSession, Principal, InputStream, Reader, HttpMethod, Locale, TimeZone, ZoneId types.
HandlerMethodArgumentResolverComposite
From the name, you can see that it is a composite parser, which is a proxy, specifically proxying other working parameter parsers.
RedirectAttributesMethodArgumentResolver
This is used to deal with the parameters of the RedirectAttributes type, RedirectAttributes Song introduced to you in the previous article: the parameters in SpringMVC can still be passed in this way? The posture has gone up.
All right, the general function of each parameter parser is introduced to you, and then we choose one of them to talk about its source code in detail.
3.AbstractNamedValueMethodArgumentResolver
AbstractNamedValueMethodArgumentResolver is an abstract class, and some key-value type parameter parsers are implemented by inheriting it, which defines many of these key-value common operations on type parameter parsers.
Many template patterns are also applied in AbstractNamedValueMethodArgumentResolver. For example, it does not implement the supportsParameter method. The specific implementation of this method is in different subclasses, but it is implemented in the resolveArgument method. Let's take a look at:
@ Override @ Nullable public final Object resolveArgument (MethodParameter parameter, @ Nullable ModelAndViewContainer mavContainer, NativeWebRequest webRequest, @ Nullable WebDataBinderFactory binderFactory) throws Exception {NamedValueInfo namedValueInfo = getNamedValueInfo (parameter); MethodParameter nestedParameter = parameter.nestedIfOptional (); Object resolvedName = resolveEmbeddedValuesAndExpressions (namedValueInfo.name); if (resolvedName = = null) {throw new IllegalArgumentException ("Specified name must not resolve to null: [" + namedValueInfo.name + "]");} Object arg = resolveName (resolvedName.toString (), nestedParameter, webRequest) If (arg = = null) {if (namedValueInfo.defaultValue! = null) {arg = resolveEmbeddedValuesAndExpressions (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 = resolveEmbeddedValuesAndExpressions (namedValueInfo.defaultValue) } if (binderFactory! = null) {WebDataBinder binder = binderFactory.createBinder (webRequest, null, namedValueInfo.name); try {arg = binder.convertIfNecessary (arg, parameter.getParameterType (), parameter);} catch (ConversionNotSupportedException ex) {throw new MethodArgumentConversionNotSupportedException (arg, ex.getRequiredType (), namedValueInfo.name, parameter, ex.getCause ()) } catch (TypeMismatchException ex) {throw new MethodArgumentTypeMismatchException (arg, ex.getRequiredType (), namedValueInfo.name, parameter, ex.getCause ());} / Check for null value after conversion of incoming argument value if (arg = = null & & namedValueInfo.defaultValue = = null & & namedValueInfo.required & &! nestedParameter.isOptional ()) {handleMissingValue (namedValueInfo.name, nestedParameter, webRequest);} handleResolvedValue (arg, namedValueInfo.name, parameter, mavContainer, webRequest); return arg;}
Hongmeng official Strategic Cooperation to build HarmonyOS Technology Community
First, get a NamedValueInfo object based on the current request, which holds three properties of the parameter: the parameter name, whether the parameter must be, and the parameter default value. The specific acquisition process is to get it in the cache first. If there is any in the cache, it will be returned directly. If not in the cache, the createNamedValueInfo method will be called to create it, and the creation result will be cached and returned. The createNamedValueInfo method is a template method, which is implemented in a subclass.
Next, deal with the Optional type parameters.
The resolveEmbeddedValuesAndExpressions method is used to handle situations where SpEL expressions are used in annotations, such as the following interfaces:
@ GetMapping ("/ hello2") public void hello2 (@ RequestParam (value = "${aa.bb}") String name) {System.out.println ("name =" + name);}
If the parameter name uses an expression, the purpose of the resolveEmbeddedValuesAndExpressions method is to parse the value of the expression, and if the expression is not used, the method returns the original parameter intact. 4. Next, call the resolveName method to parse the specific value of the parameter, which is also a template method, and the specific implementation is in the subclass. 5. If the obtained parameter value is null, first check whether there is a default value in the comments, and then check whether the parameter value is required. If so, throw an exception, otherwise set it to null. 6. If the parsed parameter value is an empty string "", take a walk in the resolveEmbeddedValuesAndExpressions method as well. 7. Finally, there is the processing of WebDataBinder, which solves the problem of some global parameters. WebDataBinder Song also introduced three usage scenarios of portal: @ ControllerAdvice in a previous article.
This is the general process.
In this process, we see that the following two main methods are implemented in subclasses:
CreateNamedValueInfo
ResolveName
With the addition of the supportsParameter method, there are three methods in the subclass that we need to focus on.
So let's take RequestParamMethodArgumentResolver as an example to take a look at these three methods.
4.RequestParamMethodArgumentResolver4.1 supportsParameter@Override public boolean supportsParameter (MethodParameter parameter) {if (parameter.hasParameterAnnotation (RequestParam.class)) {if (Map.class.isAssignableFrom (parameter.nestedIfOptional (). GetNestedParameterType () {RequestParam requestParam = parameter.getParameterAnnotation (RequestParam.class); return (requestParam! = null & & StringUtils.hasText (requestParam.name ();} else {return true;}} else {if (parameter.hasParameterAnnotation (RequestPart.class)) {return false } parameter = parameter.nestedIfOptional (); if (MultipartResolutionDelegate.isMultipartArgument (parameter)) {return true;} else if (this.useDefaultResolution) {return BeanUtils.isSimpleProperty (parameter.getNestedParameterType ());} else {return false;}} public static boolean isSimpleProperty (Class type) {return isSimpleValueType (type) | (type.isArray () & & isSimpleValueType (type.getComponentType () } public static boolean isSimpleValueType (Class type) {return (Void.class! = type & & void.class! = type & & (ClassUtils.isPrimitiveOrWrapper (type) | | Enum.class.isAssignableFrom (type) | | CharSequence.class.isAssignableFrom (type) | | Number.class.isAssignableFrom (type) | | Date.class.isAssignableFrom (type) | | Temporal.class.isAssignableFrom (type) | | URI.class = type | | URL.class = = type | | Locale.class = type | | Class.class = type));}
You can easily see the supported parameter types from the supportsParameter method:
Hongmeng official Strategic Cooperation to build HarmonyOS Technology Community
First of all, if the parameter has a @ RequestParam annotation, it can be divided into two cases: if the parameter type is Map, the @ RequestParam annotation must be configured with the name attribute, otherwise it is not supported; if the parameter type is not Map, it is returned directly to true, indicating that it is always supported (think about whether this is the case when you usually use it).
Parameter is not supported if it contains @ RequestPart annotations.
Check whether it is a file upload request, and if so, return true to show support.
If none of the above is returned, the default solution is used to determine whether it is a simple type, mainly Void, enumerations, strings, numbers, dates, and so on.
This code is actually very simple, support who does not support who, at a glance.
4.2 createNamedValueInfo@Override protected NamedValueInfo createNamedValueInfo (MethodParameter parameter) {RequestParam ann = parameter.getParameterAnnotation (RequestParam.class); return (ann! = null? New RequestParamNamedValueInfo (ann): new RequestParamNamedValueInfo ();} private static class RequestParamNamedValueInfo extends NamedValueInfo {public RequestParamNamedValueInfo () {super (", false, ValueConstants.DEFAULT_NONE);} public RequestParamNamedValueInfo (RequestParam annotation) {super (annotation.name (), annotation.required (), annotation.defaultValue ());}}
Get the annotation, read the attributes in the annotation, and construct the RequestParamNamedValueInfo object to return.
4.3 resolveName@Override @ Nullable protected Object resolveName (String name, MethodParameter parameter, NativeWebRequest request) throws Exception {HttpServletRequest servletRequest = request.getNativeRequest (HttpServletRequest.class); if (servletRequest! = null) {Object mpArg = MultipartResolutionDelegate.resolveMultipartArgument (name, parameter, servletRequest); if (mpArg! = MultipartResolutionDelegate.UNRESOLVABLE) {return mpArg;}} Object arg = null; MultipartRequest multipartRequest = request.getNativeRequest (MultipartRequest.class); if (multipartRequest! = null) {List files = multipartRequest.getFiles (name) If (! files.isEmpty ()) {arg = (files.size () = = 1? Files.get (0): files);}} if (arg = = null) {String [] paramValues = request.getParameterValues (name); if (paramValues! = null) {arg = (paramValues.length = = 1? ParamValues [0]: paramValues);}} return arg;}
The idea of this method is also relatively clear:
Hongmeng official Strategic Cooperation to build HarmonyOS Technology Community
The first two if are mainly used to handle file upload requests.
If it is not a file upload request, call the request.getParameterValues method to retrieve the parameters and return them.
The whole process is quite easy. On this basis, friends can analyze the principle of PathVariableMethodArgumentResolver by themselves, which is also very easy.
Thank you for your reading, the above is the content of "in-depth understanding of SpringMVC parameter parser", after the study of this article, I believe you have a deeper understanding of the problem of in-depth understanding of SpringMVC parameter parser, and the specific use needs to be verified in practice. Here is, the editor will push for you more related knowledge points of the article, welcome to follow!
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: 0
*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.