【问题标题】:Java serialization: readFields() beyond of readObject()?Java 序列化:readFields() 超出 readObject()?
【发布时间】:2015-07-31 09:40:13
【问题描述】:

ObjectInputStream.readFields() 仅适用于 private void readObject(ObjectInputStream) 方法。

public ObjectInputStream.GetField readFields() throws IOException, ClassNotFoundException {
  SerialCallbackContext ctx = curContext;
  if (ctx == null) {
    throw new NotActiveException("not in call to readObject");
  }
...

我无法使用默认序列化来读取对象(即ObjectInputStream.defaultReadObject())并且不希望在我的所有类中实现readObject() 方法。在理想情况下,我希望有 ownDefaultReadObject() 方法,该方法将从序列化字段(例如通过反射)构造新对象。

有什么想法吗?

如果有人想了解更多。我的一些类中的字段名称被重命名(例如通过混淆器)为 a、b、c 等。这些类使用默认的 Java 序列化使用重命名的字段进行序列化。我需要将它们反序列化为原始类(我知道每个类的字段名称对;a=> fieldName、b=> age、c=>gender 等)。

【问题讨论】:

  • 您的愿望是一回事,但您的原因是什么?不执行readObject()
  • 我不是在质疑您的选择,但是实现将调用委托给自定义处理程序的readObject() 不会更容易吗?这样,即使您需要在每个类中实现该方法,实现也只是一个方法调用。
  • @EJP 16:我有数百个这样的课程。将来可以添加/删除它们。我不希望开发中的任何人。团队甚至会想到序列化/反序列化问题。我必须使用字节码检测(例如 Javassist)在构建过程中添加 readObject() 方法的选项之一,但想使用更简单的解决方案。
  • @biziclop:是的,我正在考虑这个解决方案,但使用字节码检测。希望存在一个更容易的。
  • @FoxyBOA 我会说可能没有更简单的解决方案。但这只是基于序列化工作的一般方式的猜测,可能有一个不太可能的钩子可以附加这个逻辑。

标签: java serialization deserialization obfuscation objectinputstream


【解决方案1】:

要重命名对象流中的字段,您需要覆盖的方法是ObjectInputStream.readClassDescriptor,它返回一个ObjectStreamClass

实例ObjectStreamClass 通过接口的不同子集履行两种不同角色之一。为免生疑问,不应复制此设计选择。

  • 描述在当前 JVM 实例中运行的可序列化类的字段。通过ObjectStreamClass.lookup找到这些实例。
  • 描述在特定序列化流中表示的可序列化类的字段。这些实例由ObjectInputStream.readClassDescriptor 的实现返回。

在您的覆盖电话super.readClassDescriptor 中。这将从流中读取数据。如果它是您感兴趣的类,则将流中的值替换为具有新字段名称的值。

如何创建自己的ObjectStreamClass?将您感兴趣的类的虚拟实例写入ObjectOutputStream。您可以将其作为构建的一部分,只保留二进制数据。读取另一个 ObjectInputStream 并覆盖 readClassDescriptor 以存储描述符。

ObjectInputStream.defaultReadObject/readFieldsreadObject (或类似的)之外没有任何意义,因为它们依赖于当前的反序列化对象而不是参数。还有其他限制可以防止其他代码调用 defaultReadObject 来重写必须保持不变、复制验证、安全检查或类似的字段。

【讨论】:

  • 我会写一些代码来做到这一点,但我现在正在做其他事情。对于原始海报和 Java 序列化来说可能有点晚了。 /(我最初在错误的问题上发布了这个答案,因为我是个白痴。)
  • 您可以使用反射来分配变量,查看我的解决方案
猜你喜欢
  • 2010-11-13
  • 1970-01-01
  • 2015-08-18
  • 2011-08-20
  • 2013-01-22
  • 1970-01-01
  • 2019-01-29
  • 2018-07-22
  • 2023-03-21
相关资源
最近更新 更多