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. C语言:延时1秒

    使用sleep()函数将程序阻塞,头文件在windows系统和linux系统下是不一样的windowsSleep()//第一个字母大写#include <windows.h>函数原型voi ...

  2. python删除文件中某一行

    将文本中的 tasting123删除 with open("fileread.txt","r",encoding="utf-8") as f ...

  3. shell脚本(3)-格式化输出

    一个程序需要有0个或以上的输入,一个或更多输出 一.echo语法 1.功能:将内容输出到默认显示设备. echo命令功能在显示器上显示一段文字,一般提到提示的作用 2.语法:echo[-ne][字符串 ...

  4. 如何快速更新长缓存的 HTTP 资源

    前言 HTTP 缓存时间一直让开发者头疼.时间太短,性能不够好:时间太长,更新不及时.当遇到严重问题需紧急修复时,尽管后端文件可快速替换,但前端文件仍从本地缓存加载,导致更新长时间无法生效. 对于这个 ...

  5. PAT甲级:1066 Root of AVL Tree (25分)

    PAT甲级:1066 Root of AVL Tree (25分) 题干 An AVL tree is a self-balancing binary search tree. In an AVL t ...

  6. Cannot read property 'data' of undefined —— 小程序开发

    由于疫情原因目前处于半下岗状态,在家的时候就研究起了小程序开发.由于是新手,所以总会遇到各种问题,顺便记录一下. wx.showModal({ title: '提示', content: '这是一个模 ...

  7. springboot+mybatis+mysql 利用mybatis自动生成sql语句

    工具和环境 idea,mysql,JDK1.8 效果图如下 结构图如下 java resources sql文件 /* Navicat MySQL Data Transfer Source Serve ...

  8. 共享内存 & Actor并发模型哪个更快?

    HI,前几天被.NET圈纪检委@懒得勤快问到共享内存和Actor并发模型哪个速度更快. 前文传送门: 说实在,我内心10w头羊驼跑过...... 先说结论 首先两者对于并发的风格模型不一样. 共享内存 ...

  9. 【进阶之路】Java的类型擦除式泛型

    Java选择的泛型类型叫做类型擦除式泛型.什么是类型擦除式泛型呢?就是Java语言中的泛型只存在于程序源码之中,在编译后的字节码文件里,则全部泛型都会被替换为原来的原始类型(Raw Type),并且会 ...

  10. http笔记随笔

    1.HTTP (HyperText Transfer Protocol)超文本传输协议(80端口) 1.规定浏览器和服务器之间相互通信的规则 2.万维网交换信息的基础 3.允许将HTML文档从Web服 ...