父文章
序列化,反序列化 实现的本质
不要反序列化成接口!
原因是 序列化,反序列化本质上是存储字段, 接口是方法动作,两者语义上对不齐.
Gson - 规范json格式
利用JsonSerializer,JsonDeserializer 对接口进行序列化和反序列化.
实现 final class InterfaceAdapter<T> implements JsonSerializer<T>, JsonDeserializer<T> {
java - How to serialize a class with an interface? - Stack Overflow
java - Serializing List of Interfaces GSON - Stack Overflow
更难得是 list<接口> , 容易丢失type信息. 因为只有E和实际类. 需要使用到 tyepHi ,又出现死循环. 最终解决方案是RuntimeTypeAdapterFactory . java - Gson serialize a list of polymorphic objects - Stack Overflow 中第一高票,第二个答案.
好奇, 如何解决死循环?
flat拉平
我自己改造的,见可执行代码 阿里云登录 - 欢迎登录阿里云,安全稳定的云计算服务平台
中的FlatReflectiveTypeAdapterFactoryTest
java - GSON flat down map to other fields - Stack Overflow 自定义注解@flat
java - Make a "flat" JSON using Gson() - Stack Overflow
不如 Jackson 的自定义注解java - How to serialize a List content to a flat JSON object with Jackson? - Stack Overflow
自定义序列化. JsonAdapter , JsonSerializer JsonDeserializer
Gson 通过@JsonAdapter 自定义(反)序列化-火焰兔
原理进一步理解
Gson TypeAdapter 和 TypeAdapterFactory
fastjson 格式不规范
方式一 ObjectDeserializer,ObjectSerializer
FastJSON ObjectDeserializer,ObjectSerializer
使用fastjson提供的接口实现自定义的编解码器
@JSONType(deserializer = MyObjectDeserializer.class)
public class Person {
// 省略属性和方法
}
方式二 autoType
fastjson的泛型 接口反序列化能力autoType 和 安全漏洞
jackson 不规范格式
方案一: Per-Class Annotations JsonTypeInfo JsonSubTypes 推荐, 兼容性好. 仅注解,对代码侵入少.
Inheritance in Jackson | Baeldung 的第二部分 2.2. Per-Class Annotations
方案二: Global Default Typing
Inheritance in Jackson | Baeldung 的第一部分 2.1. Global Default Typing
更复杂的场景,例如没有 "无参构造函数"case 见 Inheritance with Jackson . 打印的内容里有子类信息..
方案3: 自定义反序列化StdDeserializer
见
Jackson使用详解关键配置类 BasicPolymorphicTypeValidator
ObjectMapper mapper = new ObjectMapper();
mapper.activateDefaultTyping(ptv, ObjectMapper.DefaultTyping.NON_FINAL);
综述
json是序列化内容对人友好,但io大. Hessian序列化内容不友好且能保存类信息,类似java自带.
Protocal Buffers 需要静态文件,故io最小.
json 默认静态反序列化 泛型参数,动态需要配置
不能动态的化就无法做成框架,框架技术.
没有class能否序列化?
I think this is another topic other than "simple or traditionally deserialize" because "simple or traditionally deserialize" not save "class definition". if u do this u will get "java.lang.ClassNotFoundException" when deserialize from this
here is the answer about "Java deserialize without knowing class, but knowing interface" jdeserialize may can do this: https:///unsynchronized/jdeserialize.
Because of this, it can analyze (serialize) streams without access to the class code that generated them.
能力和性能是相悖的, 谷歌的pb io很小,原因是反序列方有schema 文件.
java将文本反序列化读取_Java反序列化漏洞利用的学习与实践
现主流的序列化框架以及他的优缺点
框架名称 | 性能排序 | 优点 | 缺点 | 是否推荐 |
Protocal Buffers | 1 | 序列化快;开源 | 代码侵入性性强,需要相关的配置文件,无法直接使用Java等面向对象编程语言中的对象 | 否 |
Json/fastJson/JackSon | 2 | 序列化快,小巧,传输数据格式使用范围广,开源夸平台,夸语言 | 对泛型的支持不是很好。需要传入一个有泛型具化类。 可以是单独的TypeReference,或者是RequestClass<ReponseCLass> object。 T result request(Request<T> params); | 极力推荐 |
Hessian | 4 | 夸平台,夸语言,序列化的使用流程与java内置序列化类似,容易上手 | 性能略低 | 推荐 |
Java内置序列化 | 5 | 使用简单 | 由于是该语言的特殊序列化方式,其他语言没有办法进行解析,夸平台不支持,且性能较低 | 不支持 |
Xstream | 3 | 把对象转化成xml最好用的专业工具 | 使用不是很广泛,因为现在大多数的数据传输都通过json居多 | xml数据传输序列化则强烈推荐 |
看代码,看看各个框架在代码中的具体实现
- Hessian 对象的序列化简单实用
public static void main(String[] args) throws IOException {
Person person = new Person();
person.setAge(18);
person.setName("ydw");
person.setId(1L);
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
HessianOutput hessianOutput = new HessianOutput(byteArrayOutputStream);
//序列化
hessianOutput.writeObject(person);
byte[] bytes = byteArrayOutputStream.toByteArray();
//反序列化
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes);
HessianInput hessianInput = new HessianInput(byteArrayInputStream);
Person ydw = (Person) hessianInput.readObject();
System.out.println(ydw);
}