2

我有一个如下所示的课程

class Person {
    Long id;
    String firstName;
    int age;
}

我的输入看起来像这样:

{ "id": null, "firstName": "John", "age": 10 }

或像这样:

{ "id": 123 }

第一个变体代表一个“新”(非持久化)人,第二个变体通过其数据库 id 指代一个人。

如果id非空,我想在反序列化期间从数据库加载对象,否则回退到常规解析并将其反序列化为新对象。

我尝试过的:我目前有一个JsonDeserializer用于数据库反序列化的,但据我了解,没有办法“退回”常规解析。根据这个答案,我应该使用 aTypeAdapterFactorygetDelegateAdapter. 我对这种方法的问题是我得到了 a JsonReader(而不是例如 a JsonElement),所以我无法确定输入是否包含有效id输入而不消耗输入。

关于如何解决这个问题的任何建议?

4

2 回答 2

0

我想我在这里的答案的帮助下设法解决了这个问题。

这是一个工作类型的适配器工厂:

new TypeAdapterFactory() {
        @Override
        public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {

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

            // Are we asked to parse a person?
            if (!type.getType().equals(Person.class))
                return null;

            return new TypeAdapter<T>() {

                @Override
                public T read(JsonReader reader) throws IOException {

                    JsonElement tree = elementAdapter.read(reader);
                    JsonElement id = tree.getAsJsonObject().get("id");

                    if (id == null)
                        return delegate.fromJsonTree(tree);

                    return (T) findObj(id.getAsLong());
                }

                @Override
                public void write(JsonWriter writer, T obj) throws IOException {
                    delegate.write(writer, obj);
                }
            };
        }
    }

我还没有完全测试它,如果需要我会回来修改它。(现在发布它以开放以获取有关该方法的反馈。)

于 2013-09-03T17:13:11.350 回答
0

我不知道我是否正确理解了你的问题,但如果你已经有一个JsonDeserializer,你应该有一个像这样的方法:

public Person deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) { ... }

在此方法中,您拥有contexttype的对象JsonDeserializationContext,它允许您在指定对象上调用默认反序列化。

因此,您可以在自定义反序列化器中执行类似操作:

//If id is null...
Person person = context.deserialize(json, Person.class);

请参阅JsonDeserializationContext文档

于 2013-09-03T11:54:10.143 回答