0、背景
当两个进程在进行远程通信时,彼此可以发送各种类型的数据。无论是何种类型的数据,都会以二进制序列的形式在网络上传送。发送方需要把这个Java对象转换为字节序列,才能在网络上传送;接收方则需要把字节序列再恢复为Java对象。
本文主要对几种常见Java序列化方式进行实现。包括Java原生以流的方法进行的序列化、Json序列化、FastJson序列化、Protobuff序列化、Hessian序列化和Kyro序列化。
1、java原生序列化方式
这种方式只能将支持 java.io.Serializable
接口的对象写入流中。每个 serializable 对象的类都被编码,编码内容包括类名和类签名、对象的字段值和数组值,以及从初始对象中引用的其他所有对象的闭包。
java.io.ObjectOutputStream
代表对象输出流,它的writeObject(Object obj)
方法可对参数指定的obj对象进行序列化,把得到的字节序列写到一个目标输出流中。只有实现了Serializable
和Externalizable
接口的类的对象才能被序列化。
java.io.ObjectInputStream
代表对象输入流,它的readObject()
方法从一个源输入流中读取字节序列,再把它们反序列化为一个对象,并将其返回。
import java.io.*;
import java.util.Date;
public class ObjectSaver {
public static void main(String[] args) throws Exception {
/*其中的 ./objectFile.obj 表示存放序列化对象的文件*/
//序列化对象
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("./objectFile.obj"));
Customer customer = new Customer("小韩", 24);
out.writeObject("你好!"); //写入字面值常量
out.writeObject(new Date()); //写入匿名Date对象
out.writeObject(customer); //写入customer对象
out.close();
//反序列化对象
ObjectInputStream in = new ObjectInputStream(new FileInputStream("./objectFile.obj"));
System.out.println("obj1 " + (String) in.readObject()); //读取字面值常量
System.out.println("obj2 " + (Date) in.readObject()); //读取匿名Date对象
Customer obj3 = (Customer) in.readObject(); //读取customer对象
System.out.println("obj3 " + obj3);
in.close();
}
}
class Customer implements Serializable {
private String name;
private int age;
public Customer(String name, int age) {
this.name = name;
this.age = age;
}
public String toString() {
return "name=" + name + ", age=" + age;
}
}
2、json序列化
Json
序列化一般会使用jackson
包,通过ObjectMapper
类来进行一些操作,比如将对象转化为byte
数组或者将json
串转化为对象。现在的大多数公司都将json
作为服务器端返回的数据格式。比如调用一个服务器接口,通常的请求为xxx.json?a=xxx&b=xxx
的形式。Json
序列化示例代码如下所示:
package serialize;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import com.fasterxml.jackson.databind.ObjectMapper;
/**
*
* @author liqqc
*
*/
public class JsonSerialize {
public static void main(String[] args) throws IOException {
new JsonSerialize().start();
}
public void start() throws IOException {
User u = new User();
List<User> friends = new ArrayList<>();
u.setUserName("张三");
u.setPassWord("123456");
u.setUserInfo("张三是一个很好的人");
u.setFriends(friends);
User f1 = new User