一、序列化
-
序列化是将对象转换为一系列字节,以便可以将对象轻松保存到持久性存储中或通过通信链接进行流传输。然后可以将字节流反序列化-转换为原始对象的副本。
-
将内存的对象存入数据库中jdbc也会经过序列化过程
-
序列化协议:二进制,xml,json等常用序列化协议
-
序列化通常意味着将数据写入字符串(例如:xml / json)或原始二进制文件(a byte[]等)。反序列化是相反的过程。获取原始数据(从文件,传入的网络套接字等)并重建对象模型。 序列化意味着将对象持久化为表示形式,然后将其存储在某个位置。一种方法是将指针带到对象在内存中的存储位置,然后将每个字节原样写入文件。由于该表示形式非常特定于您的编程语言(以及它如何表示内存中的对象),因此可以将您的对象转换为具有某种众所周知的结构(例如XML或JSON)的String形式标识,以便您能够
- 更容易转移
- 易于存储和还原
- 由于每个人都知道格式的定义,因此任何其他程序也可以读取您的对象
二、反序列化
- 反序列是将字节流,或者字符串(json/xml)的对象信息,重构回一个对象,恢复对象状态
三、为什么需要序列化
- 所有可在网络上传输的对象都必须是可序列化的(用于分布式远程调用RMI)
- 网络传输都是二进制流,json和xml文本类型,最终也会转成二进制流传输。
- 可以用于对象的拷贝
四、java原生序列化
-
Java提供了一种称为对象序列化的机制,该机制可以将对象表示为字节序列,其中包括对象的数据以及有关对象的类型和存储在对象中的数据类型的信息。
-
将序列化的对象写入文件后,可以从文件中读取并反序列化它,即表示对象及其数据的类型信息和字节可用于在内存中重新创建对象。 java 提供自动序列化方式,需要以java.io.Serializable接口的实例来标明对象。实现接口将类别标明为“可序列化”,然后Java在内部处理序列化
-
java序列化是通过对象输出流(ObjectOutputStream)和输入流(ObjectInputStream)来保存和重构对象。
-
java原生序列化实例
-
创建实体类
@Data public class Student implements Serializable{ private static final long serialVersionUID = -6030544531566575863L; private String id; private String name; @JsonDeserialize(using = LocalDateTimeDeserializer.class) @JsonSerialize(using = LocalDateTimeSerializer.class) private LocalDateTime createTime; } -
序列化到本地磁盘中
Student student = new Student(); student.setId("88888"); student.setName("小丹"); student.setCreateTime(LocalDateTime.now()); try { //ObjectOutputStream能把Object输出成Byte流 ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("C:\\Desktop\\student.md")); out.writeObject(student); out.close(); } catch (IOException e) { e.printStackTrace(); } -
序列化后的十六进制文件
//文件中包含了序列化协议,版本,类名,序列化ID,对象属性等信息 aced 0005 7372 0017 636f 6d2e 7465 7374 2e64 6f6d 6169 6e2e 5374 7564 656e 74ac 4f33 b321 ccbf 0902 0003 4c00 0a63 7265 6174 6554 696d 6574 0019 4c6a 6176 612f 7469 6d65 2f4c 6f63 616c 4461 7465 5469 6d65 3b4c 0002 6964 7400 124c 6a61 7661 2f6c 616e 672f 5374 7269 6e67 3b4c 0004 6e61 6d65 7100 7e00 0278 7073 7200 0d6a 6176 612e 7469 6d65 2e53 6572 955d 84ba 1b22 48b2 0c00 0078 7077 0e05 0000 07e3 0b1a 0b0c 393b 7c45 8078 7400 0538 3838 3838 7400 06e5 b08f e4b8 b9 -
反序列化
try { ObjectInputStream in = new ObjectInputStream(new FileInputStream("C:\\Users\\jrkj-kaifa01\\Desktop\\student.md")); Student student = (Student) in.readObject(); log.info(student.toString()); } catch (IOException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } }
-
-
java原生序列化缺点:
- 不支持跨语言操作,由于 Java 序列化技术是 java原生序列化的内部协议,导致其他语言无法对接和识别
- 性能太低
五、xml文本序列化
-
以前XML格式是行业的标准,因为它可扩展,XML Scheme定义了它的数据结构,很容易创建新的结构,非常适合数据存储
-
XML是一种常用的序列化和反序列化协议,具有跨机器,跨语言等优点(银行系统的数据交互还是用xml格式)
-
xml文本序列化实例
- 导入XStream依赖,是一个Java对象与XML互相转换的工具类库
<dependency> <groupId>com.thoughtworks.xstream</groupId> <artifactId>xstream</artifactId> <version>1.4.10</version> </dependency> - xml序列化
Student student = new Student(); student.setId("88888"); student.setName("小丹"); student.setCreateTime(LocalDateTime.now()); //创建解析XML对象 XStream xStream = new XStream(); //设置别名,不设置会输出全路径 xStream.alias("student", Student.class); //转为xml System.out.println(xStream.toXML(student));- 序列化后的xml格式
<student> <id>88888</id> <name>小丹</name> <createTime>2019-11-29T09:41:31.154</createTime> </student>- 反序列化
String stu = "<student>\n" + " <id>88888</id>\n" + " <name>小丹</name>\n" + " <createTime>2019-11-29T09:41:31.154</createTime>\n" + "</student>"; XStream xStream = new XStream(); xStream.alias("student", Student.class); Student student = (Student) xStream.fromXML(stu); log.info(student.toString()); - 导入XStream依赖,是一个Java对象与XML互相转换的工具类库
-
XML序列化缺点:
- xml文本类型多数用于配置文件,用xml来序列对象,显得冗长而复杂
- XML的序列化和反序列化的空间和时间开销都比较大,对于效率不会太高。
六、json序列化
-
JSON(JavaScript对象表示法)是一种轻量级的数据交换格式,它完全独立于语言。它基于JavaScript编程语言,易于理解和生成。
-
现在越来越多趋于json格式数据交互,因为可以跟客户端进行无缝对接,更加容易解析处理。
-
JSON文本序列化实例
- 导入json序列化依赖,我用的是fastJSON 现在json序列化的工具类有很多(fastJson,jackson等)
<dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.49</version> </dependency> - 序列化
Student student = new Student(); student.setId("88888"); student.setName("小丹"); student.setCreateTime(LocalDateTime.now()); //序列化 String string = JSON.toJSONString(student); //{"createTime":"2019-11-29T10:17:07.916","id":"88888","name":"小丹"} log.info(string); //反序列化 Student parseStudent = JSON.parseObject(string, Student.class); // Student(id=88888, name=小丹, createTime=2019-11-29T10:17:07.916) log.info(parseStudent.toString()); - 导入json序列化依赖,我用的是fastJSON 现在json序列化的工具类有很多(fastJson,jackson等)
-
JSON序列化缺点:
- 反序列化的时候,必须将整个JSON反序列化成对象后才能进行读取,大家应该知道,Java对象尤其是层次嵌套较多的对象,占用的内存空间将会远远大于数据本身的空间
七、xml和json的对比
| JSON | XML |
|---|---|
| 这是JavaScript对象表示法 | 它是可扩展的标记语言 |
| 它基于JavaScript语言 | 它源自SGML |
| 这是一种表示对象的方式 | 它是一种标记语言,并使用标签结构表示数据项 |
| 它不提供对名称空间的任何支持 | 它支持名称空间 |
| 它支持数组 | 它不支持数组 |
| 它仅支持UTF-8编码 | 它支持各种编码 |
| 数据组成:object、array、string、number、boolean(true/false)和null | 数据组成:element、attribute和element content |