Gson: マップをシリアル化するより簡単な方法はありますか? 質問する

Gson: マップをシリアル化するより簡単な方法はありますか? 質問する

これ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);
  }

クールだし、機能するけど、オーバーヘッドが多すぎる気がする(型アダプタクラス全体ですか?)。私は 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 が推奨する方法よりも優れた方法を見つけた人はいますか。

ベストアンサー1

必要なのは部品のみ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

おすすめ記事