JAVA 前端丢失大Long精度问题

JAVA 前端丢失大Long精度问题

Mon Aug 19 2024
BigWind
3 minutes

使用JAVA开发Springboot项目,在后端使用LONG类型存储,前端获取数据会丢失精度

最近在使用RuoYi前后端分离版本发现问题,数据库的主键设计为雪花ID随机生成后,LONG类型的主键数据数据发送给前端精度丢失了

JAVASCRIPT
1
2
例如后端主键数据:7231278613075632128
       前端展示:7231278613075600000

可以看到前端数据的后几位变成了0,精度丢失

那么如何修复呢?#

核心思想:将大LONG类型JSON数据序列化为String字符串再传给前端,由前端处理

局部解决#

使用JSON序列化注解指定到具体字段

JAVA
1
2
3
4
5
6
7
8
@Data
public class SysResource implements Serializable {
    /**
     * 主键id
     */
    @JsonSerialize(using = LongToStringConverter.class)
    private Long id;
}
JAVA
1
2
3
4
5
6
7
8
9
10
@Component
public class LongToStringConverter extends JsonSerializer<Long> {

    @Override
    public void serialize(Long aLong, JsonGenerator jsonGenerator,
                          SerializerProvider serializerProvider) throws IOException {
        jsonGenerator.writeString(aLong.toString());
    }
}

优点与问题#

优点:只改变某个字段,影响可控且直观容易测试

缺点:项目存在大量大LONG类型字段传给前端添加繁琐且易遗漏

整体统一解决#

JAVA
1
2
3
4
5
6
7
8
9
10
11
12
//统一将 Long 类型序列化为 String
@Configuration
public class JacksonConfiguration {

    @Bean
    public Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer() {
        return builder -> {
            // 把 Long 类型序列化为 String
            builder.serializerByType(Long.class, ToStringSerializer.instance);
        };
    }
}

优点与问题#

优点:整体统一改变序列化方式,可自定义,可通过排除代码来排除部分LONG序列化的字段

缺点:项目框架可能有兼容问题,前端已完成部分需要改动,例如ruoyi框架的pageNumber是LONG类型,前端控制台会报错需要在前端做类型转换或者在序列化容器代码里排除

总结#

统一改变序列化方式解决前端丢失大Long精度问题更有自定义能力,可将部分字段排除,且符合SpringBoot的设计思想,但要注意项目本身的框架结构和已完成部分代码的影响,避免出现类型冲突

参考#

雷丰阳-项目开发中的小技巧