We usually develop interface parameter types, there are simple types such as Long, String, JSON format, and custom object types. Think about it, if let us develop a set of parameter value mapping code, it is still quite complicated, one is to deal with a lot of parameter types, and there will be some complex scenes, such as multi-layer nesting of objects. Today I’m going to talk about parameter value mapping from two big aspects: abstraction of the process and common parameter types.

1. Process abstraction

Speaking of parameter mapping processing of abstract, you have to mention HandlerMethodArgumentResolver interface:

1. Boolean supportsParameter(MethodParameter parameter); Used to determine whether the implementation class can handle arguments of that type

2.Object resolveArgument(…) After reading parameter values, type conversion, value mapping, etc., return parameters all parameter value processing classes need to implement this interface, following the template pattern in design mode. The process is generally said to be: from a pile of screwdrivers, one by one to judge whether the screwdriver can screw the screw, if the model is a match, then take the screwdriver to screw. SpringMvc also found a tool box for these screwdrivers to put them in. This kit is called: HandlerMethodArgumentResolverComposite, composite is mixed, synthesis. HandlerMethodArgumentResolverComposite to integrate all the parameter values of the processing class together.

Common parameter transmission types

1. Customize the object type

Example:

@RequestMapping("/test1")
public String methodForObjectParam (FamilyDTO familyDTO){
    System.out.println("familyDTO:"+JSON.toJSONString(familyDTO));
    return "";
}
Copy the code

The corresponding parameter values such as ServletModelAttributeMethodProcessor processing

The process of parameter value mapping is as follows:

2.@RequestParam Annotation parameters

Example:

@RequestMapping("/test3")
public String methodForRequestParam (@RequestParam Integer param){
    System.out.println("RequestParam:"+JSON.toJSONString(param));
    return "";
}
Copy the code

The corresponding parameter values such as RequestParamMethodArgumentResolver processing

The steps for parameter mapping are as follows:

1.1 Obtaining Parameters from Request

1.2 Parameter Value Type Conversion: The parameter value obtained from the Request is String and needs to be converted to the corresponding type, such as Integer. Spring-core provides a ton of type conversion tools. I’ve captured some of the classes:

Spring’s power lies not only in its design philosophy and support for complex situations, but also in its strong code base.

3.@RequestBody Annotation parameters

Example:

@RequestMapping("/test6")
public String methodForRequestBody (@RequestBody FamilyDTO familyDTO){
    System.out.println("methodForNormalParam:"+JSON.toJSONString(familyDTO));
    return "";
}
Copy the code

The corresponding parameter value processing such as: RequestResponseBodyMethodProcessor

The steps for parameter mapping are as follows:

1.1 Deserialize body as an object

1.2 If the type is Optional, create an Optional object

4. Simple type, no @requestParam annotation

Example:


@RequestMapping("/test5")
public String methodForNormalParam (Integer param){
    System.out.println("methodForNormalParam:"+JSON.toJSONString(param));
    return "";
}
Copy the code

Param for parameters, and with a @ RequestParam annotation parameters, using RequestParamMethodArgumentResolver class parameter value mapping.

SpringMvc interface invokeForRequest core method in the InvocableHandlerMethod class, you can read the source code:

public Object invokeForRequest(NativeWebRequest request, @Nullable ModelAndViewContainer mavContainer, Object... ProvidedArgs) throws Exception {// Read from request, Object[] args = getMethodArgumentValues(Request, mavContainer, providedArgs); if (logger.isTraceEnabled()) { logger.trace("Invoking '" + ClassUtils.getQualifiedMethodName(getMethod(), getBeanType()) + "' with arguments " + Arrays.toString(args)); Object returnValue = doInvoke(args); if (logger.isTraceEnabled()) { logger.trace("Method [" + ClassUtils.getQualifiedMethodName(getMethod(), getBeanType()) + "] returned [" + returnValue + "]"); } return returnValue; }Copy the code