java - Gson自定义序列化

标签 java json serialization gson

我希望有一个自定义的 GSON 反序列化器,这样每当它反序列化一个 JSON 对象(即大括号 { ... } 内的任何内容)时,它都会寻找一个 $type 节点并使用其针对该类型的内置反序列化功能进行反序列化。如果未找到 $type 对象,它就会执行正常操作。

例如,我希望它能工作:

{
    "$type": "my.package.CustomMessage"
    "payload" : {
        "$type": "my.package.PayloadMessage",
        "key": "value"
    }
}

public class CustomMessage {

    public Object payload;
}

public class PayloadMessage implements Payload {

    public String key;
}

调用:Object customMessage = gson.fromJson(jsonString, Object.class)

所以目前如果我将 payload 类型更改为 Payload 接口(interface):

public class CustomMessage {

    public Payload payload;
}

然后下面的 TypeAdapaterFactory 将执行我想要的操作:

final TypeAdapter<T> delegate = gson.getDelegateAdapter(this, type);
final TypeAdapter<JsonElement> elementAdapter = gson.getAdapter(JsonElement.class);
final PojoTypeAdapter thisAdapter = this;

public T read(JsonReader reader) throws IOException {

    JsonElement jsonElement = (JsonElement)elementAdapter.read(reader);

    if (!jsonElement.isJsonObject()) {
        return delegate.fromJsonTree(jsonElement);
    }

    JsonObject jsonObject = jsonElement.getAsJsonObject();
    JsonElement typeElement = jsonObject.get("$type");

    if (typeElement == null) {
        return delegate.fromJsonTree(jsonElement);
    }

    try {
        return (T) gson.getDelegateAdapter(
                thisAdapter,
                TypeToken.get(Class.forName(typeElement.getAsString()))).fromJsonTree(jsonElement);
    } catch (ClassNotFoundException ex) {
        throw new IOException(ex.getMessage());
    }
}

但是,我希望它在 payloadObject 类型或与此相关的任何类型时工作,如果不能,则抛出某种类型匹配异常' t 分配变量。

最佳答案

查看 Gson 的源代码,我发现了我认为的问题所在:

// built-in type adapters that cannot be overridden
factories.add(TypeAdapters.JSON_ELEMENT_FACTORY);
factories.add(ObjectTypeAdapter.FACTORY);

// user's type adapters
factories.addAll(typeAdapterFactories);

如您所见,ObjectTypeAdapter 将优先于我的工厂。

据我所知,唯一的解决方案是使用反射从列表中删除 ObjectTypeAdapter 或在它之前插入我的工厂。我已经这样做了,而且很有效。

关于java - Gson自定义序列化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23695649/

相关文章:

java - jaxb如何按某种顺序编码值?

c# - XML 序列化数据返回的最佳数据类型

jquery 验证显示多个错误

javascript - 带有 JSON 日期的 D3 v4 折线图

asp.net-mvc - 如何防止ASP.NET MVC中的JSON序列化?

serialization - 我如何反序列化为特征,而不是具体类型?

json - 从 Web API 返回驼峰式 JSON

java - PDFbox加载大文件

java - 试图比较两个迭代器的内容,怎么样?

java - EntityManager 数据传输到 mySQL 时出现 UTF-8 编码问题