当前位置: 首页 > news >正文

对序列化反序列化在项目中的使用优化

文章目录

  • 序列化是什么?
  • 常见的序列化协议
  • 使用
    • 序列化
    • 反序列化
    • 序列化List
    • 反序列化List
  • 查看源码,分析不足
  • 进行改善

序列化是什么?

如果我们需要持久化 Java 对象比如将 Java 对象保存在文件中,或者在网络传输 Java 对象,这些场景都需要用到序列化。

  • 序列化:将数据结构或对象转换成可以存储或传输的形式,通常是二进制字节流,也可以是 JSON, XML 等文本格式
  • 反序列化:将在序列化过程中所生成的数据转换为原始数据结构或者对象的过程

对于 Java 这种面向对象编程语言来说,我们序列化的都是对象(Object)也就是实例化后的类(Class)

下面是序列化和反序列化常见应用场景:

  • 对象在进行网络传输(比如远程方法调用 RPC 的时候)之前需要先被序列化,接收到序列化的对象之后需要再进行反序列化;
  • 将对象存储到文件之前需要进行序列化,将对象从文件中读取出来需要进行反序列化;
  • 将对象存储到数据库(如 Redis)之前需要用到序列化,将对象从缓存数据库中读取出来需要反序列化;
  • 将对象存储到内存之前需要进行序列化,从内存中读取出来之后需要进行反序列化。

序列化的主要目的是通过网络传输对象或者说是将对象存储到文件系统、数据库、内存中。

常见的序列化协议

JDK 自带的序列化方式一般不会用 ,因为序列化效率低并且存在安全问题。比较常用的序列化协议有 fastjson、jackson、protobuf(PB)、、、
在我的项目中,使用jackson

使用

我们所有的jackson序列化以及反序列化都是基于ObjecMapper来操作的
我们先定义一个错误的异常类。后续所有的序列化反序列化操作都是针对这个错误类实例出的对象而完成的。

@Data
public class CommonResult<T> implements Serializable {private Integer code;private T data;private String msg;public static <T> CommonResult<T> success(T data) {CommonResult<T> result = new CommonResult<T>();result.code = GlobalErrorCodeConstants.SUCCESS.getCode();result.data = data;result.msg = "";return result;}public static <T> CommonResult<T> error(Integer code, String msg) {Assert.isTrue(!GlobalErrorCodeConstants.SUCCESS.getCode().equals(code),"code 不是错误的异常");CommonResult<T> result = new CommonResult<T>();result.code = code;result.msg = msg;return result;}public static <T> CommonResult<T> error(ErrorCode errorCode){return error(errorCode.getCode(), errorCode.getMsg());}
}

序列化

 void TestJackson(){ObjectMapper objectMapper = new ObjectMapper();CommonResult<String> commonResult1 =  CommonResult.error(500,"系统错误!");//序列化String str;try {str = objectMapper.writeValueAsString(commonResult1);System.out.println(str);} catch (JsonProcessingException e) {throw new RuntimeException(e);}}

反序列化

 //反序列化try {CommonResult<String> commonResult = objectMapper.readValue(str, CommonResult.class);System.out.println(commonResult.getCode()+commonResult.getMsg());} catch (JsonProcessingException e) {throw new RuntimeException(e);}

序列化List

//序列化listList<CommonResult<String>> list = Arrays.asList(CommonResult.success("success111"),CommonResult.success("success222"));try {str = objectMapper.writeValueAsString(list);System.out.println(str);} catch (JsonProcessingException e) {throw new RuntimeException(e);}

反序列化List

这里反序列化有一个注意事项
在这里插入图片描述
objecMapper.readValue里面的第二个参数 valueType不能直接放里不能直接放 list<CommonResult<String>>.class,要使用 JavaType的方法 将list 和 list里面的元素 整合成一个类型

 //反序列化listJavaType listType = objectMapper.getTypeFactory().constructParametricType(List.class,CommonResult.class);try {list = objectMapper.readValue(str,listType);System.out.println(list);} catch (JsonProcessingException e) {throw new RuntimeException(e);}

运行结果如下
在这里插入图片描述

查看源码,分析不足

在我上述给出的代码中,我们可以看到,每一次进行序列化反序列化操作时,都需要进行try-catch操作,那么我们观察springboot的源码,可以来借鉴改善我们的代码

点开SpringBoot源码,找到反序列化List的方法。

  public List<Object> parseList(String json) {return (List)this.tryParse(() -> {return (List)this.getObjectMapper().readValue(json, LIST_TYPE);}, Exception.class);}

我们观察到,里面调用到了tryParse这个方法,我们点开这个方法

 protected final <T> T tryParse(Callable<T> parser, Class<? extends Exception> check) {try {return parser.call();} catch (Exception var4) {Exception ex = var4;if (check.isAssignableFrom(ex.getClass())) {throw new JsonParseException(ex);} else {ReflectionUtils.rethrowRuntimeException(ex);throw new IllegalStateException(ex);}}}

我们可以看到parseList中通过lambda表达式的方式,将异常全部在tryParse中进行try-catch。

解析tryParse

  1. 参数列表
    Callable<T> parser, Class<? extends Exception> check
    第一个参数是一个Callable,第二个参数是一个Exception的class
  2. 返回值
    泛型T
  3. parser.call()
    相当于是将parseList中的lambda表达式进行调用。(List)this.tryParse(() -> { return (List)this.getObjectMapper().readValue(json, LIST_TYPE);
  4. catch (Exception var4) { Exception ex = var4; if (check.isAssignableFrom(ex.getClass())) { throw new JsonParseException(ex); }
    检查捕获的这个var4异常是否是我们传入的check异常的实例或者是其子类的一个实例,如果是,就抛出JsonParseException(ex)

5.else { ReflectionUtils.rethrowRuntimeException(ex); throw new IllegalStateException(ex); }
不是预期的异常,就抛出IllegalStateException(ex)

进行改善

  1. 对ObjecMappper使用一个单例的构造方法
  2. 使用tryParse来对try-catch进行优化
public class JacksonUtil {public JacksonUtil() {}//单例模式 创建objecMapperprivate final static ObjectMapper OBJECT_MAPPER;static {OBJECT_MAPPER = new ObjectMapper();}private static ObjectMapper getObjectMapper() {return OBJECT_MAPPER;}// 以后就可以直接调用这个方法 而不用再传一个异常private static <T> T tryParse(Callable<T> parser) {return tryParse(parser, JacksonException.class);}/*/参考的是 springboot源码  */private static <T> T tryParse(Callable<T> parser,Class<? extends Exception> check) {try {return parser.call();} catch (Exception ex) {if (check.isAssignableFrom(ex.getClass())) {throw new JsonParseException(ex);}throw new IllegalStateException(ex);}}/*** 序列化方法* @param object* @return*/public static String writeValueAsString(Object object){return JacksonUtil.tryParse(()->{return JacksonUtil.getObjectMapper().writeValueAsString(object);});}/*** 反序列化* @param content* @param valueType* @return* @param <T>*/public static<T> T readValue(String content, Class<T> valueType) {return JacksonUtil.tryParse(()->{return JacksonUtil.getObjectMapper().readValue(content, valueType);});}/*** 反序列化list* @param content* @param paramClasses* @return* @param <T>*/public static <T> T readListValue(String content, Class<?> paramClasses) {JavaType javaType = JacksonUtil.getObjectMapper().getTypeFactory().constructParametricType(List.class, paramClasses);return JacksonUtil.tryParse(()->{return JacksonUtil.getObjectMapper().readValue(content, javaType);});}}

相关文章:

对序列化反序列化在项目中的使用优化

文章目录 序列化是什么&#xff1f;常见的序列化协议使用序列化反序列化序列化List反序列化List 查看源码&#xff0c;分析不足进行改善 序列化是什么&#xff1f; 如果我们需要持久化 Java 对象比如将 Java 对象保存在文件中&#xff0c;或者在网络传输 Java 对象&#xff0c…...

查看 git log的过程中看到 :说明日志输出可能超出屏幕大小,系统进入了分页模式

在命令行提示符中&#xff0c;通常 : 表示系统等待进一步的输入。如果你在查看 git log 的过程中看到 :&#xff0c;说明日志输出可能超出屏幕大小&#xff0c;系统进入了分页模式&#xff0c;默认使用 less 命令查看内容。 此时你可以&#xff1a; 按 q 退出日志查看。按 En…...

Linux--信号量详解

目录 一、信号量 1、信号量相关函数 2、多线程环形队列生产消费模型 3、实现代码 信号量是将整体的资源分割成多份使用 信号量本质是对资源的预定机制 一、信号量 1、信号量相关函数 创建信号量: sem_init: int sem_init(sem_t *sem, int pshared, unsigned int value); …...

【重学 MySQL】五十一、更新和删除数据

【重学 MySQL】五十一、更新和删除数据 更新数据删除数据注意事项 在MySQL中&#xff0c;更新和删除数据是数据库管理的基本操作。 更新数据 为了更新&#xff08;修改&#xff09;表中的数据&#xff0c;可使用UPDATE语句。UPDATE语句的基本语法如下&#xff1a; UPDATE ta…...

Web3与人工智能的交叉应用探索

随着数字技术的发展&#xff0c;Web3与人工智能&#xff08;AI&#xff09;之间的结合正逐渐成为一个重要的研究领域。Web3技术旨在实现更加去中心化和透明的互联网&#xff0c;而人工智能则在数据分析、自动化决策和增强人类能力方面展示了巨大的潜力。 1. 去中心化数据管理与…...

【springboot9736】基于springboot+vue的逍遥大药房管理系统

作者主页&#xff1a;Java码库 主营内容&#xff1a;SpringBoot、Vue、SSM、HLMT、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、小程序、安卓app等设计与开发。 收藏点赞不迷路 关注作者有好处 文末获取源码 项目描述 伴随着全球信息化发展&#xff0c;行行业业都与计算机技…...

四.网络层(上)

目录 4.1网络层功能概述 4.2 SDN基本概念 4.3 路由算法与路由协议 4.3.1什么是路由协议&#xff1f; 4.3.2什么是路由算法&#xff1f; 4.3.3路由算法分类 (1)静态路由算法 (2)动态路由算法 ①全局性 OSPF协议与链路状态算法 ②分散性 RIP协议与距离向量算法 4.3.…...

Leecode热题100-56.合并区间

以数组 intervals 表示若干个区间的集合&#xff0c;其中单个区间为 intervals[i] [starti, endi] 。请你合并所有重叠的区间&#xff0c;并返回 一个不重叠的区间数组&#xff0c;该数组需恰好覆盖输入中的所有区间 。 示例 1&#xff1a; 输入&#xff1a;intervals [[1,3…...

安全帽未佩戴预警系统 劳保防护用品穿戴监测系统 YOLO

在建筑、矿山、电力等高危行业中&#xff0c;工人面临着各种潜在的危险&#xff0c;如高空坠物、物体打击等。安全帽能够有效地分散和吸收冲击力&#xff0c;大大降低头部受伤的严重程度。一旦工人未正确佩戴安全帽&#xff0c;在遭遇危险时&#xff0c;头部将直接暴露在危险之…...

【python机器学习】线性回归 拟合 欠拟合与过拟合 以及波士顿房价预估案例

文章目录 线性回归之波士顿房价预测案例 欠拟合与过拟合线性回归API 介绍:波士顿房价预测数据属性:机器学习代码实现 拟合 过拟合 欠拟合 模拟 及处理方法(正则化处理)导包定义函数表示欠拟合定义函数表示拟合定义函数表示过拟合 正则化处理过拟合L1正则化L2正则化 线性回归之波…...

IT招聘乱象的全面分析

近年来&#xff0c;IT行业的招聘要求似乎越来越苛刻&#xff0c;甚至有些不切实际。许多企业在招聘时&#xff0c;不仅要求前端工程师具备UI设计能力&#xff0c;还希望后端工程师精通K8S服务器运维&#xff0c;更有甚至希望研发经理掌握所有前后端框架和最新开发技术。这种招聘…...

一入递归深似海,算法之美无止境

最近在刷leetcode hot100,在写二叉树中最大路径和的时候,看到了一个佬对递归的理解,深受启发,感觉自己对于递归的题又行了!!! 这里给大家分享一下(建立大家先去尝试一下这道题再来看 124. 二叉树中的最大路径和 二叉树中的 路径 被定义为一条节点序列&#xff0c;序列中每…...

进程的状态的理解(概念+Linux)

文章目录 进程的状态并行和并发物理和逻辑 时间片进程具有独立性等待的本质运行阻塞标记挂起等待 Linux下的进程状态&#xff08;一&#xff09;运行状态&#xff08;R - running&#xff09;&#xff08;二&#xff09;睡眠状态&#xff08;S - sleeping&#xff09;&#xff…...

Apache Linkis + OceanBase:如何提升数据分析效率

计算中间件 Apache Linkis 构建了一个计算中间件层&#xff0c;以实现上层应用程序和底层数据引擎之间的连接、治理和编排。目前&#xff0c;已经支持通过数据源的功能&#xff0c;实现用户通过Linkis 对接并使用 OceanBase数据库。 本文详细阐述了在 Apache Linkis v1.3.2中&a…...

Day01-postgresql数据库基础入门培训

Day01-postgresql数据库基础入门培训 1、PostgresQL数据库简介2、PostgreSQL行业生态应用3、PostgreSQL版本发展与特性4、PostgreSQL体系结构介绍5、PostgreSQL与MySQL的区别6、PostgreSQL与Oracle、MySQL的对比 1、PostgresQL数据库简介 PostgreSQL【简称&#xff1a;PG】是加…...

打卡第四天 P1081 [NOIP2012 提高组] 开车旅行

今天是我打卡第四天&#xff0c;做个省选/NOI−题吧(#^.^#) 原题链接&#xff1a;[NOIP2012 提高组] 开车旅行 - 洛谷 题目描述 输入格式 输出格式 输入输出样例 输入 #1 4 2 3 1 4 3 4 1 3 2 3 3 3 4 3 输出 #1 1 1 1 2 0 0 0 0 0 输入 #2 10 4 5 6 1 …...

Jenkins Pipline流水线

提到 CI 工具&#xff0c;首先想到的就是“CI 界”的大佬--]enkjns,虽然在云原生爆发的年代,蹦出来了很多云原生的 CI 工具,但是都不足以撼动 Jenkins 的地位。在企业中对于持续集成、持续部署的需求非常多,并且也会经常有-些比较复杂的需求,此时新生的 CI 工具不足以支撑这些很…...

鸿蒙harmonyos next flutter混合开发之开发FFI plugin

创建FFI plugin summation&#xff0c;默认创建的FFI plugin是求两个数的和 flutter create --templateplugin_ffi summation --platformsandroid,ios,ohos 创建my_application flutter create --org com.example my_application 在my_application项目中文件pubspec.yaml引…...

oracle数据库安装和配置

Oracle数据库安装 一、安装前的准备 系统要求&#xff1a; 硬件&#xff1a;内存至少1GB&#xff08;推荐2GB以上&#xff09;&#xff0c;硬盘至少10GB的可用空间&#xff0c;CPU至少2核心。 操作系统&#xff1a;支持Oracle版本的Windows&#xff08;如Windows 10或更高版本…...

猫玖破密啦

题目&#xff1a; 终究还是猫哥:3d5a3a0cfff7fb2e29194c0b7a89f284ff19a8 玖离&#xff1a;收到消息Oh,what_is_the_flag 玖离:7468655f666c61675f69735f666c13556d2cf2faec1e2d0f330b7dcceea1c62cb2 终究还是猫哥&#xff1a;收到消息************************************ 已…...

CGI Studio 3.11:AI驱动与安全合规的嵌入式HMI开发平台解析

1. 项目概述&#xff1a;为什么我们需要CGI Studio这样的HMI设计工具&#xff1f;在嵌入式系统开发领域&#xff0c;尤其是在汽车、工业和高端家电行业&#xff0c;图形用户界面的复杂度和美观度要求正以前所未有的速度提升。十年前&#xff0c;一个简单的单色LCD屏幕配上几个按…...

GNA稀疏注意力机制:视觉Transformer计算优化实践

1. GNA稀疏注意力机制解析在视觉Transformer领域&#xff0c;计算效率一直是制约模型规模和应用场景的关键瓶颈。传统自注意力机制需要计算所有查询&#xff08;Query&#xff09;和键&#xff08;Key&#xff09;之间的交互&#xff0c;导致计算复杂度随序列长度呈平方级增长&…...

告别手动更新!用Python脚本+Excel表格批量修改UG零件参数(NX2007实战)

告别手动更新&#xff01;用Python脚本Excel表格批量修改UG零件参数&#xff08;NX2007实战&#xff09; 在工业设计领域&#xff0c;UG NX作为主流的三维建模软件&#xff0c;其参数化设计能力直接影响产品迭代效率。传统手动修改模型参数的方式不仅耗时费力&#xff0c;还容易…...

深入RISC-V调试模块:从硬件设计视角理解DM、DMI与抽象命令的实现

RISC-V调试模块的硬件实现艺术&#xff1a;从状态机到系统总线集成 在开源指令集架构RISC-V的生态系统中&#xff0c;调试功能的设计与实现一直是芯片开发者面临的核心挑战之一。本文将深入探讨RISC-V调试模块(Debug Module)的硬件实现细节&#xff0c;揭示从状态机设计到系统总…...

TVA视觉新范式:工业视觉的百年未有之大变局(2)

重磅预告&#xff1a;本专栏将独家连载系列丛书《智能体视觉技术与应用》部分精华内容&#xff0c;该书是世界首套系统阐述“因式智能体”视觉理论与实践的专著&#xff0c;特邀美国 TypeOne 公司首席科学家、斯坦福大学博士 Bohan 担任技术顾问。Bohan先生师从美国三院院士、“…...

新手必看:Infineon UDE软件License加载保姆级教程(含永久/临时版区别与常见报错解决)

Infineon UDE软件License配置全指南&#xff1a;从加载到深度排错 引言 在嵌入式开发领域&#xff0c;Infineon UDE&#xff08;Universal Debug Engine&#xff09;作为一款功能强大的调试工具&#xff0c;被广泛应用于汽车电子、工业控制等高可靠性场景。然而对于刚接触这款工…...

从ZEMAX到SOLIDWORKS:手把手教你搞定红外平行光管的跨软件光机设计流程

从ZEMAX到SOLIDWORKS&#xff1a;红外平行光管光机协同设计全流程解析 在光学工程领域&#xff0c;红外平行光管的设计往往需要跨越光学仿真与机械实现两大专业领域。这种"光机协同设计"过程既考验工程师对光学原理的理解&#xff0c;又要求熟练掌握专业软件间的数据…...

Windows HEIC缩略图终极解决方案:3步解锁苹果照片完美预览

Windows HEIC缩略图终极解决方案&#xff1a;3步解锁苹果照片完美预览 【免费下载链接】windows-heic-thumbnails Enable Windows Explorer to display thumbnails for HEIC/HEIF files 项目地址: https://gitcode.com/gh_mirrors/wi/windows-heic-thumbnails 还在为iPh…...

枚举进阶:从常量集合到业务逻辑承载者的实战扩展技巧

1. 项目概述&#xff1a;从“能用”到“好用”的枚举进阶之路在软件开发中&#xff0c;枚举&#xff08;Enum&#xff09;是我们再熟悉不过的基础工具了。它把一组有限的、具名的常量组织在一起&#xff0c;让代码意图更清晰&#xff0c;避免“魔法数字”满天飞。但不知道你有没…...

避坑指南:STM32驱动LD3320语音模块,SPI通信和中断配置的那些‘坑’我都替你踩过了

STM32与LD3320语音模块深度避坑实战&#xff1a;从SPI配置到中断优化的完整指南 当第一次拿到LD3320语音识别模块时&#xff0c;大多数开发者都会为它的"即插即用"特性感到兴奋——理论上只需要简单的SPI连接和基础配置就能实现语音识别功能。然而在实际项目中&#…...