【问题标题】: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对象序列化为字节数组并反序列化数组以获取原始对象
【发布时间】:2017-01-31 15:21:38
【问题描述】:

社区的问候,我最近在我的 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;
}

【问题讨论】:

标签: java arrays serialization deserialization notserializableexception


【解决方案1】:

如果您想控制对象的序列化方式,请实现 Externalizable 接口以及相关的 readExternal 和 writeExternal 方法。这使您可以完全控制对象的序列化方式。

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

【讨论】:

  • 感谢您的提示!
【解决方案2】:

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

【讨论】:

    【解决方案3】:

    您可以将Element 字段包装在Serializable 的类中,以便编写它们。此解决方案假定您能够在阅读后调用必要的设置器或构造器来重新创建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;
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2013-04-29
      • 2011-02-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多