@RequestBody 原理
在Spring MVC中,DispatcherServlet
是核心的请求分发器,负责将请求分发给相应的处理器(Controller)。@RequestBody
注解用于将HTTP请求体中的数据绑定到方法的参数上。下面是对 DispatcherServlet
和 @RequestBody
的源码分析
1. 请求参数处理的入口:DispatcherServlet
DispatcherServlet
是 Spring MVC 的核心,负责将请求分发给对应的处理器(Controller)。在 doDispatch
方法中,DispatcherServlet
会调用 HandlerAdapter
来处理请求。
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
// 1. 获取处理器(Handler)
HandlerExecutionChain mappedHandler = getHandler(request);
// 2. 获取处理器适配器(HandlerAdapter)
HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
// 3. 调用处理器适配器的 handle 方法
ModelAndView mv = ha.handle(request, response, mappedHandler.getHandler());
// 4. 处理视图渲染等后续逻辑
processDispatchResult(request, response, mappedHandler, mv, dispatchException);
}
2. 处理器适配器:RequestMappingHandlerAdapter
RequestMappingHandlerAdapter
是 Spring MVC 默认的处理器适配器,负责调用带有 @RequestMapping
注解的方法。它的核心方法是 invokeHandlerMethod
,该方法会解析请求参数并调用目标方法。
protected ModelAndView invokeHandlerMethod(HttpServletRequest request,
HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {
// 1. 创建 ServletInvocableHandlerMethod 对象
ServletInvocableHandlerMethod invocableMethod = createInvocableHandlerMethod(handlerMethod);
// 2. 设置参数解析器(HandlerMethodArgumentResolver)
invocableMethod.setHandlerMethodArgumentResolvers(this.argumentResolvers);
// 3. 调用目标方法
invocableMethod.invokeAndHandle(webRequest, mavContainer);
// 4. 返回 ModelAndView
return getModelAndView(mavContainer, modelFactory, webRequest);
}
3. 参数解析的核心:HandlerMethodArgumentResolver
HandlerMethodArgumentResolver
是 Spring MVC 中用于解析方法参数的接口。@RequestBody
注解的处理由 RequestResponseBodyMethodProcessor
完成。
3.1 HandlerMethodArgumentResolver
接口
public interface HandlerMethodArgumentResolver {
// 判断是否支持当前参数
boolean supportsParameter(MethodParameter parameter);
// 解析参数
Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer,
NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception;
}
3.2 RequestResponseBodyMethodProcessor
的实现
RequestResponseBodyMethodProcessor
是 HandlerMethodArgumentResolver
的实现类,专门用于处理 @RequestBody
注解。
public class RequestResponseBodyMethodProcessor implements HandlerMethodArgumentResolver {
@Override
public boolean supportsParameter(MethodParameter parameter) {
// 判断参数是否带有 @RequestBody 注解
return parameter.hasParameterAnnotation(RequestBody.class);
}
@Override
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer,
NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
// 1. 获取请求体内容
Object arg = readWithMessageConverters(webRequest, parameter, parameter.getGenericParameterType());
// 2. 获取参数名称
String name = Conventions.getVariableNameForParameter(parameter);
// 3. 数据绑定和验证
if (binderFactory != null) {
WebDataBinder binder = binderFactory.createBinder(webRequest, arg, name);
if (arg != null) {
validateIfApplicable(binder, parameter);
if (binder.getBindingResult().hasErrors()) {
throw new MethodArgumentNotValidException(parameter, binder.getBindingResult());
}
}
}
return arg;
}
}
4. 请求体内容的读取:HttpMessageConverter
RequestResponseBodyMethodProcessor
使用 HttpMessageConverter
将请求体内容转换为 Java 对象。常用的 HttpMessageConverter
包括:
MappingJackson2HttpMessageConverter
:用于 JSON 数据的转换。StringHttpMessageConverter
:用于字符串的转换。
4.1 readWithMessageConverters
方法
protected <T> Object readWithMessageConverters(NativeWebRequest webRequest, MethodParameter parameter, Type paramType) throws IOException, HttpMediaTypeNotSupportedException {
// 1. 创建 HttpInputMessage 对象
HttpInputMessage inputMessage = createInputMessage(webRequest);
// 2. 遍历所有的 HttpMessageConverter,找到支持当前参数类型的转换器
for (HttpMessageConverter<?> converter : this.messageConverters) {
if (converter.canRead(paramType, inputMessage.getHeaders().getContentType())) {
// 3. 使用转换器读取请求体内容并转换为 Java 对象(这里可以确定是哪个json工具,当项目比较乱时,可能不能直观确定究竟是fastjson还是jackson)
return ((HttpMessageConverter<T>) converter).read(paramType, inputMessage);
}
}
// 4. 如果没有找到支持的转换器,抛出异常
throw new HttpMediaTypeNotSupportedException(contentType, this.allSupportedMediaTypes);
}
4.2 MappingJackson2HttpMessageConverter
的 read
方法
以 JSON 数据为例,MappingJackson2HttpMessageConverter
会将请求体中的 JSON 字符串转换为 Java 对象。
public class MappingJackson2HttpMessageConverter extends AbstractJackson2HttpMessageConverter {
@Override
public Object read(Type type, Class<?> contextClass, HttpInputMessage inputMessage) throws IOException {
// 使用 Jackson 的 ObjectMapper 将 JSON 字符串转换为 Java 对象
return objectMapper.readValue(inputMessage.getBody(), objectMapper.constructType(type));
}
}
5. 数据绑定和验证
在 RequestResponseBodyMethodProcessor
中,解析完请求体内容后,会进行数据绑定和验证。
if (binderFactory != null) {
// 1. 创建 WebDataBinder
WebDataBinder binder = binderFactory.createBinder(webRequest, arg, name);
// 2. 验证数据
if (arg != null) {
validateIfApplicable(binder, parameter);
if (binder.getBindingResult().hasErrors()) {
throw new MethodArgumentNotValidException(parameter, binder.getBindingResult());
}
}
}
6. 总结:@RequestBody
的处理流程
DispatcherServlet
接收到请求后,调用RequestMappingHandlerAdapter
。RequestMappingHandlerAdapter
使用RequestResponseBodyMethodProcessor
解析@RequestBody
注解的参数。RequestResponseBodyMethodProcessor
使用HttpMessageConverter
将请求体内容转换为 Java 对象。- 如果启用了数据绑定和验证,会调用
WebDataBinder
进行数据验证。 - 最终,解析后的参数值会传递给 Controller 方法。
通过以上流程,Spring MVC 能够将 HTTP 请求体中的数据绑定到方法的 @RequestBody
参数上。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具