简体   繁体   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

Greetings to the community, I recently came up with an issue in serialization and deserialization in my java project.向社区问好,我最近在我的 java 项目中提出了序列化和反序列化的问题。 I have an object of a class containing other objects as fields .我有一个包含其他对象作为一个字段的一个对象

I would like to store the state of the object into a byte array and then deserialize the byte array and get back the original object .However,the objects consisting my object's fields are not Serializable(came from third party library) so had to declare them as transient in first place.我想将对象的状态存储到一个字节数组中,然后反序列化字节数组并取回原始对象。但是,组成我的对象字段的对象不是可序列化的(来自第三方库),因此必须声明它们首先是短暂的。

Now my object is serialized and deserialized but as was to be expected it's fields are null because of the transient declaration i mentioned before.I have tried to create locally into my Serialization class all the elements and assign to them the original ones values and continue the process but it didnt had any difference.现在我的对象被序列化和反序列化,但正如预期的那样,由于我之前提到的瞬态声明,它的字段为空。过程,但没有任何区别。 I quote below part of my code, Any ideas ?我在下面引用了我的代码的一部分,有什么想法吗? Thanks beforehand :)预先感谢:)

Here is the class of my object with it's fields这是我的对象的类及其字段

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;
}

Here is my Serializer function这是我的序列化程序功能

 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;
}

Here is my Deserializer function这是我的解串器功能

 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;
}

If you want control over how an object is Serialized, implement the Externalizable interface and the associated readExternal and writeExternal methods.如果您想控制对象的序列化方式,请实现 Externalizable 接口和关联的 readExternal 和 writeExternal 方法。 This gives you full control over how an object is serialized.这使您可以完全控制对象的序列化方式。

Clearly you can't serialize a class that contains fields that are not serializable.显然,您无法序列化包含不可序列化字段的类。 But you can perhaps write enough data to recreate the objects on your own.但是您也许可以编写足够的数据来自己重新创建对象。

If you are able to copy the values needed into new Serializable CustomElement objects inside your class, it should make a difference.如果您能够将所需的值复制到您的类中的新 Serializable CustomElement 对象中,那么它应该会有所作为。 Use copy constructors ( if available), or even reflection if you have enough information available.使用复制构造函数(如果可用),如果您有足够的可用信息,甚至可以使用反射。

You could wrap your Element fields in a class that is Serializable so that you can write them.您可以将Element字段包装在一个可Serializable的类中,以便您可以编写它们。 This solution assumes you're able to call the necessary setters or constructor to recreate the Element after you read it.此解决方案假定您能够在阅读后调用必要的 setter 或构造函数来重新创建Element

Here is an example:下面是一个例子:

Very basic Element that is not Serializable不可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;
    }
}

Now a very basic wrapper class that is Serializable现在是一个非常基本的包装类,它是可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;
     }
}

Finally a main class to run the serializing and deserializing logic (slightly modified from what you posted) :最后是一个运行序列化和反序列化逻辑的主类(根据您发布的内容稍作修改):

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.

相关问题 Java 可序列化对象到字节数组 - Java Serializable Object to Byte Array 通过网络和字节数组序列化/反序列化Java对象 - Serialize/Deserialize Java object through network and byte array 如何将Httpclient的响应object序列化和反序列化为字节数组 - How to serialize & deserialize response object of Httpclient into byte array 如何使用 Jackson 和包装器 object 反序列化/序列化字节数组 - how to deserialize / serialize byte array using Jackson and wrapper object 如何将不可序列化的对象转换为字节数组? - How to convert a non serializable object to byte array? Java:如何将对象序列化为字节数组,且输出字节越少越好? - Java: how to serialize object into byte array with as few output bytes as possible? 如何在Java中使用紧凑字节将对象序列化为字节数组 - How to Serialize object to byte array with compact bytes in java 为什么java.util.Optional不可序列化,如何序列化object有这些字段 - Why java.util.Optional is not Serializable, how to serialize the object with such fields Java可序列化对象到字节数组到文件在文件开头有垃圾 - Java serializable object to byte array to file has garbage at the beginning of the file 如何在不实现Serializable接口的情况下序列化/反序列化对象? - How to Serialize/Deserialize an object without implementing Serializable interface?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM