Google gson fromJson を使用する場合、通常変換先は自分で用意するクラスがほとんどのケースであり、
であり、Object に変換させることはあまりやらない。
Gson gson = new GsonBuilder().serializeNulls().create(); Map<String, Object> map = gson.fromJson("{a:0}", new TypeToken<Map<String, Object>>(){}.getType()); System.out.println(map);
この結果は、
{a=0.0}
に、なってしまう。 0 では、なく 0.0 になってしまう。
Map<String, String> map = gson.fromJson("{a:0}", new TypeToken<Map<String, String>>(){}.getType());
であれば、、、
{a=0}
で思いどおりではあるが、Map の value を Objectにしてしまうと、こうならならない。
それでは、Gson のデシリアライザを用意するということで、以下のデシリアライザを用意する。
import java.lang.reflect.Type; import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; import java.util.Set; import com.google.gson.JsonDeserializationContext; import com.google.gson.JsonDeserializer; import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.google.gson.JsonParseException; /** * GenericMapDeserializer<T> : Map<String, T> へのデシリアライザ */ public final class GenericMapDeserializer<T> implements JsonDeserializer<Map<String, T>>{ @Override public Map<String, T> deserialize(JsonElement jsonElement, Type typeOfT , JsonDeserializationContext context) throws JsonParseException{ if (!jsonElement.isJsonObject()){ return null; } JsonObject jsonObject = jsonElement.getAsJsonObject(); Set<Entry<String, JsonElement>> jsonEntrySet = jsonObject.entrySet(); Map<String, T> deserializedMap = new HashMap<String, T>(); for(Entry<String, JsonElement> entry : jsonEntrySet){ try{ if(entry.getValue().isJsonNull()){ deserializedMap.put(entry.getKey(), null); }else if(entry.getValue().isJsonArray()){ deserializedMap.put(entry.getKey(), (T)entry.getValue()); }else if(entry.getValue().isJsonObject()){ deserializedMap.put(entry.getKey(), (T)entry.getValue()); }else if(entry.getValue().isJsonPrimitive()){ deserializedMap.put(entry.getKey(), context.deserialize(entry.getValue(), String.class)); } }catch(Exception e){ throw new RuntimeException(e.getMessage(), e); } } return deserializedMap; } }
これを GsonBuilder で Gson を作るとき、registerTypeAdapter で指定する。
Gson gson = new GsonBuilder() .registerTypeAdapter(new TypeToken<Map<String, Object>>(){}.getType(),new GenericMapDeserializer<Object>()) .serializeNulls() .create();
こうして、、
Map<String, Object> map = gson.fromJson("{a:0}", new TypeToken<Map<String, Object>>(){}.getType()); System.out.println(map);
とすれば、、、
{a=0}
が結果になる。