2

次のようなクラスがあります

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

私の入力は次のようになります。

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

またはこのように:

{ "id": 123 }

最初のバリアントは「新しい」(永続化されていない) 個人を表し、2 番目のバリアントはデータベース ID で個人を参照します。

が null でない場合idは、デシリアライズ中にデータベースからオブジェクトをロードします。それ以外の場合は、通常の解析にフォールバックし、新しいオブジェクトとしてデシリアライズします。

私が試したこと:現在JsonDeserializer、データベースのデシリアライゼーションを持っていますが、私が理解しているように、通常の解析に「フォールバック」する方法はありません。この回答によるとTypeAdapterFactory、 a とを使用する必要がありgetDelegateAdapterます。このアプローチに関する私の問題は、JsonReader(たとえば a ではなく)が与えられているため、入力を消費せずJsonElementに入力に有効なが含まれているかどうかを判断できないことです。id

これを解決する方法について何か提案はありますか?

4

2 に答える 2

0

hereの回答の助けを借りて、なんとかこれを理解できたと思います。

これはワーキングタイプのアダプタファクトリです:

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 に答える