HttpMessageConverter接口定义

  1. * Strategy interface that specifies a converter that can convert from and to HTTP requests and responses.
  2. *
  3. * @author Arjen Poutsma
  4. * @author Juergen Hoeller
  5. * @since 3.0
  6. */
  7. public interface HttpMessageConverter<T> {
  8. /**
  9. * Indicates whether the given class can be read by this converter.
  10. * @param clazz the class to test for readability
  11. * @param mediaType the media type to read, can be {@code null} if not specified.
  12. * Typically the value of a {@code Content-Type} header.
  13. * @return {@code true} if readable; {@code false} otherwise
  14. */
  15. boolean canRead(Class<?> clazz, MediaType mediaType);
  16. /**
  17. * Indicates whether the given class can be written by this converter.
  18. * @param clazz the class to test for writability
  19. * @param mediaType the media type to write, can be {@code null} if not specified.
  20. * Typically the value of an {@code Accept} header.
  21. * @return {@code true} if writable; {@code false} otherwise
  22. */
  23. boolean canWrite(Class<?> clazz, MediaType mediaType);
  24. /**
  25. * Return the list of {@link MediaType} objects supported by this converter.
  26. * @return the list of supported media types
  27. */
  28. List<MediaType> getSupportedMediaTypes();
  29. /**
  30. * Read an object of the given type form the given input message, and returns it.
  31. * @param clazz the type of object to return. This type must have previously been passed to the
  32. * {@link #canRead canRead} method of this interface, which must have returned {@code true}.
  33. * @param inputMessage the HTTP input message to read from
  34. * @return the converted object
  35. * @throws IOException in case of I/O errors
  36. * @throws HttpMessageNotReadableException in case of conversion errors
  37. */
  38. T read(Class<? extends T> clazz, HttpInputMessage inputMessage)
  39. throws IOException, HttpMessageNotReadableException;
  40. /**
  41. * Write an given object to the given output message.
  42. * @param t the object to write to the output message. The type of this object must have previously been
  43. * passed to the {@link #canWrite canWrite} method of this interface, which must have returned {@code true}.
  44. * @param contentType the content type to use when writing. May be {@code null} to indicate that the
  45. * default content type of the converter must be used. If not {@code null}, this media type must have
  46. * previously been passed to the {@link #canWrite canWrite} method of this interface, which must have
  47. * returned {@code true}.
  48. * @param outputMessage the message to write to
  49. * @throws IOException in case of I/O errors
  50. * @throws HttpMessageNotWritableException in case of conversion errors
  51. */
  52. void write(T t, MediaType contentType, HttpOutputMessage outputMessage)
  53. throws IOException, HttpMessageNotWritableException;
  54. }

该接口定义了四个方法,分别是读取数据时的 canRead(), read() 和 写入数据时的canWrite(), write()方法。

常用的HttpMessageConverter

在使用 <mvc:annotation-driven />标签配置时,默认配置了RequestMappingHandlerAdapter(注意是RequestMappingHandlerAdapter不是AnnotationMethodHandlerAdapter),并为他配置了一下默认的HttpMessageConverter:

  1. ByteArrayHttpMessageConverter converts byte arrays.
  2. StringHttpMessageConverter converts strings.
  3. ResourceHttpMessageConverter converts to/from org.springframework.core.io.Resource for all media types.
  4. SourceHttpMessageConverter converts to/from a javax.xml.transform.Source.
  5. FormHttpMessageConverter converts form data to/from a MultiValueMap<String, String>.
  6. Jaxb2RootElementHttpMessageConverter converts Java objects to/from XML added if JAXB2 is present on the classpath.
  7. MappingJacksonHttpMessageConverter converts to/from JSON added if Jackson is present on the classpath.
  8. AtomFeedHttpMessageConverter converts Atom feeds added if Rome is present on the classpath.
  9. RssChannelHttpMessageConverter converts RSS feeds added if Rome is present on the classpath.
  10. ByteArrayHttpMessageConverter: 负责读取二进制格式的数据和写出二进制格式的数据;
  11. StringHttpMessageConverter:负责读取字符串格式的数据和写出二进制格式的数据;
  12. ResourceHttpMessageConverter:负责读取资源文件和写出资源文件数据;
  13. FormHttpMessageConverter:负责读取form提交的数据(能读取的数据格式为 application/x-www-form-urlencoded,不能读取multipart/form-data格式数据);负责写入application/x-www-from-urlencodedmultipart/form-data格式的数据;
  14. MappingJacksonHttpMessageConverter: 负责读取和写入json格式的数据;
  15. SouceHttpMessageConverter:负责读取和写入 xml javax.xml.transform.Source定义的数据;
  16. Jaxb2RootElementHttpMessageConverter:负责读取和写入xml 标签格式的数据;
  17. AtomFeedHttpMessageConverter:负责读取和写入Atom格式的数据;
  18. RssChannelHttpMessageConverter:负责读取和写入RSS格式的数据;

当使用 @RequestBody和 @ResponseBody注解时,RequestMappingHandlerAdapter就使用它们来进行读取或者写入相应格式的数据。

HttpMessageConverter匹配过程:

@RequestBody注解时: 根据Request对象header部分的Content-Type类型,逐一匹配合适的HttpMessageConverter来读取数据。

spring 3.1源代码如下:

  1. private Object readWithMessageConverters(MethodParameter methodParam, HttpInputMessage inputMessage, Class paramType) throws Exception {
  2. MediaType contentType = inputMessage.getHeaders().getContentType();
  3. if (contentType == null) {
  4. StringBuilder builder = new StringBuilder(ClassUtils.getShortName(methodParam.getParameterType()));
  5. String paramName = methodParam.getParameterName();
  6. if (paramName != null) {
  7. builder.append(' ');
  8. builder.append(paramName);
  9. }
  10. throw new HttpMediaTypeNotSupportedException("Cannot extract parameter (" + builder.toString() + "): no Content-Type found");
  11. }
  12. List<MediaType> allSupportedMediaTypes = new ArrayList<MediaType>();
  13. if (this.messageConverters != null) {
  14. for (HttpMessageConverter<?> messageConverter : this.messageConverters) {
  15. allSupportedMediaTypes.addAll(messageConverter.getSupportedMediaTypes());
  16. if (messageConverter.canRead(paramType, contentType)) {
  17. if (logger.isDebugEnabled()) {
  18. logger.debug("Reading [" + paramType.getName() + "] as \"" + contentType + "\" using [" + messageConverter + "]");
  19. }
  20. return messageConverter.read(paramType, inputMessage);
  21. }
  22. }
  23. }
  24. throw new HttpMediaTypeNotSupportedException(contentType, allSupportedMediaTypes);
  25. }

@ResponseBody注解时:根据Request对象header部分的Accept属性(逗号分隔),逐一按accept中的类型,去遍历找到能处理的HttpMessageConverter。

spring 3.1 源代码如下:

  1. private void writeWithMessageConverters(Object returnValue, HttpInputMessage inputMessage, HttpOutputMessage outputMessage)
  2. throws IOException, HttpMediaTypeNotAcceptableException {
  3. List<MediaType> acceptedMediaTypes = inputMessage.getHeaders().getAccept();
  4. if (acceptedMediaTypes.isEmpty()) {
  5. acceptedMediaTypes = Collections.singletonList(MediaType.ALL);
  6. }
  7. MediaType.sortByQualityValue(acceptedMediaTypes);
  8. Class<?> returnValueType = returnValue.getClass();
  9. List<MediaType> allSupportedMediaTypes = new ArrayList<MediaType>();
  10. if (getMessageConverters() != null) {
  11. for (MediaType acceptedMediaType : acceptedMediaTypes) {
  12. for (HttpMessageConverter messageConverter : getMessageConverters()) {
  13. if (messageConverter.canWrite(returnValueType, acceptedMediaType)) {
  14. messageConverter.write(returnValue, acceptedMediaType, outputMessage);
  15. if (logger.isDebugEnabled()) {
  16. MediaType contentType = outputMessage.getHeaders().getContentType();
  17. if (contentType == null) {
  18. contentType = acceptedMediaType;
  19. }
  20. logger.debug("Written [" + returnValue + "] as \"" + contentType +
  21. "\" using [" + messageConverter + "]");
  22. }
  23. this.responseArgumentUsed = true;
  24. return;
  25. }
  26. }
  27. }
  28. for (HttpMessageConverter messageConverter : messageConverters) {
  29. allSupportedMediaTypes.addAll(messageConverter.getSupportedMediaTypes());
  30. }
  31. }
  32. throw new HttpMediaTypeNotAcceptableException(allSupportedMediaTypes);
  33. }

HttpMessageConverter用法的更多相关文章

  1. @RequestMapping 用法详解之地址映射

    @RequestMapping 用法详解之地址映射 引言: 前段时间项目中用到了RESTful模式来开发程序,但是当用POST.PUT模式提交数据时,发现服务器端接受不到提交的数据(服务器端参数绑定没 ...

  2. RestTemplate 微信接口 text/plain HttpMessageConverter

    一.背景介绍 使用 Spring Boot 写项目,需要用到微信接口获取用户信息. 在 Jessey 和 Spring RestTemplate 两个 Rest 客户端中,想到尽量不引入更多的东西,然 ...

  3. Spring常用注解用法总结

    转自http://www.cnblogs.com/leskang/p/5445698.html 1.@Controller 在SpringMVC 中,控制器Controller 负责处理由Dispat ...

  4. Spring MVC的WebMvcConfigurerAdapter用法收集(零配置,无XML配置)

    原理先不了解,只记录常用方法 用法: @EnableWebMvc 开启MVC配置,相当于 <?xml version="1.0" encoding="UTF-8&q ...

  5. [转帖]@RequestMapping 用法详解之地址映射(转)

    @RequestMapping 用法详解之地址映射(转) https://www.cnblogs.com/qq78292959/p/3760560.html 从csdn 发现的文章 然后csdn指向c ...

  6. EditText 基本用法

    title: EditText 基本用法 tags: EditText,编辑框,输入框 --- EditText介绍: EditText 在开发中也是经常用到的控件,也是一个比较必要的组件,可以说它是 ...

  7. jquery插件的用法之cookie 插件

    一.使用cookie 插件 插件官方网站下载地址:http://plugins.jquery.com/cookie/ cookie 插件的用法比较简单,直接粘贴下面代码示例: //生成一个cookie ...

  8. Java中的Socket的用法

                                   Java中的Socket的用法 Java中的Socket分为普通的Socket和NioSocket. 普通Socket的用法 Java中的 ...

  9. [转载]C#中MessageBox.Show用法以及VB.NET中MsgBox用法

    一.C#中MessageBox.Show用法 MessageBox.Show (String) 显示具有指定文本的消息框. 由 .NET Compact Framework 支持. MessageBo ...

随机推荐

  1. Library cache lock/pin详解

    Library cache lock/pin 一.概述 ---本文是网络资料加metalink 等整理得来一个实例中的library cache包括了不同类型对象的描述,如:游标,索引,表,视图,过程 ...

  2. 在linux设置环境变量

    1.直接用export命令:#export PATH=$PATH:/opt/au1200_rm/build_tools/bin查看是否已经设好,可用命令export查看: [root@localhos ...

  3. 无人机DLG生产作业流程

    参考文章 无人机(AVIAN)低空摄影测量作业流程 无人机低空遥感测绘作业流程及主要质量控制点 微型无人机低空摄影测量系 无人机航空摄影测量系统引进与发展 基于复杂地形的无人机航摄系统1∶500 DL ...

  4. XtraGrid的若干种用法 z

    支持多种类型的数据集合作为数据源 XtraGrid与传统的DataGridView一样,支持多种类型作为其数据源.下面例子是将DataTable, List<T>和数组分别绑定到XtraG ...

  5. Linux基本命令(5)管理使用者和设立权限的命令

    管理使用者和设立权限的命令 命令 说明 命令 说明 chmod 用来改变权限 useradd 用来增加用户 su 用来修改用户     5.1 chmod命令 chmod命令用来改变许可权限.读取.写 ...

  6. web自动化框架之三获取数据库值与界面值比较~~

    数据库用到的是mysql,框架涉及数据库,主要包含两个方面,一个是每个案例执行完毕后,插入案例相关信息与数据:一个是web界面数据核对的时候,需要从sql中获取某行某列值与界面某个值做比较. 描述:w ...

  7. 国内外开源与 SaaS ,团队协作平台、项目管理工具整理

    整理一些开源与 SaaS ,团队协作平台.项目管理工具.还有哪些比较好的工具,可以推荐下? 名称 地址 备注 asana https://asana.com/ 国外 basecamp https:// ...

  8. TRANSLATE

    语法格式: TRANSLATE(expr, from_string, to_string) 示例如下: SELECT TRANSLATE('ab 你好 bcdefg', 'abcdefg', '123 ...

  9. linux中的livecd、liveDVD和其他安装方式简介

    下载了几种不同格式的centos版本的iso文件,从而对比下各种iso文件的差别,下载的内容如下: 下载之后,分别在虚拟机中进行安装,从而查看有何区别: 1. 使用LiveCD进行安装 在选择安装介质 ...

  10. WordPress的SEO技术

    原文:http://blog.wpjam.com/article/wordpress-seo/ 文章目录[隐藏] 内容为王 页面优化 标题 链接(URL) Meta 标签 语义化 H1 H2 H3 等 ...