后端返回 Long 类型,前端精度丢失

1,333 阅读1分钟

约定

如下是对本文的讨论背景做出的约定

  • 语言 : 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 框架自动处理,因此也不用担心!