解决后端传long类型数据到前端精度丢失问题

 更新时间:2024年01月30日 09:58:40   作者:源末coco  
这篇文章主要介绍了解决后端传long类型数据到前端精度丢失问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

后端传long类型数据到前端精度丢失

在 Spring Boot 中,将 long 类型传输到前端时,会发现该类型的值可能会出现精度丢失的问题。

这是因为在 JavaScript 中,数字类型默认会被转换为双精度浮点数,而双精度浮点数的精度有限,只能精确表示 2 的 53 次方以内(即 Number.MAX_SAFE_INTEGER,约为 9 x 10^15)的整数。

对于超过该范围的长整数,JavaScript 会发生精度丢失,导致值变得不准确。

解决方案一

将 long 转换为字符串

1:在后端将 long 类型的值转换为字符串类型,可以使用 String.valueOf() 方法或者 Long.toString() 方法

如下所示:

long num = 123456789012345L;
String str = String.valueOf(num);
// 或者
String str = Long.toString(num);

2:在前端通过 AJAX 请求获取该字符串类型的值,并将其解析为数字类型。

由于 JavaScript 中的数值类型默认使用 IEEE 754 标准的双精度浮点数表示,因此需要使用 JavaScript 的 BigInt() 方法将其转换为大整数类型。

let str = "123456789012345";
let num = BigInt(str);

解决方案二

使用第三方库进行高精度运算

1:在后端将 long 类型的值转换为 BigDecimal 类型(Java 中的高精度类型),并通过 JSON 序列化后传递到前端。

这里以 Spring Boot 中使用 FastJSON 序列化为例

如下所示:

BigDecimal num = new BigDecimal("123456789012345");
String jsonStr = JSON.toJSONString(num);

2:在前端使用第三方库 big.jsbignumber.js 进行高精度运算。

这里以 big.js 为例,首先需要引入 big.min.js 文件,在代码中使用 Big() 类构造高精度对象,并进行相应的运算。

<script src="big.min.js"></script>
let num = new Big("123456789012345");
let result = num.plus(1);

还可以使用注解来解决long类型的精度丢失问题

Spring Boot 中提供了 @JsonFormat 注解,可以对实体类中的属性进行序列化和反序列化格式化。

对于 long 类型的属性,可以设置其格式为字符串类型,并在前端进行相应的处理,以保持其精度不丢失。

具体实现方式

1:在实体类中添加 @JsonFormat 注解,设置其 shape 属性为 JsonFormat.Shape.STRING

如下所示:

public class Example {
    @JsonFormat(shape = JsonFormat.Shape.STRING)
    private Long num;
}

2:在前端获取该值时,直接使用字符串类型进行处理

如下所示:

let numStr = data.num;

Spring Boot 中可以通过配置文件来解决 long 类型的精度丢失问题。

在 Spring Boot 的配置文件 application.properties 中添加如下配置:

spring.jackson.serialization.WRITE_DATES_AS_TIMESTAMPS=false
# 将 long 类型序列化为字符串类型
spring.jackson.serialization.WRITE_NUMBERS_AS_STRINGS=true

其中,

  • WRITE_DATES_AS_TIMESTAMPS 表示是否将日期类型序列化为时间戳类型,默认为 true,这里设置为 false 如果需要将日期类型序列化为时间戳类型,则不需要设置此属性。
  • WRITE_NUMBERS_AS_STRINGS 则表示是否将数字类型序列化为字符串类型,默认为 false,这里设置为 true 即可将 long 类型序列化为字符串类型。

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • mybatis的增删改查运用方式

    mybatis的增删改查运用方式

    这篇文章主要介绍了mybatis的增删改查运用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-11-11
  • javabean 中使用@Transient属性处理临时字段

    javabean 中使用@Transient属性处理临时字段

    @Transient表示该属性并非一个到数据库表的字段的映射,ORM框架将忽略该属性,本文给大家介绍javabean 中临时字段的处理:@Transient,感兴趣的朋友跟随小编一起看看吧
    2023-08-08
  • java策略枚举:消除在项目里大批量使用if-else的优雅姿势

    java策略枚举:消除在项目里大批量使用if-else的优雅姿势

    这篇文章主要给大家介绍了关于Java彻底消灭if-else的8种方案,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习吧
    2021-06-06
  • Springboot中LocalDateTime对象返回给前端格式化解决方案

    Springboot中LocalDateTime对象返回给前端格式化解决方案

    在项目开发当中前后端使用什么样的时间格式,是一个值得关注的问题,这篇文章主要给大家介绍了关于Springboot中LocalDateTime对象返回给前端格式化的解决方案,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2024-04-04
  • 详解Java 类的加载机制

    详解Java 类的加载机制

    这篇文章主要介绍了Java 类的加载机制,帮助大家更好的理解和学习Java,感兴趣的朋友可以了解下
    2020-08-08
  • Spring MVC中使用Controller如何进行重定向

    Spring MVC中使用Controller如何进行重定向

    这篇文章主要介绍了Spring MVC中使用Controller如何进行重定向操作,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-09-09
  • MyBatisPlus的使用最全实例详解

    MyBatisPlus的使用最全实例详解

    MyBatis-Plus是MyBatis增强工具,简化开发并提升效率,内置通用Mapper、Service及条件构造器,支持动态SQL、分页查询与注解配置,适用于单表操作,复杂SQL可手动编写,减少样板代码,优化开发体验
    2025-09-09
  • 使用jib插件为Java应用构建镜像的方法

    使用jib插件为Java应用构建镜像的方法

    这篇文章主要介绍了使用jib插件为Java应用构建镜像,要是用户本地没安装docker,可以使用jib制作出带有镜像的tar文件,本文通过实例代码给大家介绍的非常详细,需要的朋友可以参考下
    2022-08-08
  • java Spring的启动原理详解

    java Spring的启动原理详解

    大家好,本篇文章主要讲的是java Spring的启动原理详解,感兴趣的同学赶快来看一看吧,对你有帮助的话记得收藏一下
    2022-01-01
  • Spring  @Scheduled中这些参数的区别、组合和应用场景解析

    Spring  @Scheduled中这些参数的区别、组合和应用场景解析

    SpringBoot中的定时任务调度提供了多种方式,包括 cron 表达式、fixedRate、fixedDelay 和 initialDelay,每种方式都有其特点和适用场景,通过合理配置,可以满足不同任务的调度需求,本文介绍Spring  @Scheduled中这些参数的区别、组合和应用场景解析,感兴趣的朋友一起看看吧
    2026-01-01

最新评论