簡體   English   中英

如何將內部沒有 Serializable 字段的 java 對象序列化為字節數組並反序列化該數組以獲取原始對象

[英]How to serialize a java object with not Serializable fields inside it into byte array and deserialize the array to get the original object

向社區問好,我最近在我的 java 項目中提出了序列化和反序列化的問題。 我有一個包含其他對象作為一個字段的一個對象

我想將對象的狀態存儲到一個字節數組中,然后反序列化字節數組並取回原始對象。但是,組成我的對象字段的對象不是可序列化的(來自第三方庫),因此必須聲明它們首先是短暫的。

現在我的對象被序列化和反序列化,但正如預期的那樣,由於我之前提到的瞬態聲明,它的字段為空。過程,但沒有任何區別。 我在下面引用了我的代碼的一部分,有什么想法嗎? 預先感謝:)

這是我的對象的類及其字段

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 接口和關聯的 readExternal 和 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;
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM