Spring源码解析 – SpringWeb请求参数获取解析
简介
在文章:Spring Web 请求初探中,我们看到最后方法反射调用的相关代码,本篇文章就探索其中的参数是如何从请求中获取的
概览
方法反射调用的关键代码如下:
public class InvocableHandlerMethod {
protected Object doInvoke(Object... args) throws Exception {
Method method = getBridgedMethod();
ReflectionUtils.makeAccessible(method);
try {
if (KotlinDetector.isSuspendingFunction(method)) {
return CoroutinesUtils.invokeSuspendingFunction(method, getBean(), args);
}
return method.invoke(getBean(), args);
}
catch (IllegalArgumentException ex) {
......
}
}
}
现在我们更新我们的代码如下,增加接个参数:
import com.example.springexample.vo.User;
import org.springframework.web.bind.annotation.*;
@RestController
public class HelloWorld {
@GetMapping("/")
public String helloWorld(@RequestParam(value = "id") Integer id,
@RequestParam(value = "name") String name) {
return "Hello world:" + id;
}
@GetMapping("/test1")
public String helloWorld1(@RequestHeader(value = "id") Integer id) {
return "Hello world:" + id;
}
@PostMapping("/test2")
public String helloWorld2(@RequestBody User user) {
return "Hello world:" + user.toString();
}
}
发起下面的请求,在上面反射调用的代码中打上断点,跟踪调用栈分析:
GET http://localhost:8080/?id=1&id=2
POST http://localhost:8080/test2
Content-Type: application/json
{"name": "name", "password": "password"}
源码解析
首先查看调用栈,我们找到了参数最开始获取的相关代码,在下面的代码中获取相关的参数:
# InvocableHandlerMethod.java
@Nullable
public Object invokeForRequest(NativeWebRequest request, @Nullable ModelAndViewContainer mavContainer,
Object... providedArgs) throws Exception {
// 得到了相关的参数
Object[] args = getMethodArgumentValues(request, mavContainer, providedArgs);
if (logger.isTraceEnabled()) {
logger.trace("Arguments: " + Arrays.toString(args));
}
return doInvoke(args);
}
继续跟踪看看函数:getMethodArgumentValues
# InvocableHandler