约定
如下是对本文的讨论背景做出的约定
- 语言 : java
- 框架 : Spring boot (Spring web)
- json 序列化、反序列化工具 : Jackson
- 传输协议 : http
- 接口返回值格式 : JSON
背景
在后端开发中,经常使用 雪花id 作为表的主键,在 java 中使用 Long 类型存储,然后在接口返回时,通过 json 序列化,传输到前端。
然后前端的 js 语言,long 类型被设计成 2^53 位,小于 java 中 2^64 位,导致精度丢失。
解决方案
以 Spring web 自带的 Jackson 为例
局部处理
在 Long 类型字段上加 @JsonSerialize(using = ToStringSerializer.class) 注解,将该字段序列化成字符串
全局处理
全局配置 Jackson 序列化策略,将 Long 序列化 String
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
@Configuration
public class JacksonConfig {
@Bean
public Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer() {
return jacksonObjectMapperBuilder -> {
// Jackson全局转化long类型为String,解决jackson序列化时传入前端Long类型缺失精度问题
jacksonObjectMapperBuilder.serializerByType(BigInteger.class, ToStringSerializer.instance);
jacksonObjectMapperBuilder.serializerByType(Long.class, ToStringSerializer.instance);
jacksonObjectMapperBuilder.serializerByType(Long.TYPE, ToStringSerializer.instance);
};
}
}
注意:全局序列化,会导致不存在精度丢失的 Long 类型字段,也被序列化成字符串。不过反序列化时,字符串类型的数据都可以被 Spring 框架自动处理,因此也不用担心!