GSON de/serialization of wrapper class

守給你的承諾、 提交于 2020-01-05 15:16:03

问题


I have a convenience class wrapper for a Map, that looks something like this:

class MapWrapper {
    private Map<String, Integer> wrapped = new HashMap<>();

    public void add(String key, Integer count) {/*implementation*/}
    // Other modifiers
}

The reason that I'm not using a Map directly but rather the wrapper is because I need to use the methods to access the Map indirectly.

When I de/serialize this object, I would like the JSON to serialize as if the wrapper class wasn't there. E.G. I want:

{
  "key1":1,
  "key2":2
}

for my JSON in/output and not (what is the default just passing to GSON):

{
  wrapped: {
    "key1":1,
    "key2":2
  }
}

If it matters, this object will be contained within another so GSON contextual deserialization will be able to say that the Object is a MapWrapper and not just a Map.


回答1:


Implement a custom JsonSerializer / JsonDeserializer for your type:

public class MyTypeAdapter implements JsonSerializer<MapWrapper>, JsonDeserializer<MapWrapper> {
    @Override
    public JsonElement serialize(MapWrapper src, Type typeOfSrc, JsonSerializationContext context) {
        JsonObject obj = new JsonObject();
        src.wrapped.entrySet().forEach(e -> obj.add(e.getKey(), new JsonPrimitive(e.getValue())));
        return obj;
    }

    @Override
    public MapWrapper deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
        MapWrapper wrapper = new MapWrapper();
        json.getAsJsonObject().entrySet().forEach(e -> wrapper.wrapped.put(e.getKey(), e.getValue().getAsInt()));
        return wrapper;
    }
}

Then register it when you construct your Gson instance:

Gson gson = new GsonBuilder()
            .registerTypeAdapter(MapWrapper.class, new MyTypeAdapter())
            .create();

You should be able to call it like so:

MapWrapper wrapper = new MapWrapper();
wrapper.wrapped.put("key1", 1);
wrapper.wrapped.put("key2", 2);

String json = gson.toJson(wrapper, MapWrapper.class);
System.out.println(json);

MapWrapper newWrapper = gson.fromJson(json, MapWrapper.class);
for(Entry<String, Integer> e : newWrapper.wrapped.entrySet()) {
    System.out.println(e.getKey() + ", " + e.getValue());
}

This should print:

{"key1":1,"key2":2}
key1, 1
key2, 2


来源:https://stackoverflow.com/questions/34123721/gson-de-serialization-of-wrapper-class

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