每天学习一点点之从 SonarQube Code Smell 看 Serializable

相关文章:

  • 每天学习一点点之从 SonarQube Bug 看对线程中断异常的处理

昨天组内同学在进行代码合并的时候发现了一个 SonarQube 异常:
在这里插入图片描述

其实我之前也遇到过这个异常,但觉得“这种异常很无聊”,毕竟让 Spring Bean 去序列化,这不是扯么,就“偷懒”没有仔细去看。晚上回到家越想越不得劲,毕竟留个未知问题睡觉是很难受的,于是又打开电脑去看了下 Sonar 的描述:

Fields in a “Serializable” class should either be transient or serializable

Fields in a Serializable class must themselves be either Serializable or transient even if the class is never explicitly serialized or deserialized. For instance, under load, most J2EE application frameworks flush objects to disk, and an allegedly Serializable object with non-transient, non-serializable data members could cause program crashes, and open the door to attackers. In general a Serializable class is expected to fulfil its contract and not have an unexpected behaviour when an instance is serialized.

This rule raises an issue on non-Serializable fields, and on collection fields when they are not private (because they could be assigned non-Serializable values externally), and when they are assigned non-Serializable types within the class.

Noncompliant Code Example

public class Address {//...
}public class Person implements Serializable {private static final long serialVersionUID = 1905122041950251207L;private String name;private Address address;  // Noncompliant; Address isn't serializable
}

Compliant Solution

public class Address implements Serializable {private static final long serialVersionUID = 2405172041950251807L;
}public class Person implements Serializable {private static final long serialVersionUID = 1905122041950251207L;private String name;private Address address;
}

Exceptions

The alternative to making all members serializable or transient is to implement special methods which take on the responsibility of properly serializing and de-serializing the object. This rule ignores classes which implement the following methods:

 private void writeObject(java.io.ObjectOutputStream out)throws IOExceptionprivate void readObject(java.io.ObjectInputStream in)throws IOException, ClassNotFoundException;

See

  • MITRE, CWE-594 - Saving Unserializable Objects to Disk
  • Oracle Java 6, Serializable

可以发现 Sonar 的描述已经说的很清楚了:在一个声明为 Serializable 的类中,所有的字段都应该是 Serializabletransient,即使该类没有被显式地序列化或反序列化。

当一个对象被序列化时,它的所有字段(包括继承的字段)都必须是可以序列化的,也就是说它们必须要么实现了 java.io.Serializable 接口,要么被声明为 transient。这是因为,如果一个对象包含一些不是 Serializable 的字段,那么这些字段在序列化过程中将不会被保存,从而可能导致在反序列化时丢失重要的数据或引发其他问题。为了确保对象在序列化过程中得到完全的描述,并且可以在将来被正确地反序列化,我们需要将所有字段都声明为 Serializable 或者将它们声明为 transient

在这块代码中,也就是说引用 WarehouseService 的类实现了 Serializable,但是 WarehouseService 本身却没有实现 Serializable,这可能会导致序列化问题。

例如,我们有两个类:PersonAddress,其中 Person 实现了 Serializable 接口,而 Address 没有:

class Address {int id;String street;int zip;
}class Person implements Serializable {int id;String name;Address address;
}

如果我们尝试将一个 Person 对象序列化,就会出现异常,因为 Address 类中的字段不能被序列化:

Person p = new Person();
p.id = 1;
p.name = "John";
p.address = new Address();
// ...
try {FileOutputStream fileOut = new FileOutputStream("/tmp/tmp.txt");ObjectOutputStream out = new ObjectOutputStream(fileOut);out.writeObject(p);
} catch (IOException e) {
}

上述代码会抛出异常:

java.io.NotSerializableException: com.example.Addressat java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1184)at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:348)

解决这个问题的一种方法是在 Address 类中添加 implements Serializable 关键字,使其也成为可序列化的:

class Address implements Serializable {int id;String street;int zip;
}class Person implements Serializable {int id;String name;Address address;
}

另一种方法是将 Address 类中的字段声明为 transient,以防止它们被序列化:

class Address {transient int id;String street;int zip;
}class Person implements Serializable {int id;String name;Address address;
}

在此示例中,Address 类中的 id 字段将会被忽略,不会出现在序列化的数据中。 需要注意的是,如果一个字段声明为 transient,那么在反序列化时,它的值会被重置为其默认值。因此,如果你希望保留其值,在反序列化时应该手动设置。例如,我们可以在 Person 类中添加一个方法来设置地址的 ID:

public void setAddress(Address address) {this.address = address;if (address != null) {this.address.setId(this.id);}
}

另外,你还可以实现 private void writeObject(java.io.ObjectOutputStream out) throws IOExceptionprivate void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException 方法来控制如何序列化和反序列化对象。这两个方法通常被称为定制序列化方法,因为它们让你有机会自定义对象的序列化和反序列化方式。

总之,在设计类的时候,请注意一个关键点,如果你想要让一个类是可序列化的,那么它所有字段都必须是可序列化的。如果有字段不应该是序列化的,那么可以将它们声明为 transient,或者使用定制序列化方法来处理它们。

欢迎关注公众号:
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

WebSocket网络协议

二十六、WebSocket 26.1 介绍 WebSocket是基于TCP的一种新的网络协议。它实现了浏览器与服务器全双工通信,浏览器和服务器只需要完成一次握手,两者之间就可以创建持久性的连接,并进行双向数据传输。 HHTP协议和WebSocket协议对比&#xff…

Canvas—从入门到案例实现

文章目录 Canvas—从入门到案例实现一、设置canvas环境1.1 <canvas>元素1.2 渲染上下文context 二、形状与路径的绘制2.1 形状绘制2.2 路径绘制2.3 绘制一个笑脸 三、使用样式和颜色四、绘制文本五、使用图像5.1 图片源5.2 获取页面内的图片5.3 缩放Scaling5.4 切片Slici…

应急响应练习2

目录 1. 请提交攻击者的ip与系统版本 2. 攻击者通过某个组件漏洞获得服务器权限&#xff0c;请提交该组件的名称 3. 请提交攻击者首次攻击成功的时间 4. 请提交攻击者上传的webshell文件绝对路径 5. 请提交攻击者使用的webshell管理工具 6. 攻击者进一步留下的免杀的webs…

flutter逆向 ACTF native app

前言 算了一下好长时间没打过CTF了,前两天看到ACTF逆向有道flutter逆向题就过来玩玩啦,花了一个下午做完了.说来也巧,我给DASCTF十月赛出的逆向题其中一道也是flutter,不过那题我难度降的相当之低啦,不知道有多少人做出来了呢~ 还原函数名 flutter逆向的一大难点就是不知道l…

掌握Python中的控制流语句:break, continue, quit的应用技巧详解

引言 在Python编程中&#xff0c;控制流语句是非常重要的一部分&#xff0c;它们可以帮助我们控制程序的执行流程。其中&#xff0c;break、continue和quit是常用的控制流语句&#xff0c;它们可以在循环中起到关键作用。本文将详细介绍这些控制流语句的应用技巧&#xff0c;帮…

南湖HIT论坛|《医疗数据安全风险分析及防范实践(2023)》正式发布

11月11日&#xff0c;2023年南湖HIT论坛在浙江嘉兴隆重举行。作为颇受HIT从业者关注的年度盛会——本届论坛以“数据驱动医院运营管理”为主题&#xff0c;全国各地医疗机构信息主管和骨干围绕“数据驱动运营管理、运营数据中心建设、数据治理和数据安全”等话题展开深入研讨。…

Leetcode2652. 倍数求和

Every day a Leetcode 题目来源&#xff1a;2652. 倍数求和 解法1&#xff1a;模拟 计算在 [1&#xff0c;n] 范围内能被 3、5、7 整除的所有整数之和。 代码&#xff1a; /** lc appleetcode.cn id2652 langcpp** [2652] 倍数求和*/// lc codestart class Solution { pu…

冯诺依曼体系和操作系统简单介绍

冯诺依曼体系和操作系统简单介绍 冯诺依曼体系 输入设备&#xff1a;键盘&#xff0c;话筒&#xff0c;摄像头&#xff0c;usb&#xff0c;鼠标&#xff0c;磁盘/ssd&#xff0c;网卡等等输出设备&#xff1a;显示器&#xff0c;喇叭&#xff0c;打印机&#xff0c;磁盘&#…

VR建筑仿真场景编辑软件有助于激发创作者的灵感和创造力

随着VR虚拟现实技术的不断发展和普及&#xff0c;VR虚拟场景编辑器逐渐成为了VR场景开发重要工具。它对于丰富和完善VR虚拟现实内容的创建和呈现具有重要的意义&#xff0c;为我们的工作和教学带来了许多变化和可能性。 首先&#xff0c;VR虚拟场景编辑器对于提升用户体验具有重…

Windows UAC权限详解以及因为权限不对等引发的若干问题分享

目录 1、什么是UAC&#xff1f; 2、微软为什么要设计UAC&#xff1f; 3、标准用户权限与管理员权限 4、程序到底以哪种权限运行&#xff1f;与哪些因素有关&#xff1f; 4.1、给程序设置以管理员权限运行的属性 4.2、当前登录用户的类型 5、案例1 - 无法在企业微信聊天框…

asp.net core mvc之 布局

一、布局是什么&#xff1f; 布局是把每个页面的公共部分&#xff0c;提取成一个布局页面&#xff08;头、导航、页脚&#xff09;。 二、默认布局 _Layout.cshtml 默认的布局是在 /Views/Shared 目录的 _Layout.cshtml文件。通常Shared目录中的视图都是公共视图。该目录下的…

传统工艺的数字时代转变:十八数藏的文化创新

在传统工艺和数字时代的交汇之处&#xff0c;十八数藏以其独特的文化创新走在了前列。这场数字时代的转变为传统工艺注入了新的生命和活力。 十八数藏的文化创新并非简单的数字应用&#xff0c;而是一场深刻的转变。通过数字技术&#xff0c;传统工艺被赋予了新的表达方式&…