阅读完需:约 3 分钟
Http请求响应报文其实都是字符串,当请求报文到java程序会被封装为一个ServletInputStream
流,开发人员再读取报文,响应报文则通过ServletOutputStream
流,来输出响应报文。
从流中只能读取到原始的字符串报文,同样输出流也是。那么在报文到达SpringMVC / SpringBoot和从SpringMVC / SpringBoot出去,都存在一个字符串到java对象的转化问题。这一过程,在SpringMVC / SpringBoot中,是通过HttpMessageConverter
来解决的。
例子:
@RequestMapping("/test")
@ResponseBody
public String test(@RequestBody String param) {
return "param '" + param + "'";
}
在请求进入test方法前,会根据@RequestBody
注解选择对应的HttpMessageConverter
实现类来将请求参数解析到param变量
中,因为这里的参数是String类型的,所以这里是使用了StringHttpMessageConverter
类,它的canRead()
方法返回true,然后read()方法会从请求中读出请求参数,绑定到test()方法的param
变量中。
同理当执行test方法后,由于返回值标识了@ResponseBody
,SpringMVC / SpringBoot将使用StringHttpMessageConverter
的write()方法,将结果作为String值写入响应报文,当然,此时canWrite
()方法返回true。

在Spring的处理过程中,一次请求报文和一次响应报文,分别被抽象为一个请求消息HttpInputMessage
和一个响应消息HttpOutputMessage
。
处理请求时,由合适的消息转换器将请求报文绑定为方法中的形参对象,在这里同一个对象就有可能出现多种不同的消息形式,如json、xml。同样响应请求也是同样道理。
在Spring中,针对不同的消息形式,有不同的HttpMessageConverter
实现类来处理各种消息形式,至于各种消息解析实现的不同,则在不同的HttpMessageConverter
实现类中。
HttpMessageConverter
的自动配置类

针对HttpMessageConverter
的自动配置类。HttpMessageConvertersAutoConfiguration
会综合考虑jackson
,gson
,jsonb
包的引用情况
以及配置项spring.http.converters.preferred-json-mapper
的使用情况决定引入相应的json HttpMessageConverter bean
,并定义一个StringHttpMessageConverter bean
然后基于容器中所有的HttpMessageConverter bean
,定义一个HttpMessageConverters bean
(仅在该bean为定义时定义它)。
缺省情况下,HttpMessageConvertersAutoConfiguration
所定义的HttpMessageConverters bean
中通常包含两个HttpMessageConverter bean
:
-
MappingJackson2HttpMessageConverter bean
-
StringHttpMessageConverter bean
(缺省字符集UTF-8)
自定义 HttpMessageConverter
以及源码分析: