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

[Java安全入门]二.序列化与反序列化

一.概念

Serialization(序列化)是一种将对象以一连串的字节描述的过程;反序列化deserialization是一种将这些字节重建成一个对象的过程。将程序中的对象,放入文件中保存就是序列化,将文件中的字节码重新转成对象就是反序列化

二.要求

只有实现了Serializable或Externalizable接口的类的对象才能被序列化,并且序列化对象的所有属性都需是可序列化的。

三.实现

serializable接口

1.1方法

序列化:创建一个ObjectOutputStream输出流,调用 ObjectOutputStream 对象的 writeObject() 输出可序列化对象

   反序列化:创建一个ObjectInputStream输出流,调用 ObjectInputStream 对象的 readObject()得到反序列化的对象

1.2代码

import java.io.*;
import java.lang.reflect.Method;class User implements Serializable{private String name;private int age;@Overridepublic String toString(){return "User{" + "name=" +name + ", age="+age+"}";}public void setName(String name) {this.name = name;}public void setAge(int age) {this.age = age;}
}
public class Main {public static void main(String[] args) throws Exception {ObjectOutputStream out=new ObjectOutputStream(new FileOutputStream("E:\\tao.txt"));//创建一个ObjectOutputStream流,将序列化对象输出到tao.txtUser user=new User();user.setName("tao");user.setAge(20);//实例化Userout.writeObject(user);ObjectInputStream in=new ObjectInputStream(new FileInputStream("E:\\tao.txt"));// 创建一个 ObjectOutputStream 输出流User tao=(User)in.readObject();//将readObject反序列化的结果转化成User类,实例成taoSystem.out.println(tao);}
}

User{name=tao, age=20}

1.3注意

①如果实现 Serializable 接口的类有父类,则父类也必须可以序列化,若父类没有实现序列化接口,则父类必须有无参构造函数,否则会抛异常 java.io.InvalidClassException。因为在父类没有实现 Serializable 接口时,虚拟机是不会序列化父对象的,而一个 Java 对象的构造必须先有父对象,才有子对象,反序列化也不例外。所以反序列化时,为了构造父对象,只能调用父类的无参构造函数作为默认的父对象。因此当我们取父对象的变量值时,它的值是调用父类无参构造函数后的值。如果没有在父类无参构造函数中对父类变量进行初始化的话,父类变量值都是默认声明的值,如 int 型的默认是 0,string 型的默认是 null。

②序列化不保存静态变量,因为序列化保存的是对象的状态而不是类的状态,静态变量是类的状态

③ 使用transient 关键字可以选择不需要序列化的字段

如:

private transient String name;
private transient int age;

进行序列化的时候,name和age都不会被保存

Externalizable接口

2.1注意

①Externalizable接口继承Serializable 接口

②writeExternal()和readExternal()对应writeObject()和readObject()两个方法

③Externalizable序列化没有属性限制,静态变量以及transient 关键字修饰的属性都能被序列化

④必须提供public的无参构造方法,因为在反序列化实现 Externalizabale 接口的类的时需要通过反射创建对象。如果没有无参数的构造方法,在运行时会抛出异常:java.io.InvalidClassException

2.2代码

import java.io.*;
import java.lang.reflect.Method;class User implements Externalizable{private String name;private int age;public User(){}//加上public无参构造器@Overridepublic String toString(){return "User{" + "name=" +name + ", age="+age+"}";}public void setName(String name) {this.name = name;}public void setAge(int age) {this.age = age;}@Override//重写writeExternal()方法public void writeExternal(ObjectOutput out) throws IOException{out.writeObject(name);}@Override//重写wreadExternal()方法public void readExternal(ObjectInput in) throws IOException,ClassNotFoundException{name=(String)in.readObject();}}
public class Main {public static void main(String[] args) throws Exception {ObjectOutputStream out=new ObjectOutputStream(new FileOutputStream("E:\\tao.txt"));//创建一个ObjectOutputStream流,将序列化对象输出到tao.txtUser user=new User();user.setName("tao");user.setAge(20);//实例化Userout.writeObject(user);ObjectInputStream in=new ObjectInputStream(new FileInputStream("E:\\tao.txt"));// 创建一个 ObjectOutputStream 输出流User tao=(User)in.readObject();//将readObject反序列化的结果转化成User类,实例成taoSystem.out.println(tao);}
}

result

User{name=tao, age=0}

age变成了0

因为使用Externalizable接口,需要重写writeExternal() 与 readExternal() 方法,我只写了name的实现,没有写age,int型默认值为0

四.安全

java反序列化会自动触发readObject()方法,类似于php反序列化的__destruct()函数

java支持自定义writeObject()和readObject()方法

如果某个类中自定义了readObject()方法,当对其的一个实例化对象进行反序列化,就会调用readObject()方法

import java.io.*;
import java.lang.reflect.Method;class User implements Serializable{private String name;private int age;@Overridepublic String toString(){return "User{" + "name=" +name + ", age="+age+"}";}public void setName(String name) {this.name = name;}public void setAge(int age) {this.age = age;}private void readObject(ObjectInputStream in){System.out.println("这是新的readObject!");}
}
public class Main {public static void main(String[] args) throws Exception {ObjectOutputStream out=new ObjectOutputStream(new FileOutputStream("E:\\tao.txt"));//创建一个ObjectOutputStream流,将序列化对象输出到tao.txtUser user=new User();user.setName("tao");user.setAge(20);//实例化Userout.writeObject(user);ObjectInputStream in=new ObjectInputStream(new FileInputStream("E:\\tao.txt"));// 创建一个 ObjectOutputStream 输出流User tao=(User)in.readObject();//将readObject反序列化的结果转化成User类,实例成taoSystem.out.println(tao);}
}

结果

这是新的readObject!
User{name=null, age=0}

可见在反序列化的时候实现了新的readObject()

那么就可以命令执行了

 private void readObject(ObjectInputStream in) throws IOException{Runtime.getRuntime().exec("calc");}

弹计算器了!

这里初步了解java序列化与反序列话,后续构造链会继续学习。

参考博客

java基础知识点2:序列化与反序列化详解_java序列化和反序列化-CSDN博客

javasec/2.java序列化与反序列化.md at master · Maskhe/javasec (github.com)

相关文章:

[Java安全入门]二.序列化与反序列化

一.概念 Serialization(序列化)是一种将对象以一连串的字节描述的过程;反序列化deserialization是一种将这些字节重建成一个对象的过程。将程序中的对象,放入文件中保存就是序列化,将文件中的字节码重新转成对象就是反…...

Dutree:Linux 文件系统磁盘使用追踪工具

在 Linux 系统中,对文件系统的磁盘使用情况进行跟踪和管理是至关重要的。dutree 是一个功能强大的工具,它能够以可视化的方式展示文件系统中的目录和文件的大小,帮助用户更好地了解磁盘空间的使用情况。本文将介绍 dutree 工具的使用方法、功…...

http和https的区别是什么?

–前言 传输信息安全性不同、连接方式不同、端口不同、证书申请方式不同 一、传输信息安全性不同 1、http协议:是超文本传输协议,信息是明文传输。如果攻击者截取了Web浏览器和网站服务器之间的传输报文,就可以直接读懂其中的信息。 2、h…...

学习Android的第十九天

目录 Android ExpandableListView 分组列表 ExpandableListView 属性 ExpandableListView 事件 ExpandableListView 的 Adapter 范例 参考文档 Android ViewFlipper 翻转视图 ViewFlipper 属性 ViewFlipper 方法 为 ViewFlipper 加入 View 例子:全屏幕可…...

C#上位机调试经验

1.使用Visual Studio的远程工具 因为上位机软件安装在工控机上,不方便调试。如果直接把代码放在工控机上,又不太安全。 可以在工控机上安装一个Visual Studio的远程工具,把随身带的笔记本电脑通过网线插在工控机上 这样可以在笔记本上使用…...

BUUCTF---[极客大挑战 2019]BabySQL1

1.这道题和之前做的几道题是相似的,这道题考的知识点更多。难度也比之前的大一些 2.尝试万能密码 or 1#发现过滤了or,使用1和1,发现他对单引号也进行了过滤。于是我尝试进行双写绕过,发现可以通过了。 3.由之前的做题经验可知,这道题会涉及到…...

0基础跨考计算机|408保姆级全年计划

我也是零基础备考408! 虽说是计算机专业,但是本科一学期学十几门,真的期末考试完脑子里什么都不进的...基本都是考前一周发疯学完水过考试...😅 想要零基础跨考可以直接从王道开始!跟教材一点一点啃完全没必要🥸 现在…...

C# 操作LiteDB

1、很简单的东西不废话,直接上图上代码。 2、NuGet程序中根据自己的项目版本安装LiteDB,如下图: 3、程序运行加过如下图: 4、程序代码如下: using System; using System.Collections.Generic; using System.Linq; using System…...

LeetCode 2917.找出数组中的 K-or 值:基础位运算

【LetMeFly】2917.找出数组中的 K-or 值:基础位运算 力扣题目链接:https://leetcode.cn/problems/find-the-k-or-of-an-array/ 给你一个下标从 0 开始的整数数组 nums 和一个整数 k 。 nums 中的 K-or 是一个满足以下条件的非负整数: 只有…...

MySQL窗口函数:从理论到实践

目录 1. ROW_NUMBER() 2. RANK() 3. DENSE_RANK() 4. NTILE(n) 5. LAG() 和 LEAD() 6. FIRST_VALUE() 和 LAST_VALUE() 总结 MySQL中的窗口函数(Window Functions)允许用户对一个结果集的窗口(或分区)执行计算,…...

Vue+SpringBoot打造考研专业课程管理系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 数据中心模块2.2 考研高校模块2.3 高校教师管理模块2.4 考研专业模块2.5 考研政策模块 三、系统设计3.1 用例设计3.2 数据库设计3.2.1 考研高校表3.2.2 高校教师表3.2.3 考研专业表3.2.4 考研政策表 四、系统展示五、核…...

python基础第二天

世界杯小组赛成绩 注意: 1.循环 1.1while 1.2for 1.3 range 1.4 while else while 循环正常执行完才能执行else语句...

YOLOV9论文解读

代码:https://github.com/WongKinYiu/yolov9论文:https://arxiv.org/abs/2402.1361本文提出可编程梯度信息(PGI)和基于梯度路径规划的通用高效层聚合网络(GELAN),最终铸成YOLOv9目标检测全新工作!性能表现SOTA!在各个方…...

【Spring】21 通过@Primary注解优化注解驱动的自动装配

文章目录 Primary注解简介优势和适用场景小结 Spring 框架提供了强大的依赖注入机制,其中 Autowired 注解是一种常用的方式。然而,当存在多个候选 bean 时,通过类型自动装配可能导致选择困难。为了更好地控制这一过程,Spring 引入…...

【HTML】HTML基础7.3(自定义列表)

目录 标签 效果 代码 注意 标签 <dl> <dt>自定义标题</dt><dd>内容1</dd><dd>内容2</dd><dd>内容3</dd> 。。。。。。 </dl> 效果 代码 <dl><dt>蜘蛛侠系列</dt><dd>蜘蛛侠1</dd…...

java设计模式课后作业(待批改)

此文章仅记录学习&#xff0c;欢迎各位大佬探讨 实验&#xff08;一&#xff09; 面向对象设计 实验目的 ①使用类来封装对象的属性和功能&#xff1b; ②掌握类变量与实例变量&#xff0c;以及类方法与实例方法的区别&#xff1b; 知识回顾 详情见OOP课件 实验内容…...

qt 语音引擎 QTextToSpeech Microsoft SAPI

QT中语音播报的代码 在QT中实现语音播报可以使用QTextToSpeech类&#xff0c;具体代码如下&#xff1a; #include <QCoreApplication> #include <QTextToSpeech> #include <QDebug>int main(int argc, char *argv[]) {QCoreApplication a(argc, argv);// 创…...

react hook: useimperativeHandle

通过 useImperativeHandle&#xff0c;子组件可以选择性地暴露给父组件某些属性或方法&#xff0c;而不是将所有属性和方法暴露出去。 父组件 获得自组件的 ref&#xff0c;就能通过该 ref 来调用 focus来聚焦等功能 在 forwardRef 包装的组件中&#xff0c;ref 固定地是第二个…...

30天自制操作系统(第28天)

28.1 alloca __alloca 会在下述情况下被 C 语言的程序调用&#xff08;采用 near-CALL 的方式&#xff09;。 1、要执行的操作从栈中分配 EAX 个字节的内存空间&#xff08; ESP - EAX; &#xff09; 2、要遵守的规则不能改变 ECX 、 EDX 、 EBX 、 EBP 、 ESI 、 EDI的值&am…...

Nginx启动服务

Nginx启动服务 一、启动前置 下载地址 如已安装Docker&#xff0c;下一步拉取Nginx最新的Docker镜像&#xff1a; docker pull nginx:latest查看拉取下来的镜像&#xff1a; docker images二、启动服务 创建Docker容器&#xff1a; docker run --name {projectname} -p 80…...

国防科技大学计算机基础课程笔记02信息编码

1.机内码和国标码 国标码就是我们非常熟悉的这个GB2312,但是因为都是16进制&#xff0c;因此这个了16进制的数据既可以翻译成为这个机器码&#xff0c;也可以翻译成为这个国标码&#xff0c;所以这个时候很容易会出现这个歧义的情况&#xff1b; 因此&#xff0c;我们的这个国…...

Ubuntu系统下交叉编译openssl

一、参考资料 OpenSSL&&libcurl库的交叉编译 - hesetone - 博客园 二、准备工作 1. 编译环境 宿主机&#xff1a;Ubuntu 20.04.6 LTSHost&#xff1a;ARM32位交叉编译器&#xff1a;arm-linux-gnueabihf-gcc-11.1.0 2. 设置交叉编译工具链 在交叉编译之前&#x…...

解锁数据库简洁之道:FastAPI与SQLModel实战指南

在构建现代Web应用程序时&#xff0c;与数据库的交互无疑是核心环节。虽然传统的数据库操作方式&#xff08;如直接编写SQL语句与psycopg2交互&#xff09;赋予了我们精细的控制权&#xff0c;但在面对日益复杂的业务逻辑和快速迭代的需求时&#xff0c;这种方式的开发效率和可…...

页面渲染流程与性能优化

页面渲染流程与性能优化详解&#xff08;完整版&#xff09; 一、现代浏览器渲染流程&#xff08;详细说明&#xff09; 1. 构建DOM树 浏览器接收到HTML文档后&#xff0c;会逐步解析并构建DOM&#xff08;Document Object Model&#xff09;树。具体过程如下&#xff1a; (…...

屋顶变身“发电站” ,中天合创屋面分布式光伏发电项目顺利并网!

5月28日&#xff0c;中天合创屋面分布式光伏发电项目顺利并网发电&#xff0c;该项目位于内蒙古自治区鄂尔多斯市乌审旗&#xff0c;项目利用中天合创聚乙烯、聚丙烯仓库屋面作为场地建设光伏电站&#xff0c;总装机容量为9.96MWp。 项目投运后&#xff0c;每年可节约标煤3670…...

视频字幕质量评估的大规模细粒度基准

大家读完觉得有帮助记得关注和点赞&#xff01;&#xff01;&#xff01; 摘要 视频字幕在文本到视频生成任务中起着至关重要的作用&#xff0c;因为它们的质量直接影响所生成视频的语义连贯性和视觉保真度。尽管大型视觉-语言模型&#xff08;VLMs&#xff09;在字幕生成方面…...

C++中string流知识详解和示例

一、概览与类体系 C 提供三种基于内存字符串的流&#xff0c;定义在 <sstream> 中&#xff1a; std::istringstream&#xff1a;输入流&#xff0c;从已有字符串中读取并解析。std::ostringstream&#xff1a;输出流&#xff0c;向内部缓冲区写入内容&#xff0c;最终取…...

鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个生活电费的缴纳和查询小程序

一、项目初始化与配置 1. 创建项目 ohpm init harmony/utility-payment-app 2. 配置权限 // module.json5 {"requestPermissions": [{"name": "ohos.permission.INTERNET"},{"name": "ohos.permission.GET_NETWORK_INFO"…...

在鸿蒙HarmonyOS 5中使用DevEco Studio实现录音机应用

1. 项目配置与权限设置 1.1 配置module.json5 {"module": {"requestPermissions": [{"name": "ohos.permission.MICROPHONE","reason": "录音需要麦克风权限"},{"name": "ohos.permission.WRITE…...

uniapp中使用aixos 报错

问题&#xff1a; 在uniapp中使用aixos&#xff0c;运行后报如下错误&#xff1a; AxiosError: There is no suitable adapter to dispatch the request since : - adapter xhr is not supported by the environment - adapter http is not available in the build 解决方案&…...