2019-06-12 关于微服务大数字精度丢失解决方案

前后台数据传输大数字精度丢失解决方案

原理:将数字类型的字段序列化时转换为字符串(当前环境为 js - 前台Controller - 后台Controller)

  1. 前台包java 实体12位以上数字属性上或者get方法加注解(PS:个别项目,如果列表页面也使用大数据字段,则后台包java 实体也需要加注解,具体原因待查)
@JsonSerialize(using = ToStringSerializer.class) 
private BigDecimal num;
  1. 此步骤按需修改。上述操作序列化后数据为:123456789012345678.000000(mysql 小数位数根据数据库定义字段小数位长度自动补了0) 如果需要去除末尾无用的0, 数据库中,12位以上数字去掉后补的0 或者 前台实体12位以上数字属性的set方法改造
public void setGbje(BigDecimal gbje){
    if (gbje != null) {
        this.gbje = new BigDecimal(gbje.stripTrailingZeros().toPlainString());
    }
}

以上方法可以解决js 与 controller、前台controller 与 后台controller 之间大数字传输精度丢失问题。缺点是每个用到大数字的实体都需要进行配置。
本文所有方法只能解决传输过程、js 接收数据精度丢失问题。不能解决前台Js大数字运算精度丢失问题,大数字运算最好放到Java中。

其他方法(仅作参考):

方法一:解决反序列化时,BigDecimal类型精度缺失
PmServiceServiceApplication.java 增加如下配置

@Bean
public MappingJackson2HttpMessageConverter getMappingJackson2HttpMessageConverter() {
    MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter = new MappingJackson2HttpMessageConverter();
    //设置日期格式
    ObjectMapper objectMapper = new ObjectMapper();
    objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
    // 反序列化时,使用BigDecimal转换Number类型的属性。防止转为Double时精度丢失
    objectMapper.enable(DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS);
    mappingJackson2HttpMessageConverter.setObjectMapper(objectMapper);
    return mappingJackson2HttpMessageConverter;
}

此方法可以解决前台controller 到后台controller ,反序列化时数字精度丢失问题,也可以修改其他数据类型的格式。

方法二: 解决Js json字符串转换为js对象时精度缺失
用正则匹配json中的12位以上数字,替换为字符串。
以当前项目为例:修改前台 ajaxdatawrap.js 中convertJsonToDC方法,用正则表达式匹配每个大于12位的数字,替换为字符串。

var matchStr = dataArray.match(/":(-?\d+){12,}(\.\d+)?,"/g); // 匹配所有 "/ + 12位以上的数字 + ," 格式的数据,匹配规则加上前后符号是为了尽量确保数据准确
    if (matchStr) {
        for (var i=0, length = matchStr.length; i < length; i++) {
            dataArray = dataArray.replace(matchStr[i], matchStr[i].slice(0,2) + '\"' + matchStr[i].slice(2, -2) + '","'); // 给数字前后补上双引号,解决
        }
}

此方法可以解决js接收到controller数据之后,转为js对象时,精度丢失问题(列表页面中,前台controller所接收大数字字段精度已经丢失,与js无关)。
缺点:不准确(小概率,正则表达式有可能替换掉不是数字但是符合条件的数据)

你可能感兴趣的:(2019-06-12 关于微服务大数字精度丢失解决方案)