如何从byte []反序列化对象,其中byte []表示通过网络加载的类的对象?

时间:2019-04-10 20:32:35

标签: java

如何从byte []反序列化对象,其中byte []表示通过网络加载的类的对象?

我有以下Hello.java文件

import java.io.Serializable;

public class Hello implements Serializable {

    public Integer hello = 5;

    public static void main(String... args) {
        System.out.println(sayHello());
    }

    public static String sayHello() {
        return "Hello world";
    }
}

将其编译为Hello.class并存储在/tmp/test

下面是一个与我正在处理的应用程序类似的示例。

public class Util {

    public static byte[] serializeObject(Object object) throws Exception {
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
        objectOutputStream.writeObject(object);
        objectOutputStream.close();
        byteArrayOutputStream.close();
        return byteArrayOutputStream.toByteArray();
    }

    public static Object deserializeObject1(byte[] serializedObject) throws Exception {
        ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(serializedObject);
        ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream);
        Object object = objectInputStream.readObject();
        objectInputStream.close();
        byteArrayInputStream.close();
        return object;
    }

    public static Object deserializeObject2(byte[] byteArray) {
        ByteArrayInputStream bis = new ByteArrayInputStream(byteArray);
        ObjectInput input = null;
        try {
            input = new ObjectInputStream(bis){
                @Override protected Class<?> resolveClass(final ObjectStreamClass desc) throws IOException, ClassNotFoundException {
                    ClassLoader cl = Thread.currentThread().getContextClassLoader();
                    if (cl == null)  return super.resolveClass(desc);
                    return Class.forName(desc.getName(), false, cl);
                }
            };
            return input.readObject();
        } catch (ClassNotFoundException | IOException e) {
            e.printStackTrace();
            return null;
        } finally {
            try {
                bis.close();
                if (input != null)
                    input.close();
            } catch (IOException ex) {
                ex.printStackTrace();
                return null;
            }
        }
    }
}

这是我的主要应用

public class Dynamic {

     private ObjectMapper jsonMapper = new ObjectMapper();

     public static void main(String[] args) {

         File myFile=new File("/tmp/test/");

         try {
            URLClassLoader  cl = new URLClassLoader(new URL[]{myFile.toURI().toURL()});
            Class klazz = cl.loadClass("Hello");
            Object object = klazz.getDeclaredConstructor().newInstance();
            System.out.println(jsonMapper.writeValueAsString(object)); //works
            byte[] serObjectbytes  = Util.serializeObject(object);
            System.out.println(Arrays.toString(serObjectbytes)); // works
            Object deserializeObject = Util.deserializeObject1(serObjectbytes); //fails
            Object deserializeObject2 = Util.deserializeObject2(serObjectbytes); // also fails
  System.out.println(jsonMapper.writeValueAsString(deserializeObject));
        } catch (ClassNotFoundException esx) {
            esx.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
     }

}

所以Util.deserializeObject1Util.deserializeObject1都因ClassNotFoundException ex而失败我知道我正在尝试反序列化字节,而Java类加载器对{{1}的位置一无所知},除非再次Hello.class,否则我的目标是反序列化为defineClass对象,并重新填充为与序列化之前相同的状态。我该怎么办?

0 个答案:

没有答案