【问题标题】:Gson store object type in json [duplicate]json中的Gson存储对象类型[重复]
【发布时间】:2017-07-29 23:20:00
【问题描述】:

我需要将对象从一个套接字发送到另一个套接字,并且我想使用 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...)
        ...
    }
}

是否可以像这样用它们的类型序列化对象?

【问题讨论】:

标签: java json serialization gson


【解决方案1】:

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

【讨论】:

  • Gesnon 处理 Pojos 的方式你不喜欢什么?这与 Gson 或 Jackson 处理它们的方式非常相似。
猜你喜欢
  • 2012-12-26
  • 2014-08-06
  • 2017-07-07
  • 2019-01-09
  • 1970-01-01
  • 2015-11-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多