SpringMVC 中 HttpMessageConverter 简介和 Http 请求 415 Unsupported Media Type 的问题

一、概述

  本文介绍且记录如何解决在 SpringMVC 中遇到 415 Unsupported Media Type 的问题,并且顺便介绍 Spring MVC 的 HTTP 请求信息转换器 HttpMessageConverter。

二、问题描述

  在 SprinvMVC 的 Web 程序中,我在页面发送 Ajax 的 POST 请求,然后在服务器端利用@requestBody 接收请求 body 中的参数,当时运行过程中,我想服务器发送 Ajax 请求,浏览器一直反馈 415 Unsupported Media Type 或者 400 的状态码,以为是 Ajax 写的有问题。便查找了半天资料,才发现 spring-mvc.config 文件的配置中少了东西,当然也有可能是你真的在 Ajax 中缺少了对 Content-Type 参数的设置。分析后应该是我 springMVC-config.xml 文件配置有问题。

(注):400:(错误请求) 服务器不理解请求的语法。 415:(不支持的媒体类型) 请求的格式不受请求页面的支持。

三、解决方法

  在 springMVC-config.xml 文件中,增加了一个 StringHttpMessageConverter 请求信息转换器,配置片段如下:

<!--- StringHttpMessageConverter bean -->
< bean id = "stringHttpMessageConverter" class = "org.springframework.http.converter.StringHttpMessageConverter"/>

<!-- 启动Spring MVC的注解功能,完成请求和注解POJO的映射 -->
< bean class ="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" >
       < property name= "messageConverters" >
             < list>
                 < ref bean= "mappingJacksonHttpMessageConverter" />
                 <!-- 新增的StringMessageConverter bean-->
                 < ref bean= "stringHttpMessageConverter" />
                 < ref bean= "jsonHttpMessageConverter" />
                 < ref bean= "formHttpMessageConverter" />
             </ list>
        </ property>
</ bean>

四、HttpMessageConverter 请求信息转换器简介

HttpMessageConverter 接口指定了一个可以把 Http request 信息和 Http response 信息进行格式转换的转换器。通常实现 HttpMessageConverter 接口的转换器有以下几种:

  • ByteArrayHttpMessageConverter: 负责读取二进制格式的数据和写出二进制格式的数据;
  • StringHttpMessageConverter:负责读取字符串格式的数据和写出二进制格式的数据;
  • ResourceHttpMessageConverter:负责读取资源文件和写出资源文件数据;
  • FormHttpMessageConverter:负责读取 form 提交的数据(能读取的数据格式为 application/x-www-form-urlencoded,不能读取 multipart/form-data 格式数据);负责写入 application/x-www-from-urlencoded 和 multipart/form-data 格式的数据;
  • MappingJacksonHttpMessageConverter: 负责读取和写入 json 格式的数据;
  • SourceHttpMessageConverter:负责读取和写入 xml 中 javax.xml.transform.Source 定义的数据;
  • Jaxb2RootElementHttpMessageConverter: 负责读取和写入 xml 标签格式的数据;
  • AtomFeedHttpMessageConverter: 负责读取和写入 Atom 格式的数据;
  • RssChannelHttpMessageConverter: 负责读取和写入 RSS 格式的数据;

(注)更多关于 HttpMessageConverter 的信息请看:http://docs.spring.io/spring/docs/3.0.x/api/org/springframework/http/converter/HttpMessageConverter.html

五、HttpMessageConverter 请求信息转换器执行流程

当用户发送请求后,@Requestbody 注解会读取请求 body 中的数据,默认的请求转换器 HttpMessageConverter 通过获取请求头 Header 中的 Content-Type 来确认请求头的数据格式,从而来为请求数据适配合适的转换器。例如 contentType:applicatin/json,那么转换器会适配 MappingJacksonHttpMessageConverter。响应时候的时候同理,@Responsebody 注解会启用 HttpMessageConverter,通过检测 Header 中 Accept 属性来适配的响应的转换器。

总结

  当在使用 SpringMVC 做服务器数据接收时,尤其是在做 Ajax 请求的时候,尤其要注意 contentType 属性,和 accepte 属性的设置,在 springmvc-config.xml 中配置好相应的转换器。当我们在用 SpringMVC 做 Ajax 请求的时候,有的做法用 response.getWriter().print()的方法,还有更好的方法就是添加@Responsebody 注解,直接返回 Map 类型的数据,转换器自动转换为 JSON 数据类型。


最后修改于 2013-12-05