2

タイプ識別子を持つさまざまなタイプの束の単なるラッパーであるオブジェクトに対して、Gsonでカスタムデシリアライザーを作成しようとしています。

私の問題ドメインの簡単な概要は次のとおりです。

さまざまな無関係なドメイン オブジェクトを含む可能性のあるメッセージを相互に送信するユーザーがいて、次のようなものにデシリアライズしたいと考えています。

public class Message {
    public String messageType;
    public Object messageData;
}

messageData オブジェクトは JavaScript を介して構築されます。プログラマーは、すべてのオブジェクト タイプを 1 つのフィールド「messageData」に詰め込むことにしました。messageData は、User、Video、Web サイト、Picture など、基本クラスやインターフェイスを共有しないドメイン オブジェクトをいくつでも指定できます。

したがって、(単純化された) json オブジェクトは次のようになります。

{ "messageType": "video", "messageData": { "videoId": 1, "videoTitle": "my vid" } }

また

{ "messageType": "picture", "messageData": { "pictureId": 1, "pictureUrl": "http://www.example.com/cat.jpg" } }

目標は、messageType を取得し、それを使用して適切なクラスを選択して逆シリアル化することです。

私はこのようなものを思いついた:

public class MessageJsonDeserializer implements JsonDeserializer<Message> {

    @Override
    public Message deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
        throws JsonParseException {


        JsonObject obj = json.getAsJsonObject();
        Message message = new Message();
        message.messageType = obj.get("messageType").getAsString();
        message.messageData = MessageDataMapper.map(message.messageType, obj.get("messageData")); // maps and casts to the correct Video/Picture,Website etc..
        return message;
    }
}

これはうまくいくようですが、 Message には自動的にシリアル化できる他のフィールドがたくさんあるとしましょう。その場合、 JsonObject を手動で解析してそれらのフィールドを抽出する必要があります。

ハイブリッド アプローチを使用して、Gson にオブジェクト以外のフィールドを自動的にシリアル化させる方法はありますか?

4

2 に答える 2

2

少し遅いかもしれませんが、RuntimeTypeAdapter に関するこの回答は、これを解決するのに役立ちます。

https://stackoverflow.com/a/15737704/433421

RuntimeTypeAdapter を使用すると、JSON で自己構成された型属性 (この場合は「messageType」) を評価し、その値を提供された POJO クラスに登録できます。

この回答で提供されているリンクを見て、javadoc の使用例を確認してください。

私が理解しているように、GSon はそれらの POJO クラス自体のシリアライゼーションとデシリアライゼーションを処理します。

messageData のこれらのフィールドに任意のオブジェクトが含まれている場合は、MessageJsonDeserializer で行ったように、カスタム JsonDeserializer インスタンスを登録する必要があります。

お役に立てれば。

于 2014-01-13T14:23:03.743 に答える
1

悲しいことに、いいえ。少なくとも、私が特定できたわけではありません。「フィールドXをカスタム逆シリアル化しますが、それ以外はsuper.deserialize()」のようなことをさせる方法はありません。神は私が試したことを知っています。それが慰めである場合、それは私が見たすべてのJsonデシリアライザーに当てはまるようです。

于 2013-08-26T21:16:51.703 に答える