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