Enterprise JavaBeans 入门
序 列 化
序列化并不是完全自动的
序列化必需要定制
自己试一下
Seems to work...
BankAccount account = getBankAccountHome().findById(42);
ObjectOutputStream out = new ObjectOutputStream(...);
out.writeObject(account);
out.close();
You should get an exception when you attempt to send a
message
ObjectInputStream in = new ObjectInputStream(...);
BankAccount account = (BankAccount)in.readObject();
in.close();
account.getBalance();
BankAccount account = getBankAccountHome().findById(42);
ObjectOutputStream out = new ObjectOutputStream(...);
out.writeObject(account.getHandle());
out.close();
ObjectInputStream in = new ObjectInputStream(...);
Handle handle = (Handle)in.readObject();
BankAccount account = (BankAccount)handle.getEJBObject();
in.close();
account.getBalance();
public class BankAccountBean implements EntityBean {
public int id;
public double balance;
public Customer owner;
...
}
public class CustomerBean implements EntityBean {
public int id;
public Vector accounts;
...
}
可序列化对象可以调整它序列化的方式
域可以被标记为 "transient"
"transient" 意味着 "不要序列化"
这些域在序列化时被忽略,在反序列化时为空
特殊的方法:
writeObject() - 为实例提供定制的序列化
readObject() - 为实例提供定制的反序列化
序列化未编码的口令是潜在的安全问题
考虑 User 类
可序列化
"password" 域被标记为 "transient"
import java.io.*;
public class User implements Serializable {
private String name;
private transient String password;
...
}
调用 defaultWriteObject() 来自动地序列化所有的 non-transient
域
自己处理特殊的域
private void writeObject(ObjectOutputStream out)
throws IOException {
out.defaultWriteObject();
out.writeObject(encode(getPassword()));
}
调用 defaultReadObject() 来自动地反序列化所有的 non-transient
域
自己处理特殊的域
private void readObject(ObjectInputStream in)
throws ClassNotFoundException, IOException {
in.defaultReadObject();
setPassword(decode((String)in.readObject()));
}
Handle 可以作为 Bean 引用序列化的替代
但是... 哪个类应该来实现定制的序列化呢?
Bean 类本身不序列化
我们也不能扩展 Vector 类
通常总是需要的
中间对象可以提供定制的序列化
private void writeObject(ObjectOutputStream out)
throws IOException {
out.defaultWriteObject();
out.writeObject(getBean().getHandle());
}
serialVersionUID 域是不同版本间兼容的标记
例如:
创建一个类的实例
序列化它
修改此类 (添加/删除 non-static 域)
反序列化
发生了什么?
不兼容版本的异常被抛出
同一个类的不兼容版本有不同的 serialVersionUID
如果您不提供一个值,将回自动产生一个
生成的值是基于类的"形状"
如果值匹配,反序列化过程将为存在的域尽量提供值
只有同时存在于两个版本的域才会被恢复
当前版本所没有的域被忽略
当前版本新出现的域被置空
SerialVer 工具可以用来生成一个 id
id 存放在 static final 的域中
public class BankAccount implements Serializable {
static final long serialVersionUID = 3206093459760846163L;
...
}
readObject() 和 writeObject() 可以用来提供定制的序列化功能
That references between beans are possible--But that they
must be managed
serialVersionUID 被用来表明类的不同版本间的兼容性