常见序列化的优劣:pb、avro、json、hessian

news2024/11/16 3:44:12

概念

(1)基础概念和用途

序列化和反序列本质上就是对象和字节数组的转换:

序列化时,将Java对象编码为byte数组

反序列化,则是将byte数组转换为Java对象

序列化用途: 1、在网络上传送对象的字节序列

2、把对象的字节序列永久地保存到硬盘上,通常放在一个文件中

(2)java序列化的实现

1、ObjectOutputStream:通过writeObject方法将对象序列化,并将得到的字节序列写到目标输出流

try {
    ObjectOutputStream output =new ObjectOutputStream(new FileOutputStream("oppo.text"));
    output.writeObject(new Regulation<>());
}catch (Exception e){    
}

2、ObjectInputStream:通过readObject方法从输入流中读取字节序列,并反序列化一个对象

try {
    ObjectInputStream input=new ObjectInputStream(new FileInputStream("oppo.txt"));
    Object o = input.readObject()
}catch (Exception e){    
}

3、实现Sericalizable接口,实现Sericalizable接口的时候还要写一个SericalizableUID(火眼质量代码扫描可能会不通过),这个是版本号,JVM会把传进来的字节流中的serialVersionUID与本地实体类中的serialVersionUID进行比较,如果相同则认为是一致的,便可以进行反序列化,否则就会报序列化版本不一致的异常。如果实现接口的时候,没有给定UID,就会使用默认的UID,当使用默认的UID的时候,jvm每次编译的时候会生成一个UID,当后面程序改了一些代码,再次编译的时候会生成不同的UID,会导致反序列化失败!所以在实现Sericalizable接口的时候,我们自己给定一个固定的UID值,这样就能保证编译完再 反序列化的时候的版本一致性。所以能不能成功反序列化,就是看对象中的UID和实体中UID是否一致。

4、实现Externalnalizable接口,在类中实现readExternal(ObjectInput in)和writeExternal(ObjectOutput out)方法(序列化的细节需要由开发人员自己实现,与是否被transient修饰无关),在方法中定义类对象自定义的序列化和反序列化操作。这样通过对象输出流和对象输入流的输入输出方法序列化和反序列化对象时会自动调用类中定义的readExternal(ObjectInput in)和writeExternal(ObjectOutput out)方法。

注:

1)JDK中除了提供 Serializable 序列化接口外,还提供了另一个序列化接口Externalizable,使用该接口之后,之前基于Serializable接口的序列化机制就将失效。这是因为源码中Externalizable 接口继承了 Serializable 接口。并定义了两个方法 writeExternal 和 readExternal 方法,因此Externalizable 的序列化机制优先级要高于 Serializable。

2)使用 Externalizable 进行序列化时,必须要有默认的构造方法,而Serializable可以没有默认的构造方法。

一、PB序列化

PB序列化是指将Protocol Buffer(简称PB)数据结构转换为字节流的过程。PB是Google开发的一种高效、可扩展、平台无关的数据交换格式,常用于RPC协议、数据存储和数据交换等领域。

PB官方git:https://github.com/protocolbuffers/protobuf

(1)PB序列化的优点

  1. 体积小,序列化后的数据结构一般比XML和JSON更小。
  2. 速度快,PB序列化和反序列化的速度通常比XML和JSON更快。
  3. 语言支持广泛,PB提供了多种语言的API和代码生成工具,可以方便地在不同的平台上使用。
  4. 可扩展性强,PB提供了扩展机制,即使原来的数据结构发生变化,也可以通过向PB消息中添加新的字段来实现升级。 PB序列化的具体实现方式包括:
  5. 定义PB消息的.proto文件。
  6. 使用编译器将.proto文件生成对应的代码。
  7. 在代码中使用PB提供的API将对象序列化为字节流,或者将字节流反序列化为对象。 例如,下面是一个简单的.proto文件定义了一个用户信息的PB消息:
syntax = "proto3";
message UserInfo {
string name = 1;
int32 age = 2;
repeated string interests = 3;
}

通过编译器生成的代码可以使用下面的方式创建和序列化一个UserInfo对象:

UserInfo user = UserInfo.newBuilder().setName("Alice").setAge(30)
.addInterests("Programming").addInterests("Reading").build();
byte[] bytes = user.toByteArray();

反序列化的方式类似:

byte[] bytes = ... // 从文件或网络读取字节流
UserInfo user = UserInfo.parseFrom(bytes);

总的来说,PB序列化是一种高效而强大的数据交换方式,适用于需要高性能、高可扩展性,并且对数据体积有要求的场景。

(2)为什么需要@Tag注解

@Tag 是 Protocol Buffers 中的一个注解,用于指定一个字段的标签号(tag),该标签号必须是一个正整数。在序列化和反序列化中,每个字段都需要标签号来标记该字段的类型和位置,只有使用 @Tag 才能保证序列化和反序列化时字段的匹配性和正确性。如果没有使用 @Tag,则默认使用该字段在代码中的位置作为 tag,在代码修改后可能会导致 tag 发生改变,从而导致序列化和反序列化出错。因此,使用 @Tag 是为了保证数据的稳定性和一致性。

遗留:

如何实现节省空间?

各类json的选型?

使用场景?dubbo默认hessian,被替换的原因?

JDK11版本无法反序列化问题?调活动RPC问题?

二、avro序列化

Apache Avro是一个数据序列化系统

(1)Avro提供

  • 丰富的数据结构
  • 一个紧凑的,快速的,二进制的数据格式
  • 一个容器文件,来存储持久化数据
  • 远程过程调用(RPC)
  • 简单的动态语言集成
  • 代码生成不需要读写数据文件,也不要使用或实现RPC协议。代码生成是作为一个可选的优化,只对静态类型的语言值得实现。
  • .avro本质只是一种数据格式

(2)scheme

Avro依赖于模式(Schema)。通过模式定义各种数据结构,只有确定了模式才能对数据进行解释,所以在数据的序列化和反序列化之前,必须先确定模式的结构。

Avro作为RPC框架来使用。客户端希望同服务器端交互时,就需要交换双方通信的协议,它类似于模式,需要双方来定义,在Avro中被称为消息(Message)。通信双方都必须保持这种协议,以便于解析从对方发送过来的数据,这也就是握手阶段。

(3)特点

  • 跨语言
  • 可压缩可切割
  • 数据结构丰富(null、boolean、int、long、float、double、bytes、string、Records、Enums、Arrays、Maps、Unions、Fixed)
  • json定义scheme
  • 自描述语言(scheme是附加在data中同时传输的)

三、Json序列化

(1)JSON的身份证

全名:JavaScript Object Notation

户籍:Json是一种轻量级数据交换格式,它采用的是完全独立于编程语言之外的文本格式,同时它也使用了类似c家族的习惯,这些特性使得json成为最理想的数据交换语言。

特点:

1)JSON文本格式的本质就是具有特定格式的字符串

2)JSON比XML有效性更高

(2)JSON的数据格式

JSON对象和JSON数组

示例:

String json1 = "{"id":1,"name":"Tom"}";

String json2 = "[12,"abc",{"id":1,"name":"Tom"}]";

Json对象:

结构:{key1:value1,key2:value2}

格式描述:在键值对与键值对之间用“,”隔开,在键与值之间用:隔开

key的数据类型:字符串

value的数据类型:字符串,数值,JSON对象,JSON数组

Json数组:

结构:[value1,value2,value3]

value的数据类型:字符串,数值,JSON对象,JSON数组

注:JSON的对象和数组可以作为Json对象数组的value数据类型

(3)JSON的解析方向

Json对象对应的是Java中的对象

Json数组对应的是Java中的List集合

(4)各种json工具包的比较

JSON不管是在Web开发还是服务器开发中是相当常见的数据传输格式,一般情况我们对于JSON解析构造的性能并不需要过于关心,除非是在性能要求比较高的系统。

四个JSON类库分别为:Gson,FastJson,Jackson,Json-lib。

简单介绍下四个类库的身份背景。

1)Gson(项目地址:https://github.com/google/gson)。

Gson是目前功能最全的Json解析神器,Gson当初是为因应Google公司内部需求而由Google自行研发而来,但自从在2008年五月公开发布第一版后已被许多公司或用户应用。Gson的应用主要为toJson与fromJson两个转换函数,无依赖,不需要例外额外的jar,能够直接跑在JDK上。而在使用这种对象转换之前需先创建好对象的类型以及其成员才能成功的将JSON字符串成功转换成相对应的对象。类里面只要有get和set方法,Gson完全可以将复杂类型的json到bean或bean到json的转换,是JSON解析的神器。

Gson gson = new Gson();
Object object = gson.fromJson(json, Object.class);//json对象->java对象
List<Object> list = gson.fromJson(json, new TypeToken<List<Object>>() {
}.getType());//json对象->java对象list
private Type type = new TypeToken<List<Object>>(){}.getType();//泛型只在编译时有效,运行时泛型擦除
String json = gson.toJson(object);//java对象->json对象

注:gson可能会导致cpu飙高的情况

2)FastJson(项目地址:https://github.com/alibaba/fastjson)。Fastjson是一个Java语言编写的高性能的JSON处理器,由阿里巴巴公司开发。无依赖,不需要例外额外的jar,能够直接跑在JDK上。FastJson在复杂类型的Bean转换Json上会出现一些问题,可能会出现引用的类型,导致Json转换出错,需要制定引用。FastJson采用独创的算法,将解析的速度提升到极致,超过所有json库。

源码阅读博客:Fastjson源码阅读(一):前言_fastjson源码解析-CSDN博客

使用:利用@JSONField注解

String json = JSON.toJSONString(Object object);//java对象->json对象
Object object = JSON.parseObject(json);//json对象->java对象

注意事项:当对象的某个成员变量为null时,序列化时不会创建相关字段;要用相关的封装类来修改基础数据类型变量

3)Jackson(项目地址:https://github.com/FasterXML/jackson)。相比json-lib框架,Jackson所依赖的jar包较少,简单易用并且性能也要相对高些。而且Jackson社区相对比较活跃,更新速度也比较快。Jackson对于复杂类型的json转换bean会出现问题,一些集合Map,List的转换出现问题。Jackson对于复杂类型的bean转换Json,转换的json格式不是标准的Json格式。

4)Json-lib(项目地址:Maven - Json-lib::Welcome)。json-lib最开始的也是应用最广泛的json解析工具,json-lib 不好的地方确实是依赖于很多第三方包,包括commons-beanutils.jar,commons-collections-3.2.jar,commons-lang-2.6.jar,commons-logging-1.1.1.jar,ezmorph-1.0.6.jar,对于复杂类型的转换,json-lib对于json转换成bean还有缺陷,比如一个类里面会出现另一个类的list或者map集合,json-lib从json到bean的转换就会出现问题。json-lib在功能和性能上面都不能满足现在互联网化的需求。

5)选择一个合适的JSON库要从多个方面进行考虑:字符串解析成JSON性能、字符串解析成JavaBean性能、JavaBean构造JSON性能、集合构造JSON性能、易用性

使用选择原则:

  • 字符串解析成JavaBean:当数据量较少时首选FastJson,数据量较大使用Jackson。但是Jackson无法堆一个对象集合进行解析,只能转成一个Map集合,这点Gson和FastJson处理的比较好。
  • 字符串解析成JSON:当数据量较少时首选FastJson,数据量较大使用Jackson。
  • JavaBean构造JSON:当数据量较少时选择Gson,数据量较大可使用Jackson。
  • 集合构造JSON:首先Jackson,其次Fastjson。
  • 从易用性角度分析,FastJson的API设计的最简单,最方便使用,直接使用JSON的两个静态方法即可完成四种操作;而Gson和Jackson都需要new一个对象,虽然这个对象可以复用,但是在实际使用过程中还需要用一个全局变量来保存改变量,同时API设计的也不是很好理解,对于FastJson来说复杂的API是因为他支持流式解析,适合对JSON进行大量且复杂的操作,但是实际应用中对于JSON的操作都是简单的解析成JavaBean,然后JavaBean序列化成JSON字符串即可,复杂的操作很少。

(5)总结

四、hessian序列化

官方地址:Hessian 2.0 Serialization Protocol

(1)特点

参考官方文档的描述:

  • 它必须自我描述序列化类型,即不需要外部模式或接口定义
  • 它必须是独立于语言的,包括支持脚本语言
  • 它必须是可以通过单一方式进行读写
  • 它必须尽可能紧凑
  • 它必须简单,这样才能有效地测试和实现
  • 必须尽可能地快、高效
  • 它必须支持Unicode字符串
  • 它必须支持8位二进制数据,而不需要转义或使用附件
  • 它必须支持加密、压缩、签名和事务上下文信封

(2)hessian协议与jdk区别

  • 区别一:java序列化无法跨语言
  • 区别二:新旧对象的版本Java通过一个serialVersionUID来关联,需要开发者关注序列化的语义
  • 区别三:java序列化不支持加密
  • 区别四:Java序列化的内容比hessian大

(3)hessian总结

  • 序列化对象要实现 Serializable 接口,否则序列化时会报“must implement java.io.Serializable”异常
  • 若序列化对象经hessian序列化后,序列化对象中不加serialVersionUID时,再改变(增加对象属性、删除对象属性)都不会产生反序列化异常,即hessian序列化对象不再需要serialVersionUID。===
  • hessian会把复杂对象所有属性存储在一个 Map 中进行序列化。所以在父类、子类存在同名成员变量的情况下, Hessian 序列化时,先序列化子类,然后序列化父类,因此反序列化结果会导致子类同名成员变量被父类的值覆盖。
  • hessian中的writeReplace方法与readResolve方法的作用一样,如果序列化的对象具有此方法,会利用此方法返回的实例来代替序列化后实例,用以保证对象的单例性。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1423897.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Flink实战五_状态机制

接上文&#xff1a;Flink实战四_TableAPI&SQL 在学习Flink的状态机制之前&#xff0c;我们需要理解什么是状态。回顾我们之前介绍的很多流计算的计算过程&#xff0c;有些计算方法&#xff0c;比如说我们之前多次使用的将stock.txt中的一行文本数据转换成Stock股票对象的ma…

LTC5548 具宽带 DC 至 6GHz IF 的 2GHz 至 14GHz 微波混频器

优势和特点 上变频或下变频高 IIP3&#xff1a;在 5.8GHz 为 24.4dBm在 9GHz 为 21.4dBm7.1dB 转换损耗 (在 5.8GHz)15.2dBm 输入 P1dB (在 5.8GHz)集成型 LO 缓冲器&#xff1a;0dBm LO 驱动可选的集成型 LO 倍频器低 LO-RF 泄漏&#xff1a;< –30dBm50Ω 宽带匹配 RF 和…

Hadoop3.x基础(2)- HDFS

来源&#xff1a;B站尚硅谷 目录 HDFS概述HDFS产出背景及定义HDFS优缺点HDFS组成架构HDFS文件块大小&#xff08;面试重点&#xff09; HDFS的Shell操作&#xff08;开发重点&#xff09;基本语法命令大全常用命令实操准备工作上传下载HDFS直接操作 HDFS的API操作HDFS的API案例…

01神经网络的理论及实现

感知机的缺点就是需要设置合适的权重&#xff0c;而权重的设置都是人工操作的。 1、从感知机到神经网络 重新画出感知机的模型&#xff0c;在图上加上偏置&#xff0c;由于偏置始终为1&#xff0c;所以颜色加深。 图1-1 感知机模型 引入新函数(激活函数&#xff09;&#xff…

Zookeeper分布式命名服务实战

目录 分布式命名服务 分布式API目录 分布式节点的命名 分布式的ID生成器 分布式的ID生成器方案&#xff1a; 基于Zookeeper实现分布式ID生成器 基于Zookeeper实现SnowFlakeID算法 分布式命名服务 命名服务是为系统中的资源提供标识能力。ZooKeeper的命名服务主要是利用Z…

20240131在ubuntu20.04.6下使用whisper不同模式的比对

20240131在ubuntu20.04.6下使用whisper不同模式的比对 2024/1/31 16:07 首先你要有一张NVIDIA的显卡&#xff0c;比如我用的PDD拼多多的二手GTX1080显卡。【并且极其可能是矿卡&#xff01;】 2、请正确安装好NVIDIA最新的驱动程序和CUDA。可选安装&#xff01; 3、配置whisper…

大华智慧园区综合管理平台 bitmap 任意文件上传漏洞复现

0x01 产品简介 “大华智慧园区综合管理平台”是一款综合管理平台,具备园区运营、资源调配和智能服务等功能。平台意在协助优化园区资源分配,满足多元化的管理需求,同时通过提供智能服务,增强使用体验。 0x02 漏洞概述 大华智慧园区综合管理平台 /emap/webservice/gis/so…

麒麟系统—— openKylin 安装 Nginx

麒麟系统—— openKylin 安装 Nginx 一、准备工作1. 确保麒麟系统 openKylin 已经安装完毕。 二、下载 nginx三、解压与运行解压检查与编译安装编译运行 Nginx 是一款高性能的 HTTP 和反向代理服务器&#xff0c;广泛应用于 Web 服务器领域。本文将分享如何在麒麟系统&#xf…

正则表达式及文本处理三剑客(grep、sed、awk)

目录 一、正则表达式 1、正则表达式的概述 1.1 正则表达式的概念和作用 1.2 正则表达式支持的语言 1.3 正则表达式的优缺点 1.4 正则表达式的分类 1.4.1 基本正则表达式&#xff08;BRE&#xff09;&#xff1a; 1.4.2 扩展正则表达式&#xff08;ERE&#xff09;&…

「数据结构」1.初识泛型

&#x1f387;个人主页&#xff1a;Ice_Sugar_7 &#x1f387;所属专栏&#xff1a;Java数据结构 &#x1f387;欢迎点赞收藏加关注哦&#xff01; 初识泛型 &#x1f349;前言&#x1f349;包装类&#x1f34c;装箱&拆箱 &#x1f349;泛型&#x1f34c;擦除机制&#x1f…

爬虫学习笔记-Cookie登录古诗文网

1.导包请求 import requests 2.获取古诗文网登录接口 url https://so.gushiwen.cn/user/login.aspxfromhttp%3a%2f%2fso.gushiwen.cn%2fuser%2fcollect.aspx # 请求头 headers {User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like …

基于MATLAB实现的OFDM仿真调制解调,BPSK、QPSK、4QAM、16QAM、32QAM,加性高斯白噪声信道、TDL瑞利衰落信道

基于MATLAB实现的OFDM仿真调制解调&#xff0c;BPSK、QPSK、4QAM、16QAM、32QAM&#xff0c;加性高斯白噪声信道、TDL瑞利衰落信道 相关链接 OFDM中的帧&#xff08;frame&#xff09;、符号&#xff08;symbol&#xff09;、子载波&#xff08;subcarriers&#xff09;、导频…

20240127在ubuntu20.04.6下配置whisper

20240131在ubuntu20.04.6下配置whisper 2024/1/31 15:48 首先你要有一张NVIDIA的显卡&#xff0c;比如我用的PDD拼多多的二手GTX1080显卡。【并且极其可能是矿卡&#xff01;】800&#xffe5; 2、请正确安装好NVIDIA最新的驱动程序和CUDA。可选安装&#xff01; 3、配置whispe…

Windows Server 2003 DNS服务器搭建

系列文章目录 目录 系列文章目录 文章目录 前言 一、DNS服务器是什么&#xff1f; 二、配置服务器 1.实验环境搭建 2.服务器搭建 3)安装Web服务器和DNS服务器 4)查看安装是否成功 5)这里直接配置DNS服务器了,Web服务器如何配置我已经发布过了 文章目录 Windows Serve…

(已解决)Properties和Yaml格式互转

工具转换&#xff1a; 推荐转换工具或者下载idea插件yamls yml&#xff0c;properties互转工具&#xff1a;yaml和proper互转工具 插件转换&#xff1a; 下载yaml插件&#xff0c;对需要转换的文件右键选择转换

林浩然与他的“圆”满人生

林浩然与他的“圆”满人生 Lin Haoran and His “Round” Life of Fulfillment 在那遥远的数学王国&#xff0c;有一个名叫林浩然的小哥&#xff0c;他可不是一般的程序员&#xff0c;而是个痴迷于几何之美、生活之趣的大玩家。话说有一天&#xff0c;林浩然正沉浸在毕达哥拉斯…

4秒读取50w行Excel数据

4秒读取50w行Excel数据 文章比较了几种常用的读取Excel的方法&#xff0c;最终发现rust库Calamine的速度最快&#xff0c;可以在4秒内读取50w行excel数据。 原文&#xff1a;Fastest Way to Read Excel in Python&#xff1a;https://hakibenita.com/fast-excel-python 我们在…

【FFmpeg】ffplay 命令行参数 ① ( 设置播放分辨率 | 禁用 音频 / 视频 / 字幕 选项 )

文章目录 一、ffplay 命令行参数 - 设置播放分辨率1、强制设置通用播放分辨率 -x -y 参数2、命令行示例 - 正常播放视频3、命令行示例 - 强制设置播放分辨率4、设置 YUV 播放分辨率 -video_size 和 像素设置 -pixel_format5、全屏播放 -fs 参数 二、ffplay 命令行参数 - 禁用 音…

ElementUI 组件:Container 布局容器

ElementUI安装与使用指南 Container 布局容器 点击下载learnelementuispringboot项目源码 效果图 el-container.vue页面效果图 项目里el-container.vue代码 <script> import PagePath from "/components/PagePath.vue";export default {name: el_conta…

离线使用Element UI和Vue

需要依赖如下&#xff1a; 1.vue.js; 2.index.js(Element UI) 3.index.css(Element UI) 4.element-icons.ttf(Element UI字体) 5.element-icons.woff(Element UI图标) 下载链接如下&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1nGOi0Vm_xExRGmVp6oVLoA 提取…