替换序列化数据中的类名

Chr*_*ney 7 java refactoring serialization

我想在序列化数据流中用"com.newPackage.className"替换字符串"com.oldpackage.className".从DB读取此序列化数据并在替换字符串后更新.

我在做同样的事情时遇到了一些问题.如果您已经猜到了,这是重构练习的一部分.是否有任何库可以帮助我操作序列化数据?如果您还可以请注意任何预防措施或警告,这将是非常有帮助的.

非常感谢,克里斯.PS:旧类和新类都不会将serialversion ID声明为其字段的一部分.

小智 6

为了准确汤姆霍廷的答复,我设法使用以下代码实现它:

public static ObjectInputStream getSwapOIS( InputStream in ,String fromClass,String toClass)
    throws IOException ,ClassNotFoundException {
    final String from="^"+fromClass,fromArray="^\\[L"+fromClass,toArray="[L"+toClass;
    return new ObjectInputStream(in) {
        protected Class<?> resolveClass(ObjectStreamClass desc)
            throws IOException, ClassNotFoundException
        {
            String name = desc.getName().replaceFirst(from, toClass);
            name = name.replaceFirst(fromArray, toArray);
            return Class.forName(name);
        }
        protected ObjectStreamClass readClassDescriptor()
            throws IOException, ClassNotFoundException
        {
            ObjectStreamClass cd = super.readClassDescriptor();
            String name = cd.getName().replaceFirst(from, toClass);
            name = name.replaceFirst(fromArray, toArray);
            if(!name.equals(cd.getName())) {
                cd = ObjectStreamClass.lookup(Class.forName(name));
            }
            return cd;
        }
    };
}
Run Code Online (Sandbox Code Playgroud)

请注意,您还需要覆盖 readClassDescriptor()。它适用于标准类型和数组,您甚至可以更改类名而不仅仅是包名。做就是了:

 InputStream in = new ByteArrayInputStream(classBytes);
 ObjectInputStream ois = getSwapOIS(    in,
                                        "com.oldpackage.className",
                                        "com.newpackage.newClassName");
 Object myObject= ois.readObject();
Run Code Online (Sandbox Code Playgroud)


Ale*_*exR 5

我不知道如何做你正在尝试但我可以建议你"合法"的解决方案.在类路径中实现包含旧包和新包的转换器,并执行以下操作:从DB读取数据,使用旧包对其进行反序列化,在Java中将旧实例转换为new,然后再将新数据存储在DB中.

此解决方案需要执行一些脏工作,但它是安全的.此外,结果可能在将来重复使用.但我祝你好运,找到只替换序列化数据中的类名的解决方案.