最近在做开发的时候遇到了一个奇怪的问题,java后端使用雪花算法生成的long类型主键id,传到前端的时候会出现精度丢失。
后来查了下原因是因为long类型转成二进制是64位的,而js的Number类型精度只有53位,即Number的最大值只有Math.pow(2, 53)=9007199254740992,而雪花算法算出来的值有18/19位,远远大于该值。
从浏览器中也可以验证这个问题的存在。
解决思路是:后台传到前台时,Long类型数据,转为String类型。
由于后台采用了spring boot 输出采用的是默认的Jackson,查询官方文档可以发现有3种方法可以实现
1、配置参数write_numbers_as_strings(未验证)
Jackson有个配置参数WRITE_NUMBERS_AS_STRINGS,可以强制将所有数字全部转成字符串输出。其功能介绍为:Feature that forces all Java numbers to be written as JSON strings.。使用方法很简单,只需要配置参数即可:
spring: jackson: generator: write_numbers_as_strings: true
缺点:所有的返回都变成了字符串
2、使用注解
在需要转换的属性上面加上@JsonFormat(shape = JsonFormat.Shape.STRING)注解,如:
@JsonFormat(shape = JsonFormat.Shape.STRING) private Long userId;
缺点:量大的话太繁琐
3、自定义消息转换器
使用如下: