今天用Gson去对接Json,然后就出现了一个问题。对方给出的文档说该值是Number类型,然后又是金额相关的,我就直接用了BigDecimal接受,然后json转实体类的时候就出问题了。
java.lang.NumberFormatException
我感觉自己没写错啊,又试了几次,发现还是转换异常,那想了想应该文档有点问题,可能有数据不是Number类型,开始排查。
最后发现是一个key不能是BigDecimal类型,把返回的json数据格式化,然后搜索key。对比value,大部分都是数字的(没有用到三位分节法之类的),目前没有发现什么问题。
然后实体类把BigDecimal改成String,输出下实体类的toString,快捷键搜索,就发现了有些数据是这种结果:
// xx是Number类型 xx=,aa="aaa" xx="0.00",aa="bbb"
xx就直接是=,后面什么也没有,找到问题点了。根据关键字,找到对应的Json数据行,发现所有拿到的json数据全部是String类型,被""给引起来的,不管是Number类型还是String类型。
就出现了一个情况:返回的Number类型中有"",也有"0.00","0.00"能被转换,但是""就转换失败了,不能被转成BigDecimal。
后来和对方说了下这个问题,直接用String,但是我感觉不对劲,虽然Json用""引起来的String来存Number我个人感觉不是个好习惯,但是你也不能说""就转不了BigDecimal了吧?
鉴于被Gson坑了几次了,说实话,真的感觉Gson有点废,总出现几个出乎意料的结果。
然后试试了fastjson,对比了他们对同一个数据的处理结果:
<dependency> <groupId>com.google.code.gson</groupId> <artifactId>gson</artifactId> <version>2.8.5</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.72</version> </dependency>
public static void main(String[] args) { String jsonStr = "{\"aa\":\"\"}"; JSONObject jsonObject = JSON.parseObject(jsonStr); System.out.println(jsonObject.get("aa")); System.out.println(jsonObject.getString("aa")); System.out.println(jsonObject.getBigDecimal("aa")); System.out.println("--------------------------"); Gson gson = new Gson(); JsonObject jsonObject1 = gson.fromJson(jsonStr, JsonObject.class); System.out.println(jsonObject1.get("aa")); System.out.println(jsonObject1.get("aa").getAsString()); System.out.println(jsonObject1.get("aa").getAsBigDecimal()); }
下方是输出结果:
fastjson是空白,空白,null
gson是"",空白,转换异常。
哎,感觉gson比较不太行啊。虽然每个api的设计都有自己的考量,但是感觉这里不应该说转换异常的,用null表示更好一些。