Mar*_*phy 55 java android gson
当我尝试将字符串转换为json时,Gson有一些奇怪的行为.下面的代码将字符串草稿转换为json响应.有没有办法阻止gson将'.0添加到所有整数值?
ArrayList<Hashtable<String, Object>> responses;
Type ResponseList = new TypeToken<ArrayList<Hashtable<String, Object>>>() {}.getType();
responses = new Gson().fromJson(draft, ResponseList);
draft:
[ {"id":4077395,"field_id":242566,"body":""},
{"id":4077398,"field_id":242569,"body":[[273019,0],[273020,1],[273021,0]]},
{"id":4077399,"field_id":242570,"body":[[273022,0],[273023,1],[273024,0]]}
]
responses:
[ {id=4077395.0, body=, field_id=242566.0},
{id=4077398.0, body=[[273019.0, 0.0], [273020.0, 1.0], [273021.0, 0.0]], field_id=242569.0},
{id=4077399.0, body=[[273022.0, 0.0], [273023.0, 1.0], [273024.0, 0.0]], field_id=242570.0}
]
Run Code Online (Sandbox Code Playgroud)
See*_*ker 53
从2.8.9版本开始,库提供了一个解决方案。
\n我们可以通过该方法设置Object如何转换为数字GsonBuilder.setObjectToNumberStrategy()
。
LONG_OR_DOUBLE
在这种情况下,实施将起作用。可以用作
Gson gson = new GsonBuilder()\n .setObjectToNumberStrategy(ToNumberPolicy.LONG_OR_DOUBLE)\n .create();\nresponses = gson.fromJson(draft, ResponseList);\n
Run Code Online (Sandbox Code Playgroud)\n有关详细信息,请参阅 GitHub 拉取请求:支持对象和数字反序列化的任意数字实现,由 lyubomyr-shaydariv \xc2\xb7 拉取请求 #1290 \xc2\xb7 google/gson \xc2\xb7 GitHub。
\ndim*_*414 40
你告诉Gson它正在寻找一个Strings to Objects的地图列表,它实际上是为了对它的类型做出最佳猜测.由于JSON不区分整数和浮点字段,因此对于数字字段,Gson必须默认为Float/Double.
Gson从根本上构建用于检查要填充的对象的类型,以确定如何解析数据.如果你没有给它任何暗示,那就不会很好.一种选择是定义一个自定义的JsonDeserializer,但更好的方法是不使用HashMap(绝对不使用Hashtable!),而是给Gson更多关于它期望的数据类型的信息.
class Response {
int id;
int field_id;
ArrayList<ArrayList<Integer>> body; // or whatever type is most apropriate
}
responses = new Gson()
.fromJson(draft, new TypeToken<ArrayList<Response>>(){}.getType());
Run Code Online (Sandbox Code Playgroud)
同样,Gson的重点是将结构化数据无缝转换为结构化对象.如果你要求它创建一个几乎未定义的结构,比如对象的映射列表,那么你就会击败Gson的整个点,并且可能会使用一些更简单的JSON解析器.
Mar*_*man 25
这有效:
Gson gson = new GsonBuilder().
registerTypeAdapter(Double.class, new JsonSerializer<Double>() {
@Override
public JsonElement serialize(Double src, Type typeOfSrc, JsonSerializationContext context) {
if(src == src.longValue())
return new JsonPrimitive(src.longValue());
return new JsonPrimitive(src);
}
}).create();
Run Code Online (Sandbox Code Playgroud)
基本上,这个问题没有完美的答案.所有"解决方案"仅适用于某些情况.这是向gson团队报告的一个问题,遗憾的是他们似乎坚持认为"javascript没有整数类型",好像他们没有意识到gson是针对java而不是javascript.所以他们拒绝修复它直到今天(现在是2018年),尽管像杰克逊这样的其他lib根本没有这样的问题,尽管有多容易修复它.因此,您可能必须自己从gson源代码中修复问题并构建自己的gson.jar.源文件是gson/src/main/java/com/google/gson/internal/bind/ObjectTypeAdapter.java
case NUMBER:
return in.nextDouble();
Run Code Online (Sandbox Code Playgroud)
我参加聚会很晚,但是我自己碰到了这个。就我而言,我不想在ArrayList中指定一个Integer类型-因为它可以是String或Integer。
我的解决方案如下:
GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.registerTypeAdapter(Double.class, new JsonSerializer<Double>() {
public JsonElement serialize(Double src, Type typeOfSrc,
JsonSerializationContext context) {
Integer value = (int)Math.round(src);
return new JsonPrimitive(value);
}
});
Gson gs = gsonBuilder.create();
Run Code Online (Sandbox Code Playgroud)
而不是使用默认的Gson定义Gson gs = new Gson();
,我重写了Double.class序列化以返回整数。
就我而言,我的JSON中包含Strings和Integers,但是我没有任何双打,因此这没有问题。
如果您需要一个double或float值,我想可以添加一些逻辑来测试每种数据类型特定的属性的值并返回适当的值。就像是
if(/*source has a decimal point*/){
return new JsonPrimitive(src);
} else if (/* source has some attribute of a Float */){
Float value = /*convert the src value from double to a Float */;
return new JsonPrimitive(value);
} else {
//it looks like an integer
Integer value = (int)Math.round(src);
return new JsonPrimitive(value);
}
Run Code Online (Sandbox Code Playgroud)
我不知道如何测试或转换这些数据类型,但这应该使您走上正确的道路。