2019独角兽企业重金招聘Python工程师标准>>>

HttpMessageConverter接口定义

 * Strategy interface that specifies a converter that can convert from and to HTTP requests and responses. * * @author Arjen Poutsma * @author Juergen Hoeller * @since 3.0*/
public interface HttpMessageConverter<T> {  /** * Indicates whether the given class can be read by this converter. * @param clazz the class to test for readability * @param mediaType the media type to read, can be {@code null} if not specified. * Typically the value of a {@code Content-Type} header. * @return {@code true} if readable; {@code false} otherwise */  boolean canRead(Class<?> clazz, MediaType mediaType);  /** * Indicates whether the given class can be written by this converter. * @param clazz the class to test for writability * @param mediaType the media type to write, can be {@code null} if not specified. * Typically the value of an {@code Accept} header. * @return {@code true} if writable; {@code false} otherwise */  boolean canWrite(Class<?> clazz, MediaType mediaType);  /** * Return the list of {@link MediaType} objects supported by this converter. * @return the list of supported media types */  List<MediaType> getSupportedMediaTypes();  /** * Read an object of the given type form the given input message, and returns it. * @param clazz the type of object to return. This type must have previously been passed to the * {@link #canRead canRead} method of this interface, which must have returned {@code true}. * @param inputMessage the HTTP input message to read from * @return the converted object * @throws IOException in case of I/O errors * @throws HttpMessageNotReadableException in case of conversion errors */  T read(Class<? extends T> clazz, HttpInputMessage inputMessage)  throws IOException, HttpMessageNotReadableException;  /** * Write an given object to the given output message. * @param t the object to write to the output message. The type of this object must have previously been * passed to the {@link #canWrite canWrite} method of this interface, which must have returned {@code true}. * @param contentType the content type to use when writing. May be {@code null} to indicate that the * default content type of the converter must be used. If not {@code null}, this media type must have * previously been passed to the {@link #canWrite canWrite} method of this interface, which must have * returned {@code true}. * @param outputMessage the message to write to * @throws IOException in case of I/O errors * @throws HttpMessageNotWritableException in case of conversion errors */  void write(T t, MediaType contentType, HttpOutputMessage outputMessage)  throws IOException, HttpMessageNotWritableException;  }  

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

常用的HttpMessageConverter

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

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

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

HttpMessageConverter匹配过程:

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

spring 3.1源代码如下:

private Object readWithMessageConverters(MethodParameter methodParam, HttpInputMessage inputMessage, Class paramType) throws Exception {  MediaType contentType = inputMessage.getHeaders().getContentType();  if (contentType == null) {  StringBuilder builder = new StringBuilder(ClassUtils.getShortName(methodParam.getParameterType()));  String paramName = methodParam.getParameterName();  if (paramName != null) {  builder.append(' ');  builder.append(paramName);  }  throw new HttpMediaTypeNotSupportedException("Cannot extract parameter (" + builder.toString() + "): no Content-Type found");  }  List<MediaType> allSupportedMediaTypes = new ArrayList<MediaType>();  if (this.messageConverters != null) {  for (HttpMessageConverter<?> messageConverter : this.messageConverters) {  allSupportedMediaTypes.addAll(messageConverter.getSupportedMediaTypes());  if (messageConverter.canRead(paramType, contentType)) {  if (logger.isDebugEnabled()) {  logger.debug("Reading [" + paramType.getName() + "] as \"" + contentType  + "\" using [" + messageConverter + "]");  }  return messageConverter.read(paramType, inputMessage);  }  }  }  throw new HttpMediaTypeNotSupportedException(contentType, allSupportedMediaTypes);
}

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

spring 3.1 源代码如下:

private void writeWithMessageConverters(Object returnValue,  HttpInputMessage inputMessage, HttpOutputMessage outputMessage)  throws IOException, HttpMediaTypeNotAcceptableException {  List<MediaType> acceptedMediaTypes = inputMessage.getHeaders().getAccept();  if (acceptedMediaTypes.isEmpty()) {  acceptedMediaTypes = Collections.singletonList(MediaType.ALL);  }  MediaType.sortByQualityValue(acceptedMediaTypes);  Class<?> returnValueType = returnValue.getClass();  List<MediaType> allSupportedMediaTypes = new ArrayList<MediaType>();  if (getMessageConverters() != null) {  for (MediaType acceptedMediaType : acceptedMediaTypes) {  for (HttpMessageConverter messageConverter : getMessageConverters()) {  if (messageConverter.canWrite(returnValueType, acceptedMediaType)) {  messageConverter.write(returnValue, acceptedMediaType, outputMessage);  if (logger.isDebugEnabled()) {  MediaType contentType = outputMessage.getHeaders().getContentType();  if (contentType == null) {  contentType = acceptedMediaType;  }  logger.debug("Written [" + returnValue + "] as \"" + contentType +  "\" using [" + messageConverter + "]");  }  this.responseArgumentUsed = true;  return;  }  }  }  for (HttpMessageConverter messageConverter : messageConverters) {  allSupportedMediaTypes.addAll(messageConverter.getSupportedMediaTypes());  }  }  throw new HttpMediaTypeNotAcceptableException(allSupportedMediaTypes);
}

转载于:https://my.oschina.net/chenchenmei/blog/812708

HttpMessageConverter转换类型相关推荐

  1. JavaScript 技术篇-js自动转换类型,自动转换为字符串,js避免自动转换的坑

    自动转换类型 当 JavaScript 尝试操作一个 "错误" 的数据类型时,会自动转换为 "正确" 的数据类型. 而往往这种隐式的转化可能给程序带来很多莫名奇 ...

  2. 微信小程序-WXML转换类型

    微信小程序-WXML转换类型 情景:需要在WXML中把字符串转化成数字类型 解决:引入WXS wxs是小程序的一套脚本语言,结合wxml,可以构建出页面的结构. wxs不依赖于运行时的基础库版本,可以 ...

  3. Python OpenCV中色彩空间的转换类型

    OpenCV中具有的色彩空间转换类型有很多,编写一个简单的Python程序,OpenCV下所支持的色彩空间转换类型 Python程序: # -*- coding: utf-8 -*-import cv ...

  4. 坐标转换 计算机图形学_计算机图形学的转换类型

    坐标转换 计算机图形学 什么是转型? (What is Transformation?) Transformation refers to the mathematical operations or ...

  5. [Leedcode][JAVA][第50题][Pow(x, n)][快速幂][分治][转换类型]

    [问题描述][第50题][Pow(x, n)][中等] 实现 pow(x, n) ,即计算 x 的 n 次幂函数.输入: 2.10000, 3 输出: 9.26100 示例 3:输入: 2.00000 ...

  6. Python 获取(字典)字符串时间区间并转换类型,判断该时间段属否在时间范围

    源码实例 : 获取(字典)字符串时间区间并转换类型 import datetime"ssh": {"username": "johnny", ...

  7. 容器转换类型,列表,集合,字典推导式

    容器转换类型 tuple() 数据类型转换为元组 list() 转换为列表 set() 转换为集合 1.tuple() list1={'a','z','s','w'} set1={100,200,30 ...

  8. php将abc转换成整形是什么意思,php强制转换类型的方法

    php强制转换类型的方法 发布时间:2020-07-02 15:45:14 来源:亿速云 阅读:102 作者:Leah 本篇文章为大家展示了php强制转换类型的方法,代码简明扼要并且容易理解,绝对能使 ...

  9. C# 8.0和.NET Core 3.0高级编程 分享笔记三:控制流程和转换类型

    控制sql教程流程和转java基础教程换类型 本章的内容python基础教程主要包括编写代码.对变量c#教程执行简单vb.net教程的操作.做出决策.重复执行语句块.将变量或表达式值从一种类型转换为另 ...

最新文章

  1. 知识体系地图模型:你是如何有效地学习?
  2. Py之textgenrnn:textgenrnn库的简介、安装、使用方法详细攻略
  3. mysql里b树_MySQL-B树/B+树
  4. UltraEdit批量删除关键字所在的指定行
  5. 静态路由心法口诀:路由表少什么网络加什么网络
  6. Delphi调用外部程序详解
  7. python 异步api ThreadPoolExecutor 、ProcessPoolExecutor(多线程、多进程)
  8. HeadFirstJava——2_类与对象
  9. 《计算机组网试验-DNS服务器安装配置 》杭州电子科技大学
  10. Blackhat2017:如何利用PostScript语言入侵打印机
  11. 乐理小课堂——自然/和声/旋律大调的调式音阶
  12. 宝藏级别的负数取模,让你关于负数取模不在陌生 >o< 进来看看吧
  13. 微信小程序申请医疗-就医服务类目解决办法
  14. 山中无甲子,寒尽不知年
  15. 「Nescafé26」 Freda的传呼机 【最短路径+树上倍增】
  16. 浅谈JVM(六):方法调用过程
  17. 基于asp.net的婴幼儿早教管理系统
  18. 【1093. 大样本统计】
  19. 微信服务通知消息找回_80%的人都不知道的10个微信冷知识,全都超实用!
  20. 2022大数据面试总结

热门文章

  1. ClickHouse系列教程一:Debian/Ubuntu 下ClickHouse的安装和使用
  2. layui时间怎么设置年月日时分秒_layui-laydate时间日历控件使用方法详解
  3. Docker运行sonarqube-(代码质量检测平台)
  4. spring boot读取yml配置集合,反射实战!
  5. C++_STL标准库——容器
  6. k8s 使用Nginx Ingress实现灰度发布和蓝绿发布
  7. 【带你重拾Redis】Redis常见知识点
  8. 7.Spring Security 退出登录
  9. mac下java 开发环境搭建
  10. andpods授权码订单号分享_不要再让你的接口裸奔了,Boot快速尝试OAuth2密码和授权码模式...