我使用以下类反序列化字符串,并将传入的类映射到不同包中的新类。
它们包含完全相同的属性(映射的等效项除外)和相同的串行版本uid。
public class CompatibilityImporter {
public void loadOldImport(final File f, final CompatibilityImportListener importListener, final String password) {
new Thread(new Runnable() {
@Override
public void run() {
try {
String oldExport = readFileAsString(f);
ObjectInputStream ois = new ClassNameMappingObjectInputStream(new ByteArrayInputStream(Base64.decode(oldExport, Base64.DEFAULT)));
ExportPackageCompat exportPackage = (ExportPackageCompat) ois.readObject();
importListener.onImportDone();
} catch (Exception e) {
Log.e(e, "Compatibility Import failed! ");
importListener.onImportError();
}
}
}).start();
}
public class ClassNameMappingObjectInputStream extends ObjectInputStream {
public Map<String, Class> classNameMapping = initclassNameMapping();
public ClassNameMappingObjectInputStream(InputStream in) throws IOException {
super(in);
initclassNameMapping();
}
protected ClassNameMappingObjectInputStream() throws IOException, SecurityException {
super();
initclassNameMapping();
}
private Map<String, Class> initclassNameMapping() {
Map<String, Class> res = new HashMap<String, Class>();
res.put("com.example.myapp.app.settings.backup.ExportPackage", ExportPackageCompat.class);
res.put("com.example.myapp.app.settings.backup.ExportPackage$SavedPhotoFile", SavedPhotoFileCompat.class);
// all the other model mappings
return Collections.unmodifiableMap(res);
}
@Override
protected java.io.ObjectStreamClass readClassDescriptor()
throws IOException, ClassNotFoundException {
ObjectStreamClass desc = super.readClassDescriptor();
Log.d("ObjectInputStream", "Reading descriptor -> " + desc);
if (classNameMapping.containsKey(desc.getName())) {
return ObjectStreamClass.lookup(classNameMapping.get(desc.getName()));
}
return desc;
}
}
}
出于某种原因,在某种程度上,desiarialisation过程似乎试图匹配不能合并的2个属性。
(尝试使用arraylist编写String属性电话。)
这是 Logcat:
22953-23138/com.example.myapp D/ObjectInputStream﹕ Reading descriptor ->
com.example.myapp.app.settings.backup.ExportPackage: static final long serialVersionUID =3985293256L;
22953-23138/com.example.myapp D/ObjectInputStream﹕ Reading descriptor -> java.util.ArrayList: static final long serialVersionUID =8683452581122892189L;
22953-23138/com.example.myapp D/ObjectInputStream﹕ Reading descriptor -> com.example.myapp.model.Crate: static final long serialVersionUID =-2892184805959193218L;
22953-23138/com.example.myapp D/ObjectInputStream﹕ Reading descriptor -> java.util.Date: static final long serialVersionUID =7523967970034938905L;
22953-23138/com.example.myapp D/ObjectInputStream﹕ Reading descriptor -> com.example.myapp.model.Shipment: static final long serialVersionUID =-2477342699440006438L;
22953-23138/com.example.myapp D/ObjectInputStream﹕ Reading descriptor -> com.example.myapp.model.Photo: static final long serialVersionUID =-3384005512499715344L;
22953-23138/com.example.myapp D/ObjectInputStream﹕ Reading descriptor -> com.example.myapp.app.settings.backup.ExportPackage$Extras: static final long serialVersionUID =4664556672506779299L;
22953-23138/com.example.myapp D/ObjectInputStream﹕ Reading descriptor -> [B: static final long serialVersionUID =-5984413125824719648L;
22953-23138/com.example.myapp D/ObjectInputStream﹕ Reading descriptor -> com.example.myapp.model.Shipment$ShipmentType: static final long serialVersionUID =0L;
22953-23138/com.example.myapp D/ObjectInputStream﹕ Reading descriptor -> java.lang.Enum: static final long serialVersionUID =0L;
22953-23138/com.example.myapp D/ObjectInputStream﹕ Reading descriptor -> com.example.myapp.model.Donut: static final long serialVersionUID =-5666180507659888627L;
22953-23138/com.example.myapp D/ObjectInputStream﹕ Reading descriptor -> com.example.myapp.model.DonutPackage: static final long serialVersionUID =5365476511704148082L;
22953-23138/com.example.myapp E/Apotheke﹕ Compatibility Import failed!
java.lang.ClassCastException: com.example.myapp.app.settings.backup.compatibility.CrateCompat.phone - class java.lang.String not compatible with class java.util.ArrayList
at java.io.ObjectInputStream.readFieldValues(ObjectInputStream.java:1151)
at java.io.ObjectInputStream.defaultReadObject(ObjectInputStream.java:455)
at java.io.ObjectInputStream.readObjectForClass(ObjectInputStream.java:1372)
at java.io.ObjectInputStream.readHierarchy(ObjectInputStream.java:1269)
at java.io.ObjectInputStream.readNewObject(ObjectInputStream.java:1858)
at java.io.ObjectInputStream.readNonPrimitiveContent(ObjectInputStream.java:787)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:2006)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:1963)
at java.util.ArrayList.readObject(ArrayList.java:661)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:525)
at java.io.ObjectInputStream.readObjectForClass(ObjectInputStream.java:1357)
at java.io.ObjectInputStream.readHierarchy(ObjectInputStream.java:1269)
at java.io.ObjectInputStream.readNewObject(ObjectInputStream.java:1858)
at java.io.ObjectInputStream.readNonPrimitiveContent(ObjectInputStream.java:787)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:2006)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:1963)
at java.io.ObjectInputStream.readFieldValues(ObjectInputStream.java:1140)
at java.io.ObjectInputStream.defaultReadObject(ObjectInputStream.java:455)
at java.io.ObjectInputStream.readObjectForClass(ObjectInputStream.java:1372)
at java.io.ObjectInputStream.readHierarchy(ObjectInputStream.java:1269)
at java.io.ObjectInputStream.readNewObject(ObjectInputStream.java:1858)
at java.io.ObjectInputStream.readNonPrimitiveContent(ObjectInputStream.java:787)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:2006)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:1963)
at com.example.myapp.app.settings.backup.compatibility.CompatibilityImporter$1.run(CompatibilityImporter.java:48)
at java.lang.Thread.run(Thread.java:841)
有谁知道可能出现什么问题?
我希望有人能够分享并解决我的问题,或者知道属性之间的混淆是如何发生的。
答案 0 :(得分:0)
在其中一个对象中,我映射到一个属性时丢失并导致混淆。
我的错!