SpringMVC-信息转换

信息转换发生在请求处理方法的入参过程中,把请求信息转换为一个对象。

HttpMessageConverter<T> 接口

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

DispatcherServlet 默认已经装配了 RequestMappingHandlerAdapter 类作为 HandlerAdapter 组件的实现类,在 RequestMappingHandlerAdapter 类中使用了 HttpMessageConverter

HttpMessageConverter<T> 方法

  • boolean canRead(Class<?> clazz,MediaType mediaType):指定转换器可以读取的对象类型。
  • boolean canWrite(Class<?> clazz,MediaType mediaType):指定转换器可以将 clazz 类型的对象写到响应流中。
  • List<MediaType> getSupportedMediaTypes():返回当前转换器支持的媒体类型。
  • T read(Class<? extends T> clazz,HttpInputMessage inputMessage):将请求信息流转换为 T 类型的对象。
  • void write(T t,MediaType contentType,HttpOutputMessage outputMessage):将 T 类型的对象写到响应流当中,同时指定相应的媒体类型为 contentType。

HttpMessageConverter<T> 实现类

HttpMessageConverter<T> 提供了多个实现类:

  • StringHttpMessageConverter (默认装配):将请求信息转换为字符串。

  • FormHttpMessageConverter :将表单数据读取到 MultiValueMap 中。

  • XmlAwareFormHttpMessageConverter (默认装配):继承自 FormHttpMessageConverter ,如果部分表单属性是 XML 数据,则可用该转换器进行转换。

  • ResourceHttpMessageConverter:读写org.springframework.core.io.Resource 对象。

如果需要装配其他类型的 HttpMessageConverter ,可以在 Spring 的 Web 容器中自行定义一个 RequestMappingHandlerAdapter

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

转换 JSON 数据

SpringMVC 提供了处理 JSON 格式请求/响应的 HttpMessageConverter:

  • MappingJackson2HttpMessageConverter:利用 Jackson 开源类包处理 JSON 格式的请求或响应信息。

只需要在配置文件中为 RequestMappingHandlerAdapter 装配处理 JSON 的 HttpMessageConverter,并在交互过程中通过请求的 Accept 指定 MIME 类型,SpringMVC 就可以使服务端的处理方法和客户端 JSON 格式的消息进行通信。

org.springframework.web.bind.annotation.RequestBody 注解用于读取 Request 请求的 body 部分的数据,使用系统默认配置的 HttpMessageConverter 进行解析,然后把相应的数据绑定到 Controller 中方法的参数上。

当前台页面使用 GET 或 POST 提交数据时,数据编码格式由请求头的 ContentType 指定,有如下几种情况:

  • application/x-www-form-urlencoded:这种情况的数据 @RequestParam、@ModelAttribute 也可以处理,当然 @RequestBody 也能处理。
  • multipart/form-data:@RequestBody 不能处理这种数据。
  • application/json、application/xml:必须使用 @RequestBody 来处理。

自定义 HttpMessageConverter 接收 JSON 格式的数据

也可以使用其他开源类包处理 JSON 数据。下面介绍非常受欢迎的 fastjson 来接收 JSON 数据。

在引入第三放的 fastjson 处理 JSON 数据,因此需要另行配置 HttpMessageConverter:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<mvc:annotation-driven>
<mvc:message-converters register-defaults="false">
<bean class="org.springframework.http.converter.StringHttpMessageConverter"/>
<bean class="org.springframework.http.converter.xml.Jaxb2RootElementHttpMessageConverter"/>
<bean class="org.springframework.http.converter.ByteArrayHttpMessageConverter"/>
<bean class="org.springframework.http.converter.BufferedImageHttpMessageConverter"/>
<!--配置 FastJSON -->
<bean id="fastJSONHttpMessageConverter" class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter">
<property name="supportedMediaTypes">
<list>
<value>text/html;charset=UTF-8</value>
<value>application/json;charset=UTF-8</value>
</list>
</property>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>

@ResponseBody 注解用于将 Controller 方法返回的对象通过适当的消息转换器转化为指定格式后,写入到 Response 对象的 body 数据区。通常当返回的数据不是 html 标签的页面,而是其他格式的数据如 json、xml 时使用该注解。

转换 XML 数据

SpringMVC 默认使用 Jaxb2RootElementHttpMessageConverter 转换 XML 格式的数据。JAXB 可以很方便地生成 XML,也能够很方便地生成 JSON,因此可以很好地在 XML 和 JSON 之间进行转换。

JAXB 常用的注解包括:@XmlRootElement、@XmlElement。