问题复盘|在使用 gson 时,数字被自动转为 double 类型

背景

在将一个 JsonObject 转成 Map 的时候,数字全部被转成了 double 类型,
如下所示,年龄从 2 变成了 2.0,身高正常显示 98.2,登记时间成了 1.694533284627E12

   /**
    * name=小红
    * record_time=1.694533284627E12
    * age=2.0
    * height=98.2
    */
    public static void main(String[] args) {
        JsonObject jsonObject = new JsonObject();
        jsonObject.addProperty("name", "小红");
        jsonObject.addProperty("age", 2);
        jsonObject.addProperty("height",98.2);
        jsonObject.addProperty("record_time", System.currentTimeMillis());
        Map<String, Object> result = new Gson().fromJson(jsonObject, new TypeToken<HashMap<String, Object>>() {
        }.getType());
        for (Map.Entry entrySet : result.entrySet()){
            System.out.println(entrySet.getKey()+"="+entrySet.getValue());
        }
    }

排查过程

面对搜索引擎编程,我肯定不是第一个踩坑的,果不其然

https://stackoverflow.com/questions/15507997/how-to-prevent-gson-from-expressing-integers-as-floats

从解释中可以看出,gson 默认将 number 类型的数据解析成了 double 类型

case NUMBER:
  return in.nextDouble();

并且提到此问题已在版本 2.8.9 中修复

google fixed issue
https://github.com/google/gson/commit/fe30b85224316cabf19f5dd3223843437c297802#diff-9bf510cca1fa5b32b008e7daa417abf15602571dbc87f5436d9f3558ded492a5 please update gson version to 2.8.9

查看自己的版本号为 2.8.6 低于 2.8.9,且也有相同情况

        <dependency>
            <groupId>com.google.code.gsongroupId>
            <artifactId>gsonartifactId>
            <version>2.8.6version>
        dependency>

问题复盘|在使用 gson 时,数字被自动转为 double 类型_第1张图片

解决方案

问题已定位,就比较好解决
首先将 gson 版本升到 2.8.9,然后在创建 gson 对象的时候手动设置数字类型的转换策略,问题解决,如下

        <dependency>
            <groupId>com.google.code.gsongroupId>
            <artifactId>gsonartifactId>
            <version>2.8.9version>
        dependency>
    /**
     * name=小红
     * record_time=1694534362190
     * age=2
     * height=98.2
     */
    public static void main(String[] args) {
        JsonObject jsonObject = new JsonObject();
        jsonObject.addProperty("name", "小红");
        jsonObject.addProperty("age", 2);
        jsonObject.addProperty("height",98.2);
        jsonObject.addProperty("record_time", System.currentTimeMillis());
        // 手动设置数字类型数据的转换策略
        GsonBuilder gson = new GsonBuilder().setNumberToNumberStrategy(ToNumberPolicy.LONG_OR_DOUBLE)
                .setObjectToNumberStrategy(ToNumberPolicy.LONG_OR_DOUBLE);
        Map<String, Object> result = gson.create().fromJson(jsonObject, new TypeToken<HashMap<String, Object>>() {
        }.getType());
        for (Map.Entry entrySet : result.entrySet()){
            System.out.println(entrySet.getKey()+"="+entrySet.getValue());
        }
    }

我不是第一个踩此坑的,肯定也不会是最后一个踩此坑的,简单记录,等待有缘人

你可能感兴趣的:(问题排查记录,json,java,Gson)