解决后端传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 类型序列化为字符串类型。

总结

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

相关文章

  • 详解SpringBoot读取配置文件的N种方法

    详解SpringBoot读取配置文件的N种方法

    这篇文章主要介绍了详解SpringBoot读取配置文件的N种方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-02-02
  • SSM框架+Plupload实现分块上传大文件示例

    SSM框架+Plupload实现分块上传大文件示例

    这篇文章主要介绍了SSM框架+Plupload实现分块上传示例(Spring+SpringMVC+MyBatis+Plupload),将用户选中的文件(可多个)分隔成一个个小块,依次向服务器上传,有兴趣的可以了解一下。
    2017-03-03
  • spring cloud之eureka高可用集群和服务分区解析

    spring cloud之eureka高可用集群和服务分区解析

    这篇文章主要介绍了spring cloud之eureka高可用集群和服务分区解析,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-03-03
  • java基于servlet编写上传下载功能 类似文件服务器

    java基于servlet编写上传下载功能 类似文件服务器

    这篇文章主要为大家详细介绍了java基于servlet编写上传下载功能,类似文件服务器,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2016-07-07
  • Spring Cloud详细讲解zuul集成Eureka流程

    Spring Cloud详细讲解zuul集成Eureka流程

    这篇文章主要介绍了Spring Cloud zuul集成Eureka,Eureka Client中内置一个负载均衡器,用来进行基本的负载均衡,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-06-06
  • Java中如何计算一段程序的运行时间

    Java中如何计算一段程序的运行时间

    这篇文章主要介绍了Java中如何计算一段程序的运行时间问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-03-03
  • MyBatis中多对一和一对多数据的处理方法

    MyBatis中多对一和一对多数据的处理方法

    这篇文章主要介绍了MyBatis中多对一和一对多数据的处理,本文通过示例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-01-01
  • SpringCloud Feign使用ApacheHttpClient代替默认client方式

    SpringCloud Feign使用ApacheHttpClient代替默认client方式

    这篇文章主要介绍了SpringCloud Feign使用ApacheHttpClient代替默认client方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-03-03
  • dom4j创建和解析xml文档的实现方法

    dom4j创建和解析xml文档的实现方法

    下面小编就为大家带来一篇dom4j创建和解析xml文档的实现方法。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-06-06
  • Java多文件以ZIP压缩包导出的实现方法

    Java多文件以ZIP压缩包导出的实现方法

    这篇文章主要为大家详细介绍了Java多文件以ZIP压缩包导出的实现方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-07-07

最新评论