什么是序列化?序列化的作用是什么?Java 中如何实现序列化和反序列化?

一、序列化简述

序列化是指将结构化的数据( 例如对象 )转化成一个字符串 / 字节数组。转化过程中,不会造成数据信息部分丢失。

反序列化则为反向操作,将已经进行过序列化之后的数据还原回原本的结构化数据。正是序列化中需要保证转化之后的数据信息不会丢失,才能在反序列化之后成功转化为原来的数据。

常见的序列化方式有:Java 标准库中提供的序列化方式、JSON、Hessia、protobuffer、thrift……

序列化的目的是为了方便存储和传输。存储一般是指存储在文件中,而文件一般只能存储字符串 / 二进制数据,无法直接存储对象等结构化数据。而传输一般指的是网络传输,网络传输通常都是使用 socket 进行传输,socket 本质也是文件,因此也是只能传输字符串 / 二进制数据。

二、Java 中实现序列化的常用方式

1. 文本数据

针对于文本数据,首选便是使用 JSON 格式来进行序列化操作。

我们只需在 maven 中央仓库( Maven Repository: Search/Browse/Explore (mvnrepository.com )中搜索 Jackson 的相关依赖,找到任意一个版本然后引入即可使用。使用方式如下:

我们需要先创建一个 ObjectMapper 类的对象,然后使用其中的两个方法即可完成序列化和反序列化的操作:

序列化:writeValueAsString 方法就可以将一个 Java 对象转化成为一个 JSON 字符串,下述代码就是将一个 Map 类型的数据转化成 JSON 字符串。

注意:JSON 提供的序列化和反序列化方法都会抛出 JsonProcessingException,因此需要进行处理。

@RequestMapping("/demo")
@RestController
public class DemoController {
    @RequestMapping("/m1")
    public String method1() {
        ObjectMapper objectMapper = new ObjectMapper();
        Map<String, Object> arguments = new HashMap<>();
        arguments.put("aaa", 1);
        arguments.put("bbb", 2);
        
        try {
            return objectMapper.writeValueAsString(arguments);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        
        return "{}";
    }
}

反序列化:readValue 可以将 JSON 字符串转化成一个 Java 对象,该方法需要两个参数。第一个参数便是需要转化的数据,第二个参数是指定需要转化为 Java 对象的类型。

其中第二个参数如果是一个简单的对象,也即是没有泛型参数也不是诸如 Map 类的对象,则直接传入该类的类对象即可。如下所示:

@Data
public class User {
    private String userName;
    private String password;
}
@RequestMapping("/demo")
@RestController
public class DemoController {
    @RequestMapping("/m2")
    public User method2(@RequestBody String data) {
        ObjectMapper objectMapper = new ObjectMapper();
        try {
            User user = objectMapper.readValue(data, User.class);
            System.out.println(user);
            return user;
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }

        return null;
    }
}

如果第二个参数是一个带泛型参数或者集合类的复杂类型,则需要使用 TypeReference 来构造一个匿名内部类,传入泛型参数来进行描述:

@RequestMapping("/demo")
@RestController
public class DemoController {
    @RequestMapping("/m3")
    public void method3(@RequestBody String data) {
        ObjectMapper objectMapper = new ObjectMapper();
        try {
            Map<String, Object> ret = objectMapper.readValue(data, new TypeReference<Map<String, Object>>() {});
            System.out.println(ret);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
    }
}

2. 二进制数据

可以看到 JSON 的方式使用起来还是十分方便的,但是由于 JSON 序列后的结果是文本数据,因此无法存储二进制数据。

这是由于 JSON 中有很多特殊符号,例如:{ }," ",[ ]……如果数据是文本,转化为 JSON 之后的键值对中就不会包含这些特殊符号,那么就不会出现歧义,序列化之后可以正常进行反序列化来解析。

但是如果是二进制数据,保不齐数据其中一小段二进制就和 JSON 中某一个特殊符号的 ascii 值相同,如果出现相同就会出现歧义,例如转化为 JSON 之后的键值对中的值是一个字符串,其中一小段二进制的值和 " 的 ascii 值相同,此时 JSON 进行反序列化解析的时候就会发现三个 " ( 本应该只有两个 " ),此时就会发生解析错误,误以为前两个 "  就是值的所有内容。

因此我们就不能对二进制数据使用 JSON 来进行序列化处理,而 Java 标准库中提供的序列化方法就可以对二进制数据使用,这种方式是 Java 中最直接最方便的使用,因为不需要再引入第三方库就可以直接是使用。

首先,我们需要对需要进行序列化的 Java 对象实现 Serializable 接口,来表示该类是可序列化的。实现该接口无需重写任何方法。但是需要注意的是:如果该对象其中有属性也是类,那么这个属性也需要实现该接口,才能达到完全序列化。

例如:

public class School implements Serializable {
    private Student student;
    private int count;
}

如果 School 对象想要使用 Java 标准库提供的序列化方法,School 类需要实现 Serializable 接口,且由于其中的 student 属性也是一个类,因此 Student 类也需要实现 Serializable 接口。

序列化:创建一个 ObjectOutputStream 流对象,调用其中的 writeObject 方法,传入需要序列化的数据即可。

反序列化:创建一个 ObjectInputStream 流对象,调用其中的 readObject 方法,该方法无需传入参数,返回值是一个 Object 对象。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

游戏 AI 在体育竞技游戏中的应用实践,通过 PVE 对抗规则AI+自博弈的方式,训练出了高强度、多风格策略的足球 SPG 对战 AI | 附方案详情及资料

AI 在体育竞技游戏&#xff08;SPG&#xff0c;Sports Game&#xff09;中的应用已经成为游戏厂商持续探索的领域之一。随 着人工智能技术的不断发展&#xff0c;越来越多的游戏开发商开始使用 AI 来提升游戏的真实感和沉浸感。 例如&#xff0c;在足球模拟游戏中&#xff0c…

SpringMVC10、拦截器

10、拦截器 10.1、概述 SpringMVC的处理器拦截器类似于Servlet开发中的过滤器Filter,用于对处理器进行预处理和后处理。开发者可以自己定义一些拦截器来实现特定的功能。 过滤器与拦截器的区别&#xff1a;拦截器是AOP思想的具体应用。 过滤器 servlet规范中的一部分&…

力扣每日一题 猜数字游戏 阅读理解

Problem: 299. 猜数字游戏 思路 &#x1f468;‍&#x1f3eb; 灵神 复杂度 Code class Solution {public String getHint(String secret, String guess) {int a 0;int[] cntS new int[10];int[] cntG new int[10];for(int i 0; i < secret.length(); i){if(secre…

小迪安全34WEB 攻防-通用漏洞文件上传黑白盒审计逻辑中间件外部引用

#知识点&#xff1a; 1、白盒审计三要素 2、黑盒审计四要素 3、白黑测试流程思路 #详细点&#xff1a; 1、检测层面&#xff1a;前端&#xff0c;后端等 2、检测内容&#xff1a;文件头&#xff0c;完整性&#xff0c;二次渲染等 3、检测后缀&#xff1a;黑名单&…

http升级https需要做什么

背景&#xff1a;随着现代网络时代的高速发展&#xff0c;网络安全方面的日益更新&#xff0c;实现网站https协议的数量也在不断增多&#xff0c;完善安全方面的因素也在逐步增加。 下面从最基础的网站http协议全面升级为https协议的流程做出说明。 目录 首先带大家一起先了解…

打包paddle 运行时出现RuntimeError: (PreconditionNotMet) 错误的解决

一、问题描述 一个自动化操作的项目&#xff0c;使用了paddle&#xff0c;由于第一次用pyinstaller打包paddle项目(为什么不用nuitka?打包时间太长啦&#xff0c;遇到问题解决一次&#xff0c;时间都非常的长&#xff0c;无奈只把自己开发的模块用nuitka进行了打包&#xff0…

SSM整合项目(Vue3 + Element - Plus 创建项目基础页面)

文章目录 1.配置Vue启动端口1.修改vue.config.js2.启动 2.安装Element Plus命令行输入 npm install element-plus --save 3.修改Vue3默认样式并自定义一个组件1.修改App.vue1.删除原有结构2.启动项目查看 2.修改HomeView.vue3.删除HelloWorld.vue组件4.创建一个组件 src/compon…

介绍Kanzi

Linux开发过程中使用的Kanzi 是一个由 Rightware&#xff08;现为 Thundersoft 的一部分&#xff09;开发的跨平台图形用户界面&#xff08;GUI&#xff09;框架。它主要用于设计、开发和部署在计算机、移动设备和嵌入式设备上的2D和3D用户界面。Kanzi 提供了一个现代化的内容创…

GO语言-切片底层探索(上)

1.前言 今天在力扣上写算法&#xff0c;遇到了一个比较"奇怪"的错误。由于自己使用了递归切片&#xff0c;导致一开始没有看明白&#xff0c;直到在自己电脑上进行debug的时候才反应过来&#xff0c;原因出在了哪里&#xff1f;下面会先进行错误的分析和纠正&#x…

物理机win10怎么与虚拟机win10共享文件

打开win10虚拟机点击虚拟机选项安装vmTools 安装完成后系统会重启重启后关机 点击编辑虚拟机设置 选项、共享文件夹、总是启用 接下来点击添加选择你要共享的文件点击确定 打开虚拟机点击此电脑 就会看到共享的文件夹啦

python 导入excel空间三维坐标 生成三维曲面地形图 5-3、线条平滑曲面且可通过面观察柱体变化(三)

环境 python:python-3.12.0-amd64 包: matplotlib 3.8.2 pandas 2.1.4 openpyxl 3.1.2 scipy 1.12.0 import pandas as pd import matplotlib.pyplot as plt from mpl_toolkits.mplot3d import Axes3D from scipy.interpolate import griddata from matplotlib.c…

基于微信小程序的校园跑腿小程序,附源码

博主介绍&#xff1a;✌程序员徐师兄、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;…

SSM整合项目(添加家居)

文章目录 1.需求分析2.设计结构3.编写Service层1.创建文件夹2.FurnService.java3.FurnServiceImpl.java4.单元测试 FurnServiceTest.java5.指定默认图片位置1.Furn.java 为imgPath设置默认值2.Furn.java 的全参构造器内判断imgPath是否为空 4.返回json数据的通用类com/sun/furn…

【QT+QGIS跨平台编译】之七十:【QGIS_Analysis跨平台编译】—【qgsrastercalcparser.cpp生成】

文章目录 一、Bison二、生成来源三、构建过程一、Bison GNU Bison 是一个通用的解析器生成器,它可以将注释的无上下文语法转换为使用 LALR (1) 解析表的确定性 LR 或广义 LR (GLR) 解析器。Bison 还可以生成 IELR (1) 或规范 LR (1) 解析表。一旦您熟练使用 Bison,您可以使用…

C语言内存管理-数据段与代码段

数据段细分成如下几个区域&#xff1a; .bss 段&#xff1a;存放未初始化的静态数据&#xff0c;它们将被系统自动初始化为0.data段&#xff1a;存放已初始化的静态数据.rodata段&#xff1a;存放常量数据代码段细分成如下几个区域&#xff1a; .text段&#xff1a;存放用户代码…

南洋理工发布多模态金融交易Agent,平均利润提高36%!

金融市场是经济稳定的基石&#xff0c;它不仅促进了资本的分配&#xff0c;还提供了风险管理的机制。随着市场的不断演变&#xff0c;传统的基于规则的交易系统由于缺乏适应市场波动的能力而表现不佳。尽管基于强化学习的系统显示出更好的适应性&#xff0c;但它们在处理多模态…

LVGL:渐变方案

仿照qt的QGradient::Preset渐变类型写的&#xff0c;因为lvgl只支持水平/垂直渐变&#xff0c;且只支持两种颜色的渐变&#xff0c;所以有些类型的渐变未能实现&#xff0c;有些则缺少中间颜色。 代码&#xff1a; namespace Gradient { enum Preset {WarmFlame 1,NightFade…

allegro PCB设计心得笔记(二) -- ERROR(SPMHUT-144): Illegal arc specification

使用Allegro PCB Editor设计PCB&#xff0c;其中使用了中文丝印&#xff0c;设计完成后&#xff0c;进行Tools -> Database Check&#xff0c;提示如下错误&#xff1a; 对PCB文件进行反复检查&#xff0c;也没有找到具体问题&#xff0c;但是删除中文丝印封装后&#xff0c…

安卓玩机工具推荐----MTK芯片读写分区 备份分区 恢复分区 制作线刷包 工具操作解析

安卓玩机工具推荐----高通芯片9008端口读写分区 备份分区 恢复分区 制作线刷包 工具操作解析 安卓玩机工具推荐----ADB状态读写分区 备份分区 恢复分区 查看分区号 工具操作解析 前面做了两期教程。分别解析了下ADB端口与高通9008端口备份分区一些基础的常识&#xff0c;那么…

【Oracle之DataGuard的初步学习】

** 以下所有均是基于11G版本的 ** 一、DataGuard的部署方式 DG的部署最常用的方式就是直接在备库端部署一个空库然后再设置参数&#xff0c;但是这样做在初始同步时如果数据量过大会耗费较长的时间&#xff1b;相对来说这中方式比较简单不易出错。 还有一种方式就是通过rman的备…