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

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

public class Response<T> {

   /**
    * 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<LinkedTreeMap<String, Object>>(){}.getType(),
            new JsonDeserializer<LinkedTreeMap<String, Object>>() {
                @Override
                public LinkedTreeMap<String, Object> deserialize(
                        JsonElement json, Type typeOfT,
                        JsonDeserializationContext context) throws JsonParseException {

                    LinkedTreeMap<String, Object> treeMap = new LinkedTreeMap<>();
                    JsonObject jsonObject = json.getAsJsonObject();
                    Set<Map.Entry<String, JsonElement>> entrySet = jsonObject.entrySet();
                    for (Map.Entry<String, JsonElement> 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<Response<LinkedTreeMap<String, Object>>>(){}.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<Double>() {
        @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<Response<LinkedTreeMap<String, Object>>>(){}.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源码注释及wiki所作的原创内容,转载请注明出处。 该系列其它文章 你真的会用G...
    怪盗kidou阅读 78,632评论 119 213
  • 转自:http://www.jianshu.com/p/3108f1e44155?nomobile=yes 该系列...
    逍遥游lx阅读 1,185评论 0 2
  • 原文地址:https://www.jianshu.com/p/e740196225a4 主要内容 1.TypeAd...
    盼旺阅读 345评论 0 2
  • 1.概述2.Gson的目标3.Gson的性能和扩展性4.Gson的使用者5.如何使用Gson 通过Maven来使用...
    人失格阅读 14,414评论 2 18
  • 基本规范 推荐使用 private 类型,支持使用 final 声明 支持 null 值,序列化输出时自动跳过,反...
    Wavky阅读 3,197评论 0 1