我目前正在开发客户端/服务器应用程序。应用程序服务器是Glassfish v3,通过远程EJB进行通信。主要问题是序列化对象图时网络带宽的使用。例如,在下一个方法中:
@Stateless
public class MyEJB extends MyRemoteInterface {
@Override
public PurchaseOrder savePurchaseOrder( PurchaseOrder po ) { ... }
}
这个方法,当远程调用时,将接收一个PurchesOrder实例,该实例是一个对象图,当通过网络传输时,它将需要大量的KB,返回时也是如此。
我已经管理了这个,现在,改变这个方法的原型:
...
@Override
public byte[] savePurchaseOrder( byte[] po ) { ... }
...
我在通过网络传输之前和之后手动解压缩/取消/序列化PurchaseOrder实例。但是我放松了类型安全的方法而且它变得丑陋。
有没有办法在默认的序列化过程中使用java自定义序列化来压缩输出流?例如:
@Entity
public class PurchaseOrder implements Serializable {
private void writeObject(ObjectOutputStream oos) throws IOException {
// default serialization
oos.defaultWriteObject();
// COMPRESS STREAM HERE (zip or gzip)
}
private void readObject(ObjectInputStream ois)
throws ClassNotFoundException, IOException {
// DECOMPRES STREAM HERE
// default deserialization
ois.defaultReadObject();
}
}
我需要“DE / COMPRESS STREAM HERE”部分的代码或其他好主意。
提前感谢您的建议。
济。
答案 0 :(得分:2)
使用自定义序列化的一些建议很好,但根据您的对象可能会有很多工作。你可以使用泛型和包装类来获得“有点”更好的实现。
“简单”实现可能如下所示:
public class ShrinkWrap<E> implements Serializable
{
private transient E _value;
public ShrinkWrap(E value) { _value = value; }
public E get() { return _value; }
private void writeObject(ObjectOutputStream oos) throws IOException {
// default serialization
oos.defaultWriteObject();
// compress _value to a byte[] using new ObjectOutputStream(new GZIPOutputStream(new ByteArrayOutputStream()))
byte[] compValue = ...;
oos.writeInt(compValue.length);
oos.write(compValue);
}
@SuppressWarnings("unchecked")
private void readObject(ObjectInputStream ois) throws ClassNotFoundException, IOException {
// default deserialization
ois.defaultReadObject();
byte[] compValue = new byte[ois.readInt()];
ois.readFully(compValue);
// decompress _value from byte[] using new ObjectInputStream(new GZIPInputStream(new ByteArrayInputStream()))
_value = ...;
}
}
答案 1 :(得分:1)
我建议你需要提供一个能够自动压缩/解压缩流的自定义工厂
尝试阅读http://docs.oracle.com/javase/7/docs/technotes/guides/rmi/socketfactory/index.html
答案 2 :(得分:0)
您可以使用DeflatorOutputStream和InflatorInputStream来压缩流。
如果可以,我建议使用更紧凑的序列化格式,如JSon,Exernalizable或您自己的二进制格式。这是因为默认的Java序列化相对冗长。例如一个整数使用超过80个字节。
答案 3 :(得分:0)
我认为上帝的想法是使用ZipOutputStream and ZipInputStream
。您可以选择压缩对象的级别并在一个文件中发送多个对象。
答案 4 :(得分:0)
看看JBoss Serialization,值得一看,也许可以帮到你。