HttpMessageConverter转换类型
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转换类型相关推荐
- JavaScript 技术篇-js自动转换类型,自动转换为字符串,js避免自动转换的坑
自动转换类型 当 JavaScript 尝试操作一个 "错误" 的数据类型时,会自动转换为 "正确" 的数据类型. 而往往这种隐式的转化可能给程序带来很多莫名奇 ...
- 微信小程序-WXML转换类型
微信小程序-WXML转换类型 情景:需要在WXML中把字符串转化成数字类型 解决:引入WXS wxs是小程序的一套脚本语言,结合wxml,可以构建出页面的结构. wxs不依赖于运行时的基础库版本,可以 ...
- Python OpenCV中色彩空间的转换类型
OpenCV中具有的色彩空间转换类型有很多,编写一个简单的Python程序,OpenCV下所支持的色彩空间转换类型 Python程序: # -*- coding: utf-8 -*-import cv ...
- 坐标转换 计算机图形学_计算机图形学的转换类型
坐标转换 计算机图形学 什么是转型? (What is Transformation?) Transformation refers to the mathematical operations or ...
- [Leedcode][JAVA][第50题][Pow(x, n)][快速幂][分治][转换类型]
[问题描述][第50题][Pow(x, n)][中等] 实现 pow(x, n) ,即计算 x 的 n 次幂函数.输入: 2.10000, 3 输出: 9.26100 示例 3:输入: 2.00000 ...
- Python 获取(字典)字符串时间区间并转换类型,判断该时间段属否在时间范围
源码实例 : 获取(字典)字符串时间区间并转换类型 import datetime"ssh": {"username": "johnny", ...
- 容器转换类型,列表,集合,字典推导式
容器转换类型 tuple() 数据类型转换为元组 list() 转换为列表 set() 转换为集合 1.tuple() list1={'a','z','s','w'} set1={100,200,30 ...
- php将abc转换成整形是什么意思,php强制转换类型的方法
php强制转换类型的方法 发布时间:2020-07-02 15:45:14 来源:亿速云 阅读:102 作者:Leah 本篇文章为大家展示了php强制转换类型的方法,代码简明扼要并且容易理解,绝对能使 ...
- C# 8.0和.NET Core 3.0高级编程 分享笔记三:控制流程和转换类型
控制sql教程流程和转java基础教程换类型 本章的内容python基础教程主要包括编写代码.对变量c#教程执行简单vb.net教程的操作.做出决策.重复执行语句块.将变量或表达式值从一种类型转换为另 ...
最新文章
- 知识体系地图模型:你是如何有效地学习?
- Py之textgenrnn:textgenrnn库的简介、安装、使用方法详细攻略
- mysql里b树_MySQL-B树/B+树
- UltraEdit批量删除关键字所在的指定行
- 静态路由心法口诀:路由表少什么网络加什么网络
- Delphi调用外部程序详解
- python 异步api ThreadPoolExecutor 、ProcessPoolExecutor(多线程、多进程)
- HeadFirstJava——2_类与对象
- 《计算机组网试验-DNS服务器安装配置 》杭州电子科技大学
- Blackhat2017:如何利用PostScript语言入侵打印机
- 乐理小课堂——自然/和声/旋律大调的调式音阶
- 宝藏级别的负数取模,让你关于负数取模不在陌生 >o< 进来看看吧
- 微信小程序申请医疗-就医服务类目解决办法
- 山中无甲子,寒尽不知年
- 「Nescafé26」 Freda的传呼机 【最短路径+树上倍增】
- 浅谈JVM(六):方法调用过程
- 基于asp.net的婴幼儿早教管理系统
- 【1093. 大样本统计】
- 微信服务通知消息找回_80%的人都不知道的10个微信冷知识,全都超实用!
- 2022大数据面试总结
热门文章
- ClickHouse系列教程一:Debian/Ubuntu 下ClickHouse的安装和使用
- layui时间怎么设置年月日时分秒_layui-laydate时间日历控件使用方法详解
- Docker运行sonarqube-(代码质量检测平台)
- spring boot读取yml配置集合,反射实战!
- C++_STL标准库——容器
- k8s 使用Nginx Ingress实现灰度发布和蓝绿发布
- 【带你重拾Redis】Redis常见知识点
- 7.Spring Security 退出登录
- mac下java 开发环境搭建
- andpods授权码订单号分享_不要再让你的接口裸奔了,Boot快速尝试OAuth2密码和授权码模式...