一、问题背景
在我们的项目中经常会有前端解析后端返回的数据出现精度丢失的问题,如下所示:
后端返回前端的数据:
uuid:1534595659129294849
前端解析后的数据:
uuid:1534595659129294800
原因如下:
在JavaScript中,存在两种数字。Number和BigInt。最常用的,就是number。最大的Number,叫做Number.MAX_SAFE_INTEGER,它的值为:
2^53-1 或者+/- 9,007,199,254,740,991
众所周知,Java中的Long,是64位的。Js中的这个Number在长度大于17位时会出现精度丢失的问题。
二、解决方案
1.简单的解决方案只需要使用fastjson的ToStringSerializer注解,让系统序列化时,保留相关精度即可。
@JsonSerialize(using = ToStringSerializer.class)
private String uuid;
2.当然我们也可以对using的值自己进行拓展,实现不同的转换,例如
自定义一个类来继承JsonSerializer类来重写serialize方法,进行自定义转换
public class DateToLongSerializer extends JsonSerializer<Date> {
@Override
public void serialize(Date date, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
jsonGenerator.writeNumber(date.getTime() / 1000);
}
}
类字段上声明注解
@JsonSerialize(using = DateToLongSerializer.class)
private Date createTime;
3.我们也可以使用全局配置的方式
spring.jackson.generator.write-numbers-as-strings=true