gpt4 book ai didi

java - 使用不同的包名称跨不同应用程序反/序列化 java 对象

转载 作者:太空宇宙 更新时间:2023-11-04 10:36:13 28 4
gpt4 key购买 nike

我想在不同的应用程序之间共享 java 对象。

只要我在不同的项目中使用相同的包名称,它就可以正常工作。但如果我更改包名称,它就不再起作用了。

我尝试通过扩展 ObjectInputStream 类并重写 readClassDescriptor 方法来解决此问题。

但是这样做我收到以下错误:

java.io.StreamCorruptedException: invalid type code: 00

...不知道如何解决这个问题。

这是我用于扩展 ObjectInputStream 类的代码:

public class MyObjectInputStream extends ObjectInputStream {

public static Map<String, Class> classNameMapping = initclassNameMapping();

private static Map<String, Class> initclassNameMapping(){
Map<String, Class> res = new HashMap<String, Class>();
//ipxTest is the name of the package where the objects got serialized
res.put("ipxTest.IPX", interprojectxchangeTest.IPX.class);
res.put("ipxTest.A", interprojectxchangeTest.A.class);
return Collections.unmodifiableMap(res);
}

public MyObjectInputStream(InputStream in) throws IOException {
super(in);
enableResolveObject(true);
}


protected MyObjectInputStream() throws IOException, SecurityException {
super();
enableResolveObject(true);
}

@Override
protected java.io.ObjectStreamClass readClassDescriptor()
throws IOException, ClassNotFoundException {
ObjectStreamClass desc = super.readClassDescriptor();
if (classNameMapping.containsKey(desc.getName()))
return ObjectStreamClass.lookup(classNameMapping.get(desc.getName()));
return desc;
}
}

IPX 和 A 类在不同的项目中看起来都是相同的,并且都具有相同的序列 ID。

最佳答案

我的第一个建议是让您的实现变得简单并停止与框架对抗 - 跨应用程序使用相同的包名称。我建议用可序列化的类创建一个库,并在实现之间共享它。

如果您必须跨具有不同包名称的应用程序进行序列化/反序列化,那么我的建议是放弃与类名和包名称紧密相关的内置 Java 序列化,并使用 Gson 之类的东西来序列化/反序列化。

Gson 允许您指定 TypeAdaper。您可以为要序列化/反序列化的每个类创建并注册一个 TypeAdapter,并在序列化时指定类名(不带包名)作为“类型”,如下例所示,但使用 getSimpleName() 而不是 getCanonicalName()

反序列化时,您必须将正确的包名称添加到“类型”

您必须为每个应用程序单独执行 TypeAdapter。

public class GsonTypeAdapter<T> implements JsonSerializer<T>, JsonDeserializer<T> {
@Override
public JsonElement serialize(T src, Type typeOfSrc, JsonSerializationContext context) {
JsonObject result = new JsonObject();
result.add("type", new JsonPrimitive(src.getClass().getCanonicalName()));
result.add("properties", context.serialize(src, src.getClass()));

return result;
}

@Override
public T deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
throws JsonParseException {
JsonObject jsonObject = json.getAsJsonObject();
String type = jsonObject.get("type").getAsString();
JsonElement element = jsonObject.get("properties");

try {
return context.deserialize(element, Class.forName(type));
} catch (ClassNotFoundException cnfe) {
throw new JsonParseException("Unknown element type: " + type, cnfe);
}
}
}

关于java - 使用不同的包名称跨不同应用程序反/序列化 java 对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49439800/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com