一 . 前言
这一篇只关注一个小点 , 学习一下 SpringMVC 是如何进行数据转换.
二. 数据承接
2.1 数据转换常见用法
以 fasterxml 为例 , 它属于外包 , 但是 SpringMVC 对其进行了集成 , 那么该功能是如何进行处理的呢 ?
2.2 数据转换的源码梳理
JSON 的转换流程主要为 HttpMessageConverter 模块 , 先来看一下之前的流程图
可以看到 , 会先通过 HandlerMethodArgumentResolverComposite 对属性进行解析 , 通过 HandlerMethodReturnValueHandlerComposite 对返回进行解析 , 他们都会通过 AbstractMessageConverterMethodArgumentResolver 进行统一的处理.
2.2.1 MessageConverter 的加载和初始化
// 注意 , 该类在 Spring AutoConfigure 中 , 并不是 MVC 专属
private static class MessageConverterInitializer implements Runnable {
@Override
public void run() {
// 此处创建了一个对应的 FormHttpMessageConverter 扩展 ,增加对XML和基于json的部件的支持
new AllEncompassingFormHttpMessageConverter();
}
}
// 其中预加载了多种解析的类
public AllEncompassingFormHttpMessageConverter() {
addPartConverter(new SourceHttpMessageConverter<>());
// JAXB是Java Architecture for XML Binding的缩写,可以将一个Java对象转变成为XML格式,反之亦然
if (jaxb2Present && !jackson2XmlPresent) {
addPartConverter(new Jaxb2RootElementHttpMessageConverter());
}
// 处理JSON和XML格式化的类库
if (jackson2Present) {
addPartConverter(new MappingJackson2HttpMessageConverter());
}
// Gson是谷歌官方推出的支持 `JSON -- Java Object` 相互转换的 Java`序列化/反序列化` 库
else if (gsonPresent) {
addPartConverter(new GsonHttpMessageConverter());
}
// 与 JSON 不同 , jsonb是保存为二进制格式的
//- jsonb通常比json占用更多的磁盘空间(有些情况不是)
//- jsonb比json的写入更耗时间
//- json的操作比jsonb的操作明显更耗时间(在操作一个json类型值时需要每次都去解析)
else if (jsonbPresent) {
addPartConverter(new JsonbHttpMessageConverter());
}
// jackson 并不是值处理 JSON 的 , 这个转换器用于读写XML编码数据的扩展组件
if (jackson2XmlPresent) {
addPartConverter(new MappingJackson2XmlHttpMessageConverter());
}
// 可以读写Smile数据格式
if (jackson2SmilePresent) {
addPartConverter(new MappingJackson2SmileHttpMessageConverter());
}
}
- jaxb2Present = ClassUtils.isPresent("javax.xml.bind.Binder", classLoader);
- jackson2Present = ClassUtils.isPresent("com.fasterxml.jackson.databind.ObjectMapper", classLoader) &&
ClassUtils.isPresent("com.fasterxml.jackson.core.JsonGenerator", classLoader);
- jackson2XmlPresent = ClassUtils.isPresent("com.fasterxml.jackson.dataformat.xml.XmlMapper", classLoader);
- jackson2SmilePresent = ClassUtils.isPresent("com.fasterxml.jackson.dataformat.smile.SmileFactory", classLoader);
- gsonPresent = ClassUtils.isPresent("com.google.gson.Gson", classLoader);
- jsonbPresent = ClassUtils.isPresent("javax.json.bind.Jsonb", classLoader);
2.2.2 转化的入口
MessageConvert 转换的核心入口为 AbstractMessageConverterMethodArgumentResolver , 来看一下处理逻辑 (之前已经看过相关的代码 , 这里只截取一部分 -> juejin.cn/post/696584…)