解决GSON转Long型变为科学计数法或整形变double的问题(自动转换成Double类型

假如有这么个响应结果Response,当不指定泛型T的时候,泛型T中的数据成员容易出现Long型变为科学计数法或整形变double,原因自行百度研究(ObjectTypeAdapter),本文列出两种解决方案即通过自定义Gson类型适配器,在json序列化或反序列化的时候处理

public class Response {

   /**
    * data : data from server
    */

   private T data;

   public T getData() {
       return data;
   }

   public void setData(T data) {
       this.data = data;
   }

   @Override
   public String toString() {
       return "Response{" +
               "data=" + data +
               '}';
   }
}

方案1:使用JsonSerializer处理

    GsonBuilder gsonBuilder = new GsonBuilder();
    gsonBuilder.disableHtmlEscaping();
    gsonBuilder.registerTypeAdapter(
            new TypeToken>(){}.getType(),
            new JsonDeserializer>() {
                @Override
                public LinkedTreeMap deserialize(
                        JsonElement json, Type typeOfT,
                        JsonDeserializationContext context) throws JsonParseException {

                    LinkedTreeMap treeMap = new LinkedTreeMap<>();
                    JsonObject jsonObject = json.getAsJsonObject();
                    Set> entrySet = jsonObject.entrySet();
                    for (Map.Entry entry : entrySet) {
                        Object ot = entry.getValue();
                        if(ot instanceof JsonPrimitive){
                            JsonPrimitive ot1 = (JsonPrimitive) ot;
                            if (ot1.isNumber()){
                                double dbNum = ot1.getAsDouble();
                                long lngNum = (long) dbNum;

                                // 数字超过long的最大值,返回浮点类型
                                if (dbNum > Long.MAX_VALUE) {
                                    treeMap.put(entry.getKey(), dbNum);
                                }
                                // 判断数字是否为整数值
                                if (dbNum == lngNum) {
                                    treeMap.put(entry.getKey(), lngNum);
                                } else {
                                    treeMap.put(entry.getKey(),dbNum);
                                }
                            }else {
                                treeMap.put(entry.getKey(),ot1);
                            }
                        }else{
                            treeMap.put(entry.getKey(), ot);
                        }
                    }
                    return treeMap;
                }
            });
   
   
    Gson gson = gsonBuilder.create();

使用:

Type typeToken = new TypeToken>>(){}.getType();
//Response数据
 String jsonStr="{\"data\":{\"flag\":0.0,\"createTime\":1.641811578E12,\"money\":10.12}}";
Response response = gson.fromJson(jsonStr,typeToken);//反序列化触发JsonDeserializer
//这样Response中泛型T数据成员变为整形

方案2:使用JsonDeserializer处理

    GsonBuilder gsonBuilder = new GsonBuilder();
    gsonBuilder.disableHtmlEscaping();
    gsonBuilder.registerTypeAdapter(Double.class,  new JsonSerializer() {
        @Override
        public JsonElement serialize(final Double src, final Type typeOfSrc, final JsonSerializationContext context) {
            long longNum = src.longValue();
            if (src.doubleValue() > Long.MAX_VALUE) {
                return new JsonPrimitive(src);
            }
            if (src == longNum) {
                return new JsonPrimitive(longNum);
            } else {
                return new JsonPrimitive(src);
            }
        }
    });
   
    Gson gson = gsonBuilder.create();

使用:

Type typeToken = new TypeToken>>(){}.getType();
    String jsonStr="{\"data\":{\"flag\":0.0,\"createTime\":1.641811578E12,\"money\":10.12}}";
Response response = gson.fromJson(jsonStr,typeToken); //泛型T数据成员没改变
jsonStr=  gson.toJson(bean)//序列化触发JsonSerializer,泛型T数据成员改变

上面Gson设置也可以综合起来,看实际需求定义

你可能感兴趣的:(解决GSON转Long型变为科学计数法或整形变double的问题(自动转换成Double类型)