我正在使用Gson将我的JSON数据转换为Map<String, Object>
。我的JSON有一些整数(实际上很长)字段,我希望它们被解析得很久(显然)。然而,Gson将它们解析为双打。我如何让Gson将它们解析为long / integers?我见过How to deserialize a list using GSON or another JSON library in Java?但我不想创建一个强类型的自定义类,我将使用Map。我还看到了Android: Gson deserializes Integer as Double以及其他一些我认为可能重复的问题,但所有答案都指向创建一个强类型类,创建在反序列化中起作用的额外函数或完全使用另一个函数库。
谷歌自己的JSON序列化器/反序列化器中是不是有一种简单的方法可以简单地将整数反序列化(是的,一个数字而不是一个点)作为一个整数而不是两倍,因为它应该首先作为默认值?如果我想发送浮点数,我将从服务器JSON发送2.0
,而不是2
。为什么在地球上我得到一个双倍,我该如何摆脱它?
更新尽管我已经清楚地解释过,但有些人仍然不理解我不的另一个图书馆(例如杰克逊)和我知道一个简单的事实,即任何解析器都应该能够将2.0
标识为浮点数并将2
标识为纯整数并进行相应的解析,所以请不要指示我告诉为什么就是这样,因为它只是不正确,并不是不正确解析整数的借口。所以,不,这是不重复Gson. Deserialize integers as integers and not as doubles。
答案 0 :(得分:1)
你不能。
您无法覆盖gson的内置数字转换器。
我做了一个简短的代码测试,以便在gson试图找到委托转换器的引擎盖下查看。
package net.sargue.gson;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.TypeAdapter;
import com.google.gson.TypeAdapterFactory;
import com.google.gson.reflect.TypeToken;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonWriter;
import org.intellij.lang.annotations.Language;
import java.io.IOException;
import java.util.Map;
public class SO36528727 {
public static void main(String[] args) {
@Language("JSON")
String json = "{\n" +
" \"anInteger\": 2,\n" +
" \"aDouble\": 2.0\n" +
"}";
Gson gson = new GsonBuilder()
.registerTypeAdapterFactory(new LongDeserializerFactory())
.create();
Map<String, Object> m =
gson.fromJson(json,
new TypeToken<Map<String, Object>>() {}.getType());
System.out.println(m.get("aDouble").getClass());
System.out.println(m.get("anInteger").getClass());
}
private static class LongDeserializerFactory
implements TypeAdapterFactory
{
@Override
public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
System.out.println("type = " + type);
if (type.getRawType().equals(String.class)) {
TypeAdapter<String> stringAdapter =
gson.getDelegateAdapter(this, TypeToken.get(String.class));
return new TypeAdapter<T>() {
@Override
public void write(JsonWriter out, T value) throws IOException {
stringAdapter.write(out, (String) value);
}
@SuppressWarnings("unchecked")
@Override
public T read(JsonReader in) throws IOException {
String s = stringAdapter.read(in);
System.out.println("s = " + s);
return (T) s;
}
};
} else
return null;
}
}
}
执行结果如下:
type = java.util.Map<java.lang.String, java.lang.Object>
type = java.lang.String
s = anInteger
s = aDouble
class java.lang.Double
class java.lang.Double
所以,你可以看到gson看起来只是两个转换器:整个Map<>
的东西和基本的String
。但不是Double
或Integer
或Number
甚至Object
。所以你可以覆盖它,除非你从更高的地方覆盖它,就像处理Map
时一样。关于这个问题was answered on the thread you reference。