简介
不知道你是否清楚我们controller中方法的参数如何来的,我们的方法返回值如何处理的呢,我们requestBody中的内容(xml,properties,json)如何转化为方法参数的呢,我们返回的bean如何转变为reponse body 中的特定格式的响应内容的呢?本文将解开谜团。
大致流程图解
通过上图,引入了几个相关概念。
处理方法参数解析器 HandlerMethodArgumentResolver 用于 HTTP 请求中解析 HandlerMethod 参数内容
处理方法返回值解析器 HandlerMethodReturnValueHandler 用于 HandlerMethod 返回值解析为 HTTP 响应内容HTTP消息转换 HttpMessageConverter HTTP 消息转换器,用于反序列化 HTTP 请求或序列化响应
流程分析
当我们使用restful 的时候通常会这样写:
@RestController
public class PropertiesRestController {
@PostMapping("/index")
public User index(@RequestBody User user) {
return user;
}
}
现在我们以该restful为背景分两部分进行分析
1方法参数的解析工作
我们通过postman进行请求
//参数转化的堆栈流程
read:222, AbstractJackson2HttpMessageConverter (org.springframework.http.converter.json)
readWithMessageConverters:206, AbstractMessageConverterMethodArgumentResolver (org.springframework.web.servlet.mvc.method.annotation)
readWithMessageConverters:157, RequestResponseBodyMethodProcessor (org.springframework.web.servlet.mvc.method.annotation)
resolveArgument:130, RequestResponseBodyMethodProcessor (org.springframework.web.servlet.mvc.method.annotation)
resolveArgument:124, HandlerMethodArgumentResolverComposite (org.springframework.web.method.support)
getMethodArgumentValues:161, InvocableHandlerMethod (org.springframework.web.method.support)
invokeForRequest:131, InvocableHandlerMethod (org.springframework.web.method.support)
invokeAndHandle:102, ServletInvocableHandlerMethod (org.springframework.web.servlet.mvc.method.annotation)
invokeHandlerMethod:877, RequestMappingHandlerAdapter (org.springframework.web.servlet.mvc.method.annotation)
handleInternal:783, RequestMappingHandlerAdapter (org.springframework.web.servlet.mvc.method.annotation)
handle:87, AbstractHandlerMethodAdapter (org.springframework.web.servlet.mvc.method)
doDispatch:991, DispatcherServlet (org.springframework.web.servlet)
doService:925, DispatcherServlet (org.springframework.web.servlet)
上面的堆栈流程就是具体解析的过程,对源码感兴趣的可以到源码中看相应方法的实现。这里需要重点说明一下的是
RequestResponseBodyMethodProcessor就具体处理我们的@requestBody 和@responseBody,他既是方法参数处理器又是方法返回值处理器
返回值得处理
这里我们需要补充一点额外的知识
那就是Spring Web MVC REST 内容协商处理流程,说白了就是使用哪个转换器进行相关的序列化和反序列化操作,具体来说就是
RequestResponseBodyMethodProcessor中利用ContentNegotiationManager选出浏览器期望的媒体类型,然后去converter中进行匹配,找到匹配的第一个来进行序列化和反序列化。
到此,我想要讲解的内容基本就完成了。谢谢大家的支持。
本篇文章的核心内容在堆栈流程图上面,期望读者进行具体分析。
spring boot中HttpMessageConverter的所有默认实现类
0 = {ByteArrayHttpMessageConverter@8529}
1 = {StringHttpMessageConverter@8530}
2 = {StringHttpMessageConverter@8531}
3 = {ResourceHttpMessageConverter@8532}
4 = {ResourceRegionHttpMessageConverter@8533}
5 = {SourceHttpMessageConverter@8534}
6 = {AllEncompassingFormHttpMessageConverter@8535}
7 = {MappingJackson2HttpMessageConverter@8536}
8 = {MappingJackson2HttpMessageConverter@8537}
9 = {Jaxb2RootElementHttpMessageConverter@8538}