使用null作为地图键时,Gson反序列化失败
Gson gson = new GsonBuilder()
.serializeNulls()
.serializeSpecialFloatingPointValues()
.create();
Map<Integer, String> mapData = new HashMap<Integer, String>();
mapData.put(null, "abc");
String data = gson.toJson(mapData);
System.out.println(data);
Type type = TypeToken.getParameterized(HashMap.class, Integer.class, String.class).getType();
Object obj = gson.fromJson(data, type);
System.out.println(obj);
例外:
Exception in thread "main" com.google.gson.JsonSyntaxException: java.lang.NumberFormatException: For input string: "null"
以下代码段效果很好。
Gson gson = new GsonBuilder()
.serializeNulls()
.serializeSpecialFloatingPointValues()
.create();
Map<String, Integer> mapData = new HashMap<>();
mapData.put("abc", null);
String data = gson.toJson(mapData);
System.out.println(data);
Type type = TypeToken.getParameterized(HashMap.class, String.class, Integer.class).getType();
Object obj = gson.fromJson(data, type);
System.out.println(obj);
输出:
{"abc":null}
{abc=null}
答案 0 :(得分:1)
您可以为Integer
创建TypeAdapter:
Gson gson = new GsonBuilder()
.serializeNulls()
.serializeSpecialFloatingPointValues()
.registerTypeAdapter(Integer.class, new TypeAdapter<Integer>() {
@Override
public void write(JsonWriter jsonWriter, Integer integer) throws IOException {
jsonWriter.jsonValue(String.valueOf(integer));
}
@Override
public Integer read(JsonReader jsonReader) throws IOException {
if (jsonReader.peek() == JsonToken.NULL) {
jsonReader.nextNull();
return null;
} else {
String numberStr = jsonReader.nextString();
return "null".equals(numberStr) ? null : Integer.valueOf(numberStr);
}
}
})
.create();
输出:
{"null":"abc"}
{null=abc}
在没有自定义Integer适配器的情况下,null
会为值工作而对密钥不起作用的原因是映射适配器序列化每个密钥的方式:密钥始终是JSON中的String
,它既不是int
也不是null
。您可以在输出中看到它:{"null":"abc"}
与{"abc":null}
。
查看map type adapter的实现。