序列化概述
序列化: 将数据结构或对象转换成二进制字节流的过程
反序列化:将在序列化过程中所生成的二进制字节流转换成数据结构或者对象的过程
TCP/IP 四层模型
transient
transient 只能修饰变量,不能修饰类和方法。
transient 修饰的变量,在反序列化后变量值将会被置成类型的默认值。例如,如果是修饰 int 类型,那么反序列后结果就是 0。
static 变量因为不属于任何对象(Object),所以无论有没有 transient 关键字修饰,均不会被序列化。
为什么不推荐使用 JDK 自带的序列化?
-
不支持跨语言调用 : 如果调用的是其他语言开发的服务的时候就不支持了。
-
性能差 :相比于其他序列化框架性能更低,主要原因是序列化之后的字节数组体积较大,导致传输成本加大。
-
存在安全问题 :序列化和反序列化本身并不存在问题。但当输入的反序列化的数据可被用户控制,那么攻击者即可通过构造恶意输入,让反序列化产生非预期的对象,在此过程中执行构造的任意代码。
class JdkSerialize {
public static void serializePerson(Student student) throws FileNotFoundException, IOException {
ObjectOutputStream oo = new ObjectOutputStream(new FileOutputStream(
new File("F:/student.txt")));
oo.writeObject(student);
oo.close();
}
public static Student deserializePerson() throws IOException, Exception {
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(new File("F:/student.txt")));
Student student = (Student) ois.readObject();
return student;
}
public static void main(String[] args) {
Student student = new Student();
student.setId("123");
student.setName("方辰");
try {
// 序列化
JdkSerialize.serializePerson(student);
// 反序列化
Student serializeStudent = JdkSerialize.deserializePerson();
System.out.println(serializeStudent.getName()+";"+serializeStudent.getId());
} catch (Exception e) {
e.printStackTrace();
}
}
}
class Student implements Serializable {
private String id;
private String name;
public Student() {
}
public Student(String id, String name) {
this.id = id;
this.name = name;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}