来自Gson项目的此链接似乎表明,将类型化的Map序列化为JSON时,我将必须执行以下操作:
public static class NumberTypeAdapter implements JsonSerializer<Number>, JsonDeserializer<Number>, InstanceCreator<Number> { public JsonElement serialize(Number src, Type typeOfSrc, JsonSerializationContext context) { return new JsonPrimitive(src); } public Number deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { JsonPrimitive jsonPrimitive = json.getAsJsonPrimitive(); if (jsonPrimitive.isNumber()) { return jsonPrimitive.getAsNumber(); } else { throw new IllegalStateException("Expected a number field, but was " + json); } } public Number createInstance(Type type) { return 1L; } } public static void main(String[] args) { Map<String, Number> map = new HashMap<String, Number>(); map.put("int", 123); map.put("long", 1234567890123456789L); map.put("double", 1234.5678D); map.put("float", 1.2345F); Type mapType = new TypeToken<Map<String, Number>>() {}.getType(); Gson gson = new GsonBuilder().registerTypeAdapter(Number.class, new NumberTypeAdapter()).create(); String json = gson.toJson(map, mapType); System.out.println(json); Map<String, Number> deserializedMap = gson.fromJson(json, mapType); System.out.println(deserializedMap); }
很酷,这行得通,但是似乎有很多开销( 整个Type Adapter类? )。我使用了其他JSONLib之类的JSON库,它们使您可以通过以下方式构建地图:
JSONObject json = new JSONObject(); for(Entry<String,Integer> entry : map.entrySet()){ json.put(entry.getKey(), entry.getValue()); }
或者,如果我有一个自定义类,则如下所示:
JSONObject json = new JSONObject(); for(Entry<String,MyClass> entry : map.entrySet()){ JSONObject myClassJson = JSONObject.fromObject(entry.getValue()); json.put(entry.getKey(), myClassJson); }
该过程更加手动,但是所需的代码更少,并且没有开销来为Number创建自定义类型适配器,或者在大多数情况下 为我自己的自定义类 创建自定义类型适配器。
这是使用Gson序列化地图的唯一方法,还是有人在上面的链接中找到了超越Gson建议的方法。
只有TypeToken一部分是必需的(当涉及泛型时)。
TypeToken
Map<String, String> myMap = new HashMap<String, String>(); myMap.put("one", "hello"); myMap.put("two", "world"); Gson gson = new GsonBuilder().create(); String json = gson.toJson(myMap); System.out.println(json); Type typeOfHashMap = new TypeToken<Map<String, String>>() { }.getType(); Map<String, String> newMap = gson.fromJson(json, typeOfHashMap); // This type must match TypeToken System.out.println(newMap.get("one")); System.out.println(newMap.get("two"));
输出:
{"two":"world","one":"hello"} hello world