将本地已经实例化的某个对象(此对象有参数),有 传输或持久化、重构Java对象 的需求,怎么才能把数据包装到一起?
众所周知,参数指向内存中的地址,这些内存地址存储着实际的数据,这些地址可能并不连续,这就使得在内存中到处都有此对象的参数数据,怎么才能把这些数据全部集合在一起呢?得到集成在一起的数据了,怎么才能把它转化为内存的对象参数呢?
这就需要使用 序列化和反序列化 技术:
序列化常用类型分为 text and binary 两种形式(不常用不列),即 字符串和字节流。
序列化技术,具有 跨语言、跨平台、可扩展和向下兼容 的优点。比如C语言中序列化一个对象后,可以被对应的Java语言解析出来。
数据对象,必须被encoding编码以后才能被序列化(UTF-8等)。下面使用Java分别实现序列化实体类实例为 字节流和文本,文本处以JSON数据格式为例。
Java实现序列化注意的点:
以序列化为二进制数据存储到本地为例(字节流序列化实际应用偏向于存储到本地),简单实现:
实体类User
public class User implements Serializable {
// getter,setter,constructor 加上
private static final long serialVersionUID = 5887391604554532906L;
private String name;
private Integer age;
private Character sex;
}
序列化和反序列化操作
public static void main(String[] args) throws Exception {
// 序列化 二进制存储到本地
User user = new User("张三",22,'男');
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("User.obj"));
oos.writeObject(user); // 写到本地文件中
//反序列化 从本地文件中获取数据
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("User.obj"));
User user1 = (User) ois.readObject();
System.out.println(user1);
}
现在,就可在当前项目的根目录看到此文件(也可以自己指定位置),打开它(建议使用sublime text或其他编辑器打开):
【Java、JS与JSON互转,点击我快速跳转!】
以为JSON序列化,进行打印为例。JSON序列化实际应用偏向于传输数据。这里使用Java类库实现简单Java对象转换为JSON字符串:
// user 是前面代码中的实现
// 使用java类库 throws JsonProcessingException
String json = new ObjectMapper().writeValueAsString(user);
System.out.println(json);
输出如下
{“name”:“张三”,“age”:22,“sex”:“男”}
简单实现肯定是有一些问题,那么为什么我这么敷衍?因为我们可以使用阿里的fastjson类库,使用及其广泛,特别强大!【点击我查看并学习fastjson使用】。
针对于二进制序列化
举个例子:在平时我们与人说话交流的时候,大家都用普通话,如果有人使用家乡话,你就会感觉到听不懂了,更别说好好交流了。这里的普通话就是一种协议,作为我们与身边人的语言协议,大家都遵守它才能高效沟通。
而serialVersionUID就是序列化操作的协议,我在解析别人传递给我的数据的时候,会去检查此文件是否遵守协议,遵守我才能正常解析,不遵守我就直接抛出异常(解析也会出现问题)。即反序列化时,JVM会判断serialVersionUID是否一致,不一致就会直接抛出异常。
比如前后使用不同的serialVersionUID:
当我们一个实体类中没有显式的定义一个名为 serialVersionUID、类型为long的变量时,Java序列化机制会根据编译时的class自动生成一个serialVersionUID作为序列化版本比较,这种情况下,只有同一次编译生成的class才会生成相同的serialVersionUID。时间不同,也会出错。那么如何决呢?便是在本地类中加个serialVersionUID变量,值保持不变,便可以进行序列化和反序列化(显式的定义一个serialVersionUID)。
下面这些地方同样可能存在反序列化安全隐患,但很可能不常被关注到:
治病需要除根,能从根本上阻止反序列化安全问题的防御方案就是完整性校验,而最常见的例子之一就是JWT。
【更多序列化的问题请移步:https://tech.meituan.com/2015/02/26/serialization-vs-deserialization.html】。
版权说明 : 本文为转载文章, 版权归原作者所有 版权申明
原文链接 : https://blog.csdn.net/yeahPeng11/article/details/121034445
内容来源于网络,如有侵权,请联系作者删除!