项目中使用 fastjson 来处理 json 格式,当前使用的版本为1.1.37。在和其它系统交互时,将一个json串传给了对方,原值为5.0,json 处理后格式为:{"dou", 5}; 结果对方处理该串报错了, 缘由是他将串整理转成 Map ,在取值时强制转为了 Double ,由于拿到的值转化是 Integer 类型,强转确定异常了。 简单的作法应该经过 Double.valueOf(value) 进行处理。但无奈合做方不肯意处理。 因而测试了下fastjson处理这个串时,经过如下作处理, 输出的结果为 {"dou", 5}。git
JSONObject jsonObject = new JSONObject(); Double dou = new Double(5.0); jsonObject.put("dou", dou); System.out.println(JSON.toJSONString(jsonObject));
想要输出{"dou",5.0} 怎么办, 跟踪了下源码,发如今 DoubleSerializer 的 write 方法中,判断告终尾若是是.0 就截掉了。github
doubleText = Double.toString(doubleValue); if(doubleText.endsWith(".0")) { doubleText = doubleText.substring(0, doubleText.length() - 2); }
那想要的格式怎么办,能够经过自定义 filter 方式实现,:json
ValueFilter filter = new ValueFilter() { @Override public Object process(Object object, String name, Object value) { if(value instanceof BigDecimal || value instanceof Double || value instanceof Float){ return new BigDecimal(value.toString()); } return value; } }; String s = JSON.toJSONString(jsonObject, filter, new SerializerFeature[0]);
以上能够完美解决。后来想有没有跟好的方法呢。 因而网上搜索了一下,大多数都是这种作法,而且有人认为这是一个bug,因而忽然想有没有可能 wenshao 会处理一下,因而在 github 找到 fastjson 的最新版本 1.2.23。 先修改 pom 文件,而后运行。发现即便不处理也能输出了 {"dou",5.0} 。 因而 debug 进去原来对 DoubleSerializer 进行了重写,并在 write 方法中原来处理格式的地方修改成以下:ide
if (decimalFormat == null) { out.writeDouble(doubleValue, true); } else { String doubleText = decimalFormat.format(doubleValue); out.write(doubleText); } //out SerializeWriter String doubleText = Double.toString(doubleValue); if (isEnabled(SerializerFeature.WriteNullNumberAsZero) && doubleText.endsWith(".0")) { doubleText = doubleText.substring(0, doubleText.length() - 2); }
即,以上粉色代码调用 SerializeWriter 的writeDouble 方法, 看绿色部分。 同时判断了 SerializerFeature.WriteNullNumberAsZero 和 结尾是否为 .0测试
就是经过这个解决了 double 精度的正常输出。 在使用 1.2.23时若是想输出{"dou", 5}, 能够经过设置 SerializerFeature.WriteNullNumberAsZero 实现。spa
System.out.println(JSON.toJSONString(jsonObject, SerializerFeature.WriteNullNumberAsZero));
啰嗦了这么,但愿经过升级版本解决一样遇到这样问题的小伙伴。debug