2

Imagine if I have the following JSON

{"game":"football", "people":"elevent"}
{"game":"badminton", "people":"two"}

My class as below

class Sport {
    String game;
    String people;
}

I could do a deserialize of my Json as below

Sport mySport = Gson().fromJson(json, Sport.class);

However, if my JSON is only

{"game":"football"}
{"game":"badminton"}

I would like it to automatically initialize people to "elevent" or "two", pending of the first field. Is there a way to configure my GsonBuilder() to have that achieve automatically during deserialization?

Elye
  • 53,639
  • 54
  • 212
  • 474
  • 1
    http://stackoverflow.com/questions/30216317/setting-default-value-to-a-variable-when-deserializing-using-gson could help this. – Soeun Park Oct 10 '16 at 04:14
  • Having a default value is simple, by instantiating `String people="elevent"`. But I have two and three values to set pending on the initial value. So I would prefer a custom deserialization if possible. – Elye Oct 10 '16 at 04:18

2 Answers2

1

You could create a custom JsonDeserializer:

public class SportDeserializer implements JsonDeserializer<Sport> {
    @Override
    public Sport deserialize(final JsonElement json, final Type typeOfT, final JsonDeserializationContext context) throws JsonParseException {
        JsonObject jsonObject = (JsonObject) json;

        String game = jsonObject.get("game").getAsString();
        JsonElement nullablePeople = jsonObject.get("people");
        String people = nullablePeople == null ? null : nullablePeople.getAsString();

        if (people == null || people.isEmpty()) {
            if (game.equals("football")) {
                people = "elevent";
            }
            else if (game.equals("badminton")) {
                people = "two";
            }
        }

        Sport sport = new Sport();
        sport.game = game;
        sport.people = people;

        return sport;
    }
}

And then use the custom JsonDeserializer:

GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.registerTypeAdapter(Sport.class, new SportDeserializer());
Gson gson = gsonBuilder.create();
Sport sport = gson.fromJson(jsonString, Sport.class);
Wayne Ellery
  • 7,888
  • 1
  • 28
  • 45
  • Thanks Wayne. Your answer best suit my question. I didn't use it as my actual condition is more complicated than the above Json, it has various hierarchies of Json and the two fields are not close to each other in the same hierarchy. Hence I use my solution below. But I still give you a tick and upvote since you answer my question well. Thanks!! – Elye Oct 10 '16 at 06:56
0

My answer below isn't the best for this question since I simplified the question, and the other answer would suite this better.

But for more complicated scenarios, my answer below would help. It is basically setup a post-processing after the GSon converted.

I finally use Gson convert post-processing.

class Sport implements PostProcessingEnabler.PostProcessable {
    String game;
    String people;

    @Override
    public void gsonPostProcess() {
        // The below is something simple.
        // Could have more complicated scneario.
        if (game.equals("football")) {
            people = "elevant";
        } else  if (game.equals("badminton")) {
            people = "two";
        }
    }
}

class PostProcessingEnabler implements TypeAdapterFactory {
    public interface PostProcessable {
        void gsonPostProcess();
    }

    public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
        final TypeAdapter<T> delegate = gson.getDelegateAdapter(this, type);

        return new TypeAdapter<T>() {
            public void write(JsonWriter out, T value) throws IOException {
                delegate.write(out, value);
            }

            public T read(JsonReader in) throws IOException {
                T obj = delegate.read(in);
                if (obj instanceof PostProcessable) {
                    ((PostProcessable) obj).gsonPostProcess();
                }
                return obj;
            }
        };
    }
}

Tribute goes to https://blog.simplypatrick.com/til/2016/2016-03-02-post-processing-GSON-deserialization/

Elye
  • 53,639
  • 54
  • 212
  • 474