Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Gson deserializing with changing field types

Tags:

java

json

gson

i have an API-Call that returns:

{
  "id": 550,
  "favorite": false,
  "rated": {
    "value": 7.5
  },
  "watchlist": false
}

or

{
  "id": 550,
  "favorite": false,
  "rated": false,
  "watchlist": false
}

so the "rated"-Field is sometimes an object or an boolean. How do i deserialize something like that with Gson?

my Object so far looks like:

public class Status{
    @Expose public boolean favorite;
    @Expose public Number id;
    @Expose public Rated rated;
    @Expose public boolean watchlist;
}
public class Rated{
    @Expose public Number value;
}
like image 250
www40 Avatar asked Nov 23 '25 07:11

www40


1 Answers

In order for this to work, one way is to implement TypeAdapter<Rated> - something like this:

public class RatedAdapter extends TypeAdapter<Rated> {

    public Rated read(JsonReader reader) throws IOException {
        reader.beginObject();
        reader.nextName();

        Rated rated;
        try {
            rated = new Rated(reader.nextDouble());
        } catch (IllegalStateException jse) {
            // We have to consume JSON document fully.
            reader.nextBoolean();
            rated = null;
        }

        reader.endObject();

        return rated;
    }

    public void write(JsonWriter writer, Rated rated) throws IOException {
        if (rated == null) {
            writer.value("false");
        } else {
            writer.value(rated.value);
        }
    }
}

When you have TypeAdapter in place, all you have to do is to register it with GsonBuilder and create new Gson like this:

    GsonBuilder builder = new GsonBuilder();
    builder.registerTypeAdapter(Rated.class, new RatedAdapter());
    Gson gson = builder.create();

    //Let's try it
    Status status = gson.fromJson(json, Status.class);

With this type adapter installed, Gson will try to convert all properties named rated to appropriate Rated Java object.

like image 140
PrimosK Avatar answered Nov 25 '25 21:11

PrimosK