3

Google Gson を使用してクラスを逆シリアル化する際に問題があります。この問題に何日も悩まされており、解決策が見つかりません。

簡単なテスト ケースを作成しました。これは、クラスの最小限の作業サブセットです。

import java.util.Date;

import com.google.api.client.util.DateTime;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;

public class Test {
public static void main(String[] args) {

    GsonBuilder builder = new GsonBuilder();

    Gson gson = builder.create();

    DateTest dt = new DateTest(new Date());
    String j1 = gson.toJson(dt);
    System.out.println(j1);
    DateTest dt2 = gson.fromJson(j1, DateTest.class);
    System.out.println(dt2);

}

static class DateTest {
    @com.google.api.client.util.Key
    private final DateTime date;

    public DateTest(Date dt) {
        this.date = new DateTime(dt);
    }

    @Override
    public String toString() {
        return date.toString();
    }
}
}

これにより、目的の出力が生成されます。

シリアライズ先: {"date":{"value":1381503448717,"dateOnly":false,"tzShift":60}} 逆シリアル化先: 2013-10-11T15:57:28.717+01:00

ただし、シリアライズしようとしているクラスは、「Generate Cloud Endpoint Client Library」を使用して Google App Engine クラスから自動的に生成されます (つまり、変更することはできません/変更するつもりはありませんが、このクラスは jar を使用して JSON にシリアライズ/デシリアライズできます)私はクラスパスにあります - https://developers.google.com/appengine/docs/java/endpoints/consume_androidを参照してください)。

多くのテストの後、問題は自動生成されたクラス「com.google.api.client.json.GenericJsonを拡張する」であることがわかりました-コードを次のように変更した場合:

static class DateTest extends com.google.api.client.json.GenericJson{

シリアル化は (同じ出力で) 成功しますが、逆シリアル化は次のように失敗します。

Exception in thread "main" java.lang.ClassCastException: Cannot cast java.util.LinkedHashMap to Test$DateTest
at java.lang.Class.cast(Unknown Source)
at com.google.gson.Gson.fromJson(Gson.java:643)
at Test.main(Test.java:17)

Android はより詳細な出力を提供しているようです。問題は、非基本的なクラス属性が失敗することです。

私の質問は、逆シリアル化が成功するように逆シリアル化コードを変更するにはどうすればよいですか? 私は何を間違っていますか?

私のプロジェクトはネットワークから同じ JSON オブジェクトを逆シリアル化できるため、「別の JSON ライブラリを使用してみてください」という種類の回答は受け付けないことに注意してください。

4

1 に答える 1