如何防止Gson将整数表示为浮点数
当我尝试将string转换为json时,Gson有一些奇怪的行为。 下面的代码将string草稿转换成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} ]
你告诉Gson它正在寻找一个Strings to Objects的地图列表,它基本上是为了最好地猜测Object的types。 由于JSON不区分整数和浮点数字段,所以 Gson必须默认为Float / Double。
Gson基本上是为了检查要填充的对象的types而构build的,以便确定如何parsing数据。 如果你不给它任何暗示的话,那就不太好用了。 一个select是定义一个自定义的JsonDeserializer,不过最好不要使用HashMap(而且绝对不要使用Hashtable!),而是给Gson更多关于它所期待的数据types的信息。
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());
同样,Gson的重点是将结构化数据无缝转换为结构化对象。 如果你要求它创build一个近似未定义的结构,像对象的映射列表,那么你就是在击败Gson的全部观点,而且还可以使用一些更简单的JSONparsing器。
这工作:
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();
我迟到了,但是我自己也碰到了。 在我的情况下,我不想在我的ArrayList中指定一个整数types – 因为它可能是一个string或整数。
我的解决scheme如下:
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();
而不是使用默认的Gson定义与Gson gs = new Gson();
,我已经重写了Double.class序列化来返回一个整数。
在我的情况下,我的JSON中有string和整数,但是我没有任何双打,所以这不会造成问题。
如果你需要一个double或float值,我想可以添加一些逻辑来testing特定于每个数据types的属性的值,并返回一个合适的值。 就像是
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); }
我不知道如何testing或转换这些数据types的头顶,但这应该把你放在正确的道路上。