Gson. Deserialize integers as integers and not as doubles

后端 未结 7 1106
我寻月下人不归
我寻月下人不归 2020-12-09 16:46

I have json object with arbitary values inside. And I want to deserialize it in a Map. Everything is ok except converting integers to a doubles. See example:



        
7条回答
  •  粉色の甜心
    2020-12-09 17:28

    Been searching for a solution to the nested Map problem myself and "이종은" above was the first answer that actually helped in the non trivial use cases.

    Since the solution above only handled Number I updated the solution to provide generic parsing capability for String and booleans also, see the updated code below:

    private static class MapDeserializer implements JsonDeserializer> {
    
        public Map deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
            Map m = new LinkedHashMap();
            JsonObject jo = json.getAsJsonObject();
            for (Entry mx : jo.entrySet()) {
                String key = mx.getKey();
                JsonElement v = mx.getValue();
                if (v.isJsonArray()) {
                    m.put(key, g.fromJson(v, List.class));
                } else if (v.isJsonPrimitive()) {
                    Number num = null;
                    ParsePosition position=new ParsePosition(0);
                    String vString=v.getAsString();
                    try {
                      num = NumberFormat.getInstance(Locale.ROOT).parse(vString,position);
                    } catch (Exception e) {
                    }
                    //Check if the position corresponds to the length of the string
                    if(position.getErrorIndex() < 0 && vString.length() == position.getIndex()) {
                      if (num != null) {
                        m.put(key, num);
                        continue;
                      }
                    }
                    JsonPrimitive prim = v.getAsJsonPrimitive();
                    if (prim.isBoolean()) {
                        m.put(key, prim.getAsBoolean());
                    } else if (prim.isString()) {
                        m.put(key, prim.getAsString());
                    } else {
                        m.put(key, null);
                    }
    
                } else if (v.isJsonObject()) {
                    m.put(key, g.fromJson(v, Map.class));
                }
    
            }
            return m;
        }
    }
    
    private static class ListDeserializer implements JsonDeserializer> {
    
        public List deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
            List m = new ArrayList();
            JsonArray arr = json.getAsJsonArray();
            for (JsonElement jsonElement : arr) {
                if (jsonElement.isJsonObject()) {
                    m.add(g.fromJson(jsonElement, Map.class));
                } else if (jsonElement.isJsonArray()) {
                    m.add(g.fromJson(jsonElement, List.class));
                } else if (jsonElement.isJsonPrimitive()) {
                    Number num = null;
                    try {
                        num = NumberFormat.getInstance().parse(jsonElement.getAsString());
                    } catch (Exception e) {
                    }
                    if (num != null) {
                        m.add(num);
                        continue;
                    }
                    JsonPrimitive prim = jsonElement.getAsJsonPrimitive();
                    if (prim.isBoolean()) {
                        m.add(prim.getAsBoolean());
                    } else if (prim.isString()) {
                        m.add(prim.getAsString());
                    } else {
                        m.add(null);
                    }
                }
            }
            return m;
        }
    }
    
    private static Gson g = new GsonBuilder().registerTypeAdapter(Map.class, new MapDeserializer()).registerTypeAdapter(List.class, new ListDeserializer()).setDateFormat("yyyy-MM-dd HH:mm:ss").create();
    
        

    提交回复
    热议问题