java - Gson在json中存储对象类型

标签 java json serialization gson

我需要将对象从一个套接字发送到另一个套接字,并且我想使用 JSON 进行序列化。 每个 json 对象都必须存储其类型。我的计划是包装我的物体:

{
   /* the type */ "_type_": "my.package.MyClass",
   /* the actual object */ "_data_": {
      ...
   }
}

我尝试通过编写此序列化适配器来实现此目的

Gson gson = new GsonBuilder().registerTypeAdapter(Wrapper.class, new ObjectWrapperAdapter()).create();
gson.toJson(new Wrapper(myObject), Wrapper.class);

private static class ObjectWrapperAdapter implements JsonSerializer<Wrapper>, JsonDeserializer<Wrapper> {
    private static final String TYPE_KEY = "__type__";
    private static final String DATA_KEY = "__data__";

    @Override
    public Wrapper deserialize(JsonElement json, Type type, JsonDeserializationContext context) throws JsonParseException {
        if(!json.isJsonObject()) throw new JsonParseException("element is not an object!");
        JsonObject object = json.getAsJsonObject();
        if(!object.has(TYPE_KEY)) throw new JsonParseException(TYPE_KEY + " element is missing!");
        if(!object.has(DATA_KEY)) throw new JsonParseException(DATA_KEY + " element is missing!");
        JsonElement dataObject = object.get(DATA_KEY);
        String clazzName = object.get(TYPE_KEY).getAsString();
        Class<?> clazz = classForName(clazzName);
        return new Wrapper(context.deserialize(dataObject, clazz));
    }

    private Class<?> classForName(String name) throws JsonParseException {
        try {
            return Class.forName(name);
        } catch (ClassNotFoundException e) {
            throw new JsonParseException(e);
        }
    }

    @Override
    public JsonElement serialize(Wrapper src, Type type, JsonSerializationContext context) {
        JsonObject wrapper = new JsonObject();
        Object data = src.object;
        JsonElement dataElement = context.serialize(data);
        String className = data.getClass().getName();
        wrapper.addProperty(TYPE_KEY, className);
        wrapper.add(DATA_KEY, dataElement);
        return wrapper;
    }
}

public static class Wrapper {
    private final Object object;

    public Wrapper(Object object) {
        this.object = object;
    }
}

理论上,这是可行的,但是当我尝试序列化嵌套对象时,它会失败,就像这样

class MyType {
    AnotherType anotherType;
}

因为只有MyType将被包装,生成的 json 将如下所示:

{
    "__type__": "my.package.MyType",
    "__data__": {
        (No "__type__" field here...)
        ...
    }
}

是否可以像这样序列化对象及其类型?

最佳答案

This answer描述了如何解决这个问题。它不使用Gson,而是Genson反而。我不太喜欢 Genson 处理 Pojos 的方式,但我想我必须忍受这一点。

关于java - Gson在json中存储对象类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45394932/

相关文章:

java - Joda Time 有时返回错误时间

java - 无法提供 key.p12 文件来连接到 Google Cloud Datastore

java - 如何通过 Java FX 中的多个事件处理程序执行一项操作?

java - 需要非常快速的序列化 Java

serialization - Julia:serialize()/deserialize() 有多稳定

arrays - 如何在 Swift 中将 Floats 的 ContiguousArray 转换为字节数组?

java - MapStruct 不生成实现类

java - 如何将所有调用映射到 springboot Controller 中的 *.html ?

arrays - JQ 将数组展平为对象

javascript - SQL 插入语句在 Javascript 中不起作用