3.13 @RequestBody注解 3.13.1 HttpMessageConverter接口

3.13 @RequestBody注解

用途:处理JSON、XML等数据

org.springframework.web.bind.annotation.RequestBody注解常用来处理ContentType不是application/x-ww-form-urlencoded编码的内容,例如application/json,application/xml等。

使用HttpMessageConverters类解析JSON、XML

@RequestBody注解通过使用HandlerAdapter配置的HttpMessageConverters来解析JSONxml数据,然后绑定到相应的Bean上。

3.13.1 HttpMessageConverter接口

用途

HttpMessageConverter<T>Spring3.0之后新增的一个重要接口,它负责将请求信息转换为一个对象(类型为T),并将对象(类型为T)绑定到请求方法的参数上或输出为响应信息

由RequestMappingHandlerAdapter使用

DispatcherServlet默认已经装配了RequestMappingHandlerAdapter作为HandlerAdapter组件的实现类,即:HttpMessageConverterRequestMappingHandlerAdapter使用,将请求信息转换为对象,或将对象转换为响应信息

HttpMessageConverter接口方法

HttpMessageConverter<T>接口中定义了以下几个方法

方法 描述
boolean canRead(Class<?>clazz,MediaType mediaType) 该方法指定转换器可以读取的对象类型,
即转换器可将请求信息转换为clazz类型的对象,
同时指定支持的MIME类型(text/htmlapplication/json等)。
MIME媒体类型在RFC2616中定义,
具体请参考http://tools.ietf.org/html/rfc2616#section-3.7上的说明。
boolean canWrite(Class<?>clazz,MediaType mediaType) 该方法指定转换器可以将clazz类型的对象写到响应流当中,
响应流支持的媒体类型在mediaType中定义。
List<MediaType> getSupportedMediaTypes() 该方法返回当前转换器支持的媒体类型。
T read(Class<?extendsT> clazz,HttpInputMessage inputMessage) 该方法将请求信息流转换为T类型的对象
void write(T t,MediaType contentType,HttpOutputMessage outputMessage) 该方法将T类型的对象写到响应流当中,同时指定响应的媒体类型为contentType

Spring提供的HttpMessageConverter接口实现类

SpringHttpMessageConverter<T>提供了多个实现类,这些实现类组成了一个功能强大、用途广泛的信息转换家族。详细说明如下:

实现类 描述
StringHttpMessageConverter
  • 将请求信息转换为字符串,
  • 泛型T为String类型,
  • 可以读取所有媒体类型(*/*)的请求信息,可通过设置supportedMediaTypes属性指定媒体类型。响应信息的媒体类型为text/plain(即Content-Type的值)。
FormHttpMessageConverter
  • 将表单数据读取到MultiValueMap中,
  • 泛型T为org.springframework.util.MultiValueMap<String,?>类型,
  • 支持读取application/x-www-form-urlencoded类型的信息,但不支持读取multipart/form-data类型的信息。
  • 可以写application/x-www-form-urlencodedmultipart/form-data类型的响应信息。
SourceHttpMessageConverter 如果部分表单属性是XML数据,则可用该转换器进行转换。
ResourceHttpMessageConverter
  • 读写org.springframework.core.io.Resource对象,
  • 泛型T为org.springframework.core.io.Resource对象,
  • 可以读取所有媒体类型(*/*)的请求信息。如果类路径下提供了JAFJavaActivationFramework),则根据Resource的类型指定响应的类型,否则响应的类型为application/octet-stream
BufferedImageHttpMessageConverter
  • 读写BufferedImage对象,
  • 泛型T为BufferedImage对象,
  • 可以读取所有类型(*/*)的请求信息,返回BufferedImage相应的类型,也可以通过contentType显式指定。
ByteArrayHttpMessageConverter
  • 读写二进制数据,
  • 泛型T为byte[]类型,
  • 可以读取所有类型(*/*)的请求信息,可以通过设置supportMediaTypes属性指定类型,响应信息的媒体类型为application/octet-stream
SourceHttpMessageConverter
  • 读写javax.xml.transform.Source类型的数据,
  • 泛型T为javax.xml.transform.Source类型及其扩展类型包括:
    • javax.xml.transform.dom.DOMSource
    • javax.xml.transform.sax.SAXSource
    • javax.xml.transform.stream.StreamSource;
  • 可以读取text/xmlapplication/xml类型请求,响应信息的类型为text/xmlapplication/xml
MarshallingHttpMessageConverter
  • 通过Springorg.springframework.oxm.Marshalling(将Java对象转换成XML)和Unmarshaller(将XML解析为Java对象)读写XML消息
  • 泛型T为Object类型;可以读取text/xmlapplication/xml类型请求,
  • 响应信息的类型为text/xmlapplication/xml
Jaxb2RootElementHttpMessageConverter
  • 通过JAXB2读写XML消息,将请求消息转换到注解@XmlRootElementXmlType作用的类中。
  • 泛型T为Object类型;
  • 可以读取text/xmlapplication/xml类型请求,响应信息的类型为text/xmlapplication/xml
MappingJackson2HttpMessageConverter
  • 利用Jackson开源类包读写JSON数据。
  • 泛型T为Object类型;
  • 可以读取application/json类型的数据,响应信息的类型为application/json
RssChannelHttpMessageConverter
  • 能够读写RSS种子消息;
  • 泛型T为com.sun.syndication.feed.rss.Channel类型;
  • 可以读取application/rss+xml类型的数据,响应信息的类型为application/rss+xml
AtomFeedHttpMessageConverter
  • 能够读写RSS种子消息。
  • 泛型T为com.sun.syndication.feed.atom.Feed类型;
  • 可以读取application/atom+xml类型的数据,响应信息的类型为application/atom+xml

默认装配的HandlerAdapter实现类

DispatcherServlet默认已经装配了RequestMappingHandlerAdapter作为HandlerAdapter组件的实现类;RequestMappingHandlerAdapter默认已经装配了以下的HttpMessageConverter:

  • StringHttpMessageConverter
  • ByteArrayHttpMessageConverter
  • SourceHttpMessageConverter

自定义RequestMappingHandlerAdapter

如果需要装配其他类型的HttpMessageConverter,则可以在SpringWeb容器的上下文中自定义一个RequestMappingHandlerAdapter,如下所示:

1
2
3
4
5
6
7
8
9
10
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
<property name="messageConverters">
<list>
<bean class="org.springframework.http.comverter.StringHttpMessageConverter"/>
<bean class="org.springframework.http.comverter.xml.SourceHttpMessageConverter"/>
<bean class="org.springframework.http.comverter.ByteArrayHttpMessageConverter"/>
<bean class="org.springframework.http.comverter.BufferedImageHttpMessageConverter"/>
</list>
</property>
</bean>

自定义后默认装配的HttpMessageConverter

提示如果在Spring Web容器中显式定义了一个RequestMappingHandlerAdapter,则Spring MVCRequestMappingHandlerAdapter默认装配的HttpMessageConverter将不再起作用。