new FileOutputStream("obj"));
out.writeObject(new C());
out.close();
ObjectInputStream oin = new ObjectInputStream(new FileInputStream(
"obj"));
C t = (C) oin.readObject();
oin.close();
System.err.println(t.b1 + ", " + t.b2 + ", " + t.c1 + ", " + t.c2);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
运行Test3的main方法,结果输出0, 100, 0, -100;即在子类的构造方法中对父类的成员变量的初始化没有被系列化;而反系列化时,则是调用父类的无参构造方法实例化父类。
【对敏感字段加密】
情境:服务器端给客户端发送序列化对象数据,对象中有一些数据是敏感的,比如密码字符串等,希望对该密码字段在序列化时,进行加密,而客户端如果拥有解密的密钥,只有在客户端进行反序列化时,才可以对密码进行读取,这样可以一定程度保证序列化对象的数据安全。
解决:在序列化过程中,虚拟机会试图调用对象类里的writeObject(ObjectOutputStread out) 和readObject(ObjectInputStread in) 方法(通过反射机制),进行用户自定义的序列化和反序列化,如果没有这样的方法,则默认调用是ObjectOutputStream 的defaultWriteObject 方法以及ObjectInputStream 的defaultReadObject 方法。用户自定义的writeObject 和readObject 方法可以允许用户控制序列化的过程,比如可以在序列化的过程中动态改变序列化的数值。基于这个原理,可以在实际应用中得到使用,用于敏感字段的加密工作,如:
view plain
package wen.hui.test.serializable;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectInputStream.GetField;
import java.io.Serializable;
/**
* @author whwang 2011-12-1 下午10:29:54
*/
public class D implements Serializable {
private static final long serialVersionUID = 1L;
private String password;
public D() {
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
// private void writeObject(ObjectOutputStream out) {
//
// }
private void readObject(ObjectInputStream in) {
try {
GetField readFields = in.readFields();
Object object = readFields.get("password", "");
System.err.println("要解密的字符串:" + object.toString());
password = "password";// 模拟解密,需要获得本地的密钥
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
view plain
package wen.hui.test.serializable;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
/**
* @ClassName: Test4
* @Description: 加密测试。
* @author whwang
* @date 2011-12-1 下午05:01:34
*
*/
public class Test4 {
public static void main(String[] args) {
try {
ObjectOutputStream out = new ObjectOutputStream(
new FileOutputStream("obj"));
D t1 = new D();
t1.setPassword("encryption");// 加密后的(模拟)
out.writeObject(t1);
out.close();
ObjectInputStream oin = new ObjectInputStream(new FileInputStream(
"obj"));
D t = (D) oin.readObject();
oin.close();