Java Serializable系列化与反系列化(四)

2014-11-24 03:19:37 · 作者: · 浏览: 2
System.err.println("解密后的字符串:" + t.getPassword());

} catch (FileNotFoundException e) {

e.printStackTrace();

} catch (IOException e) {

e.printStackTrace();

} catch (ClassNotFoundException e) {

e.printStackTrace();

}

}

}

在系列化之前,将密码字段加密,然后系列化到硬盘,在反系列化时,通过类D中的readObject(ObjectInputStream in)做解密操作,确保了数据的安全。

如:RMI 技术是完全基于Java 序列化技术的,服务器端接口调用所需要的参数对象来至于客户端,它们通过网络相互传输。这就涉及RMI 的安全传输的问题。一些敏感的字段,如用户名密码(用户登录时需要对密码进行传输),我们希望对其进行加密,这时,就可以采用本节介绍的方法在客户端对密码进行加密,服务器端进行解密,确保数据传输的安全性。

【序列化存储规则】

请看如下代码:

view plain

package wen.hui.test.serializable;

import java.io.File;

import java.io.FileInputStream;

import java.io.FileNotFoundException;

import java.io.FileOutputStream;

import java.io.IOException;

import java.io.ObjectInputStream;

import java.io.ObjectOutputStream;

/**

*

* @author whwang 2011-12-1 下午11:00:35

*/

public class Test5 {

public static void main(String[] args) {

ObjectOutputStream out;

try {

out = new ObjectOutputStream(new FileOutputStream(

"obj"));

A t = new A();

// 试图将对象两次写入文件

out.writeObject(t);

out.flush();

System.err.println("加入第一个类:" + new File("obj").length());

//t.a = 10;

out.writeObject(t);

out.close();

System.err.println("加入第二个类:" + new File("obj").length());

ObjectInputStream oin = new ObjectInputStream(new FileInputStream(

"obj"));

// 从文件依次读出两个文件

A t1 = (A) oin.readObject();

A t2 = (A) oin.readObject();

oin.close();

// 判断两个引用是否指向同一个对象

System.err.println(t1 == t2);

} catch (FileNotFoundException e) {

e.printStackTrace();

} catch (IOException e) {

e.printStackTrace();

} catch (ClassNotFoundException e) {

e.printStackTrace();

}

}

}

对同一对象两次写入文件,打印出写入一次对象后的存储大小和写入两次后的存储大小,然后从文件中反序列化出两个对象,比较这两个对象是否为同一对象。一般的思维是,两次写入对象,文件大小会变为两倍的大小,反序列化时,由于从文件读取,生成了两个对象,判断相等时应该是输入false 才对。但实际结果是:第二次写入对象时文件只增加了5 字节,并且两个对象是相等的,这是为什么呢?

解答:Java 序列化机制为了节省磁盘空间,具有特定的存储规则,当写入文件的为同一对象时(根据包名+类名),并不会再将对象的内容进行存储,而只是再次存储一份引用,上面增加的5 字节的存储空间就是新增引用和一些控制信息的空间。反序列化时,恢复引用关系,使得程序 中的t1 和t2 指向唯一的对象,二者相等,输出true,该存储规则极大的节省了存储空间。

但需要注意,在上面程序中将//t.a = 10注释打开,执行的结果也一样。 原因就是第一次写入对象以后,第二次再试图写的时候,虚拟机根据引用关系知道已经有一个相同对象已经写入文件,因此只保存第二次写的引用,所以读取时,都是第一次保存的对象

作者 SMCwwh