HttpMessageConverter简介

HTTP 请求和响应的传输是字节流,意味着浏览器和服务器通过字节流进行通信。但是,使用 Spring,controller 类中的方法返回纯 String 类型或其他 Java 内建对象。如何将对象转换成字节流进行传输?

在报文到达SpringMVC和从SpringMVC出去,都存在一个字节流到java对象的转换问题。在SpringMVC中,它是由HttpMessageConverter来处理的。

当请求报文来到java中,它会被封装成为一个ServletInputStream的输入流,供我们读取报文。响应报文则是通过一个ServletOutputStream的输出流,来输出响应报文。

我们可以用下图来加深理解。

 

HttpMessageConverter接口

在Spring中,内置了大量的HttpMessageConverter。通过请求头信息中的MIME类型,选择相应的HttpMessageConverter。

  1. // 数据转换器 -> 将数据转换成 requests 或 response 中的数据
  2. public interface HttpMessageConverter<T> {
  3.  
  4. // 指定的 class 是否支持读取(MediaType 指数据的格式)
  5. boolean canRead(Class<?> clazz, MediaType mediaType);
  6.  
  7. // 传入 class 与 MediaType -> 看 HttpMessageConverter 是否支持写数据到数据流中
  8. boolean canWrite(Class<?> clazz, MediaType mediaType);
  9.  
  10. // 返回 HttpMessageConverter 支持的 MediaType
  11. List<MediaType> getSupportedMediaTypes();
  12.  
  13. // 从 HttpInputMessage 中读取数据流, 并转化成 T 这站类型
  14. T read(Class<? extends T> clazz, HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException;
  15.  
  16. // 将 T 里面的数据信息写入到 HttpOutputMessage 的数据流中
  17. void write(T t, MediaType contentType, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException;
  18. }

HttpMessageConverter接口的定义中出现了成对的canRead(),read()和canWrite(),write()方法。MediaType是对请求的Media Type属性的封装。

read方法中有一个HttpInputMessage,我们查看它的源码如下。

  1. public interface HttpInputMessageextends HttpMessage {
  2. InputStreamgetBody() throws IOException;
  3. }

HttpInputMessage提供的接口就是将body中的数据转为输入流。
write方法中有一个HttpOutputMessage,我们查看它的源码如下。

  1. public interface HttpOutputMessageextends HttpMessage {
  2. OutputStreamgetBody() throws IOException;
  3. }

HttpOutputMessage提供的接口就是将body中的数据转为输出流。
它们拥有相同的父接口HttpMessage。

  1. public interface HttpMessage {
  2. HttpHeadersgetHeaders();
  3. }

HttpMessage提供的方法是读取头部中的信息。

Spring中内置的一部分HttpMessageConverter

  1. 1. FormHttpMessageConverter
  2. 支持 MultiValueMap 类型, 并且 MediaType 类型是 "multipart/form-data", InputStream 里面读取数据, 并通过&符号分割, 最后转换成 MultiValueMap, MultiValueMap转换成 & 符号连接的字符串, 最后转换成字节流, 输出到远端
  3. 2. BufferedImageHttpMessageConverter
  4. 支持 BufferedImgae HttpMessageConverter, 通过 ImageReader HttpBody 里面的数据转换成 BufferedImage, ImageWriter ImageReader 转换成字节流输出到 OutputMessage
  5. 3. StringHttpMessageConverter
  6. 支持数据是 String 类型的, InputMessage 中读取指定格式的 str, 将数据编码成指定的格式输出到 OutputMessage
  7. 4. SourceHttpMessageConverter
  8. 支持 DOMSource, SAXSource, StAXSource, StreamSource, Source 类型的消息转换器, 在读取的时候, HttpBody 里面读取对应的数据流转换成对应对应, 输出时通过 TransformerFactory 转换成指定格式输出
  9. 5. ResourceHttpMessageConverter
  10. 支持数据类型是 Resource 的数据, HttpBody 中读取数据流转换成 InputStreamResource|ByteArrayResource, 或从 Resource 中读取数据流, 输出到远端
  11. 6. ProtobufHttpMessageConverter
  12. 支持数据类型是 com.google.protobuf.Message, 通过 com.google.protobuf.Message.Builder HttpBody 中的数据流转换成指定格式的 Message, 通过 ProtobufFormatter com.google.protobuf.Message 转换成字节流输出到远端
  13. 7. ObjectToStringHttpMessageConverter
  14. 支持 MediaType text/plain 类型, InputMessage 读取数据转换成字符串, 通过 ConversionService 将字符串转换成自定类型的 Object; 或将 Obj 转换成 String, 最后 String 转换成数据流
  15. 8. ByteArrayHttpMessageConverter
  16. 支持格式是 byte 类型, InputMessage 中读取指定长度的字节流, 或将 OutputMessage 转换成字节流
  17. 9. AbstractXmlHttpMessageConverter及其子类
  18. 支持从 xml Object 之间进行数据转换的 HttpMessageConverter
  19. 10. AbstractGenericHttpMessageConverter
  20. 支持从 Json Object 之间进行数据转换的 HttpMessageConverter (PS: 主要通过 JackSon Gson)
  21. 11. GsonHttpMessageConverter
  22. 支持 application/*++json 格式的数据, 并通过 Gson, 将字符串转换成对应的数据
  23. 12. MappingJackson2XmlHttpMessageConverter
  24. 持 application/*++json/*+xml 格式的数据, 并通过 JackSon, 将字符串转换成对应的数据

HttpMessageConverter 在整个 SpringMVC 中起着根据 MediaType 类型将 HttpServletRequest 中的数据转换成 指定对象的转换器, 或将对象转换成指定格式的数据(PS: byte/String/xml/json 等);

自定义HttpMessageConverter

1.通过继承 AbstractHttpMessageConverter自定义HttpMessageConverter

配置自定义HttpMessageConverter

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xmlns:context="http://www.springframework.org/schema/context"
  5. xmlns:mvc="http://www.springframework.org/schema/mvc"
  6. xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">
  7. <!--spring可以自动去扫描base-pack下面的包或者子包下面的java文件,
  8. 如果扫描到有Spring的相关注解的类,则把这些类注册为Spring的bean-->
  9. <context:component-scan base-package="com.wen.controller"/>
  10. <!--设置默认的Servlet来响应静态文件-->
  11. <mvc:default-servlet-handler/>
  12. <!--设置配置方案,会自动注册RequestMappingHandlerMapping与RequestMappingHandlerAdapter两个Bean-->
  13. <mvc:annotation-driven>
  14. <!--设置不使用默认的消息转换器-->
  15. <mvc:message-converters register-defaults="false">
  16. <!--配置Spring的转换器-->
  17. <bean class="org.springframework.http.converter.StringHttpMessageConverter"/>
  18. <bean class="org.springframework.http.converter.xml.XmlAwareFormHttpMessageConverter"/>
  19. <bean class="org.springframework.http.converter.ByteArrayHttpMessageConverter"/>
  20. <bean class="org.springframework.http.converter.BufferedImageHttpMessageConverter"/>
  21. <!--配置fastjson中实现HttpMessageConverter接口的转换器-->
  22. <!--FastJsonHttpMessageConverter是fastjson中实现了HttpMessageConverter接口的类-->
  23. <bean id="fastJsonHttpMessageConverter" class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter">
  24. <!--加入支持的媒体类型:返回contentType-->
  25. <property name="supportedMediaTypes">
  26. <list>
  27. <!--这里顺序一定不能写反,不然IE会出现下载提示-->
  28. <value>text/html;charset=UTF-8</value>
  29. <value>application/json;charset=UTF-8</value>
  30. </list>
  31. </property>
  32. </bean>
  33. </mvc:message-converters>
  34. </mvc:annotation-driven>
  35.  
  36. <!--视图解析器-->
  37. <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
  38. <!--前缀-->
  39. <property name="prefix" value="/WEB-INF/pages/"/>
  40. <!--后缀-->
  41. <property name="suffix" value=".jsp"/>
  42. </bean>
  43. </beans>

11.SpringMVC之HttpMessageConverter的更多相关文章

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

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

  2. 【SpringMVC】HttpMessageConverter报文信息转换器

    HttpMessageConverter HttpMessageConverter,报文信息转换器,将请求报文转换为Java对象,或将Java对象转换为响应报文 HttpMessageConverte ...

  3. 11. SpringMVC拦截器(资源和权限管理)

    1.DispatcherServlet SpringMVC具有统一的入口DispatcherServlet,所有的请求都通过DispatcherServlet.     DispatcherServl ...

  4. SpringMVC之HttpMessageConverter

    http://blog.csdn.net/zmx729618/article/details/53034420 HttpMessageConverter接口: T read(Class<? ex ...

  5. 11.SpringMVC注解式开发-处理器方法的返回值

    处理器方法的返回值 使用@Controller 注解的处理器的处理器方法,其返回值常用的有四种类型 1.ModelAndView 2.String 3.void 4.自定义类型对象 1.返回Model ...

  6. springmvc知识点整理

    1.Springmvc架构 2.Springmvc组件三大组件:处理器映射器,处理器适配器,视图解析器处理器映射器:注解式处理器映射器,对类中标记了@ResquestMapping的方法进行映射,根据 ...

  7. 是否要学SpringMVC

    如题,希望大侠们指出,不能用Spring就觉得他什么都好,本帖子意在实际工作中,对是否将Spring引入项目及如何更好的使用Spring提出启发式意见.目前已有高人表达了自己对Spring的不满,让我 ...

  8. 转:SpringMVC浅谈

    因为项目文案需要,于是乎翻阅spring相关资料.顿觉该篇不错详尽易懂,特转载之. 转载出处: http://blog.csdn.net/gane_cheng/article/details/5278 ...

  9. SpringMVC的相关知识

    前几天学习了SpringMVC 感觉比Servlet好用得多具体如下: 首先SpringMVC的概念: SpringMVC是一个前端控制框架,主要用来负责与页面的交互.SpringMVC是Spring ...

随机推荐

  1. Collection集合工具类

    Ⅷ.Collections 工具类 java.util.Collections Collections 集合工具类,用来对集合进行操作,部分重要方法如下: 1.public static <T& ...

  2. Docker编排利器DockerCompose

    Docker 编排利器 DockerCompose,编排之后可以一次性通过一条命令启动一组服务 例如一条命令启动 SpringBoot 项目,同时启动 SpringBoot 项目依赖的其他中间件(My ...

  3. 【洛谷P5008 逛庭院】tarjan缩点+贪心

    既然没有题解,那么我就来提供给一份. -- 首先我们看到数据范围.妈耶!数据这么大,一开始还想用个DP来做,但是看着就不行,那么根据这个数据范围,我们大致可以猜到这道题的算法是一个贪心,那么我们怎么贪 ...

  4. 在Windows7/8/10 64位操作系统下安装并注册ocx控件

    例如: 先网上下载一个MtbLine.ocx控件放入C:\Windows\SysWOW64\目录下 1.首先确保你的 Windows7 账户是管理员权限 2.下载MtbLine.ocx控件,网上可搜到 ...

  5. 【阿菜用工具】利用 Web3.js 在 ganache 上部署以及调用智能合约

    合约部署 要部署的合约 pragma solidity ^0.4.23; contract test { uint256 value; function setValue(uint256 _value ...

  6. nuxt服务部署到云上全程记录

    首先,在使用脚手架nuxt-app中创建项目时,箭头选用不起作用,这是因为git bash在windows中交互问题,临时的解决办法是换用cmd 登录云服务器后,首先安装nodejs yum inst ...

  7. 关于win7+cenos 7双系统安装

    ---恢复内容开始--- 1,cenos 0 7制作U盘启动 制作工具 http://pan.baidu.com/s/1nv9lpmp 镜像自备 2,安装centos 7 释放磁盘空间,如:20G.用 ...

  8. 大都市meg DFS序

    题目描述 在经济全球化浪潮的影响下,习惯于漫步在清晨的乡间小路的邮递员Blue Mary也开始骑着摩托车传递邮件了.不过,她经常回忆起以前在乡间漫步的情景.昔日,乡下有依次编号为1..n的n个小村庄, ...

  9. 在vmware虚拟机下的Window2003服务器下安装IIS服务详细教程——超级详细(解决关于:800a0bb9的解决办法)

    总的来说,就是9步: 1.控制面板添加或者删除程序2.删除想要删的3.打开IIS配置4.开始共享5.导入源码6.配置权限7.网站属性.文档.应用程序配置8.web服务扩展9.访问网站 在安装好虚拟机的 ...

  10. C语言复习(六)----typedef 的作用

    typedef的作用 重命名变量:typedef unsigned int Uint;//可以使用Uint代替unsigned int 定义新的数据类型 typedef struct Books{ c ...