0


后端传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.js

bignumber.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 类型序列化为字符串类型。

标签: spring boot js 前端

本文转载自: https://blog.csdn.net/weixin_58724261/article/details/130974162
版权归原作者 源末coco 所有, 如有侵权,请联系我们删除。

“后端传long类型数据到前端精度丢失问题”的评论:

还没有评论