How to do conditional Gson deserialization default value

走远了吗. 提交于 2020-01-01 19:47:47

问题


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?


回答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);



回答2:


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/



来源:https://stackoverflow.com/questions/39951187/how-to-do-conditional-gson-deserialization-default-value

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!