如何序列化一个java对象,其中不序列化字段到字节数组和反序列化数组,以获得原始对象



向社区致敬,我最近在我的java项目中遇到了序列化和反序列化的问题。我有一个对象包含其他对象作为字段

我想将对象的状态存储到一个字节数组中,然后对字节数组进行反序列化并返回原始对象。但是,组成我的对象字段的对象是不可序列化的(来自第三方库),因此必须首先将它们声明为transient。

现在我的对象被序列化和反序列化,但正如预期的那样,由于我之前提到的瞬态声明,它的字段为空。我已经尝试在本地创建我的序列化类的所有元素,并分配给他们的原始值,并继续这个过程,但它没有任何区别。我引用下面我的代码的一部分,有什么想法吗?事先谢谢:)

这是我的对象的类和它的字段

public class AbePublicKey implements java.io.Serializable{
private static final long serialVersionUID = 7526472295622776147L;
public transient  Element g;
public transient Element h;
public transient Element f;
public transient Element e_g_g_hat_alpha;
}

这是我的序列化函数

 public  byte[] PublicKeytoByteArray(AbePublicKey publickey) throws IOException {
   KeyAuthority keyauthority = new KeyAuthority();
    byte[] bytes = null;
    ByteArrayOutputStream bos = null;
    ObjectOutputStream oos = null;
    publickey.setElements(g, h, f, e_g_g_hat_alpha);
    try {
        bos = new ByteArrayOutputStream();
        oos = new ObjectOutputStream(bos);
        oos.writeObject(publickey);
        oos.flush();
        bytes = bos.toByteArray();
    } finally {
        if (oos != null) 
            oos.close();
        }
        if (bos != null) {
            bos.close();
        }
    }
    return bytes;
}

这是我的反序列化函数

 public static AbePublicKey PublicKeyBytestoObject(byte[] publickeybytes) throws IOException, ClassNotFoundException {
    AbePublicKey obj = null;
    ByteArrayInputStream bis = null;
    ObjectInputStream ois = null;
    try {
        bis = new ByteArrayInputStream(publickeybytes);
        ois = new ObjectInputStream(bis);
        obj = (AbePublicKey) ois.readObject();
    } finally {
        if (bis != null) {
            bis.close();
        }
        if (ois != null) {
            ois.close();
        }
    }
    return obj;
}

如果你想控制一个对象是如何序列化的,实现Externalizable接口和相关的readeexternal和writeExternal方法。这使您可以完全控制对象的序列化方式。

显然你不能序列化一个包含不可序列化字段的类。但是您也许可以编写足够的数据来自己重新创建对象。

如果您能够将所需的值复制到您的类中的新的Serializable CustomElement对象中,那么它应该会有所不同。使用复制构造函数(如果可用),如果有足够的信息,甚至可以使用反射。

您可以将Element字段包装在Serializable类中,以便您可以编写它们。这个解决方案假设您能够调用必要的setter或构造函数来重新创建Element后,您读取它。

下面是一个例子:

Serializable的基本元素

public class Element {
    private String value;
    public Element(){
        value = null;
    }
    public Element(String value){
        setValue(value);
    }
    public void setValue(String value){
        this.value = value;
    }
    public String getValue(){
        return value;
    }
}
现在是一个非常基本的包装器类Serializable
import java.io.IOException;
import java.io.ObjectStreamException;
import java.io.Serializable;
public class SerializableElement implements Serializable{
    // Generated ID
    private static final long serialVersionUID = -6751688345227423403L;
    private transient Element element;
    public SerializableElement(Element el)
    {
        element = el;
    }
    private void writeObject(java.io.ObjectOutputStream out)
             throws IOException{
        out.writeObject(element.getValue());
    }
     private void readObject(java.io.ObjectInputStream in)
         throws IOException, ClassNotFoundException{
         String elementValue = (String)in.readObject();
         element = new Element(elementValue);
     }
     private void readObjectNoData()
         throws ObjectStreamException{
         element = null;
     }
     public Element getElement(){
         return element;
     }
}

最后一个运行序列化和反序列化逻辑的主类(从你发布的稍微修改):

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
public class SerializeMain {
    public static void main(String[] args) {
        SerializableElement serializableElement = new SerializableElement(
                new Element("test value"));
        try {
            byte[] serializedData = storeElement(serializableElement);
            SerializableElement loadedElement = loadElement(serializedData);
            System.out.println("loadedElement.element.value: "
                    + loadedElement.getElement().getValue());
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
    public static byte[] storeElement(SerializableElement sElement)
            throws IOException {
        byte[] bytes = null;
        ByteArrayOutputStream bos = null;
        ObjectOutputStream oos = null;
        try {
            bos = new ByteArrayOutputStream();
            oos = new ObjectOutputStream(bos);
            oos.writeObject(sElement);
            oos.flush();
            bytes = bos.toByteArray();
        } finally {
            if (oos != null) {
                oos.close();
            }
            if (bos != null) {
                bos.close();
            }
        }
        return bytes;
    }
    public static SerializableElement loadElement(byte[] byteData)
            throws IOException, ClassNotFoundException {
        SerializableElement obj = null;
        ByteArrayInputStream bis = null;
        ObjectInputStream ois = null;
        try {
            bis = new ByteArrayInputStream(byteData);
            ois = new ObjectInputStream(bis);
            obj = (SerializableElement) ois.readObject();
        } finally {
            if (bis != null) {
                bis.close();
            }
            if (ois != null) {
                ois.close();
            }
        }
        return obj;
    }
}

相关内容

  • 没有找到相关文章

最新更新