thedayofcondor
thedayofcondor

Reputation: 3876

JSON - deserializing client class using Gson

I have a problem deserializing a class using Google Gson. This problem has afflicted me for days and I cannot find a solution.

I have created a simple test case, this is the minimal working subset of my class:

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();
    }
}
}

This produces the desired output.

Serialised to: {"date":{"value":1381503448717,"dateOnly":false,"tzShift":60}} Deserialized back to: 2013-10-11T15:57:28.717+01:00

However, the class I am trying to serialise is automatically generated from a Google App Engine class using "Generate Cloud Endpoint Client Library" (meaning I am not able/willing to modify it but also that this class IS serializable/deserializable to JSON with jars I have in the classpath - see https://developers.google.com/appengine/docs/java/endpoints/consume_android ).

After a lot of testing I found out the problem is the auto generated class "extends com.google.api.client.json.GenericJson" - if you change the code to:

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

the serialisation succeeds (with the same output) but deserialising fails with:

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 seems to be giving a more detailed output, the problem is any non basic class attribute fails.

My question is - how can I modify my deserialization code so the deserialization is successful? What am I doing wrong?

As my project is able to deserialise the same JSON object from the network please be aware I will not accept any answer on the kind "try using another JSON library".

Upvotes: 3

Views: 2520

Answers (1)

thedayofcondor
thedayofcondor

Reputation: 3876

After a weekend of digging through Google code, I found the following code which solves my problem:

public static void main(String[] args) {

    GsonFactory factory= new GsonFactory();

    DateTest dt = new DateTest(new Date());
    String j1 = factory.toString(dt);
    System.out.println(j1);
    DateTest dt2 = factory.fromString(j1, DateTest.class);
    System.out.println(dt2);

}

Hope this will help other people in the future.

Upvotes: 8

Related Questions