父文章

序列化,反序列化 实现的本质

不要反序列化成接口!

   原因是 序列化,反序列化本质上是存储字段,  接口是方法动作,两者语义上对不齐.

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

rpcbond的111端口可以修改吗_序列化

更复杂的场景,例如没有 "无参构造函数"case 见 Inheritance with Jackson . 打印的内容里有子类信息.. 

方案3: 自定义反序列化StdDeserializer

Jackson使用详解关键配置类 BasicPolymorphicTypeValidator

ObjectMapper mapper = new ObjectMapper();
mapper.activateDefaultTyping(ptv, ObjectMapper.DefaultTyping.NON_FINAL);

rpcbond的111端口可以修改吗_开发语言_02

rpcbond的111端口可以修改吗_rpcbond的111端口可以修改吗_03

综述

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);
    }