前端Long类型精度丢失

本文探讨了在前后端交互中,如何通过添加注解和全局配置解决Long类型id在序列化时精度丢失的问题,提供两种解决方案并给出了测试实践。

描述

  • 在后台返回的Long类型的id为长整型:1400467439103381504,但是在前端接收参数造成末尾精度丢失:1400467439103381500

解决

1、在实体类字段上添加注解

@JsonFormat(shape = JsonFormat.Shape.STRING)

在这里插入图片描述

OR

2、全局配置

  • 继承WebMvcConfigurer
	/**
     * 配置返回前端Json
     * @param: builder
     * @return: com.fasterxml.jackson.databind.ObjectMapper
     * @author: HL
     * @date: 2021/12/27 14:17
     */
    @Bean
    public ObjectMapper jacksonObjectMapper(Jackson2ObjectMapperBuilder builder) {
        ObjectMapper objectMapper = builder.createXmlMapper(false).build();

        // 将Long类型序列化成String类型 防止Long类型造成前端精度丢失
        SimpleModule simpleModule = new SimpleModule();
        simpleModule.addSerializer(Long.class, ToStringSerializer.instance);
        simpleModule.addSerializer(Long.TYPE, ToStringSerializer.instance);
        objectMapper.registerModule(simpleModule);

        return objectMapper;
    }
  • 测试:
    在这里插入图片描述

在这里插入图片描述

<think>首先,用户的问题是:如何解决JavaScript前端处理long类型数值精度丢失的问题。这涉及到处理超过53位的整数时,JavaScript的Number类型丢失精度的问题。 关键点: - JavaScript使用IEEE 754双精度浮点数表示数字,整数范围是-2^53到2^53。 - 当后端返回的long类型数值(如Javalong,64位)超过这个范围时,前端解析时会丢失精度。 - 解决方案包括使用字符串表示、BigInt、或第三方库。 解决方案步骤: 1. **后端配合**:确保后端返回数值时以字符串形式发送,而不是直接作为JSON数字。这样前端可以解析为字符串,避免精度丢失。 2. **前端处理**: - 使用BigInt:现代浏览器支持BigInt,可以直接处理大整数。 - 使用第三方库:如json-bigint,它可以解析JSON时自动处理大整数。 - 手动处理:解析JSON时,使用reviver函数将特定字段转换为字符串或BigInt。 系统指令要求: - 行内数学表达式用$...$,例如数字范围。 - 独立公式用$$...$$,但这里可能不需要。 - 使用中文回答。 - 生成相关问题。 - 回答中引用的段落末尾自然地添加引用标识。参考引用是[^1],但它是关于长整型处理的,我需要自然地引用它。 回答结构: - 先解释问题原因。 - 然后提供解决方案。 - 包括代码示例。 - 最后生成相关问题。 参考引用: - 引用[1]是关于克服JavaScript长整型精度丢失的挑战,所以我应该在相关部分引用它,如"如引用[1]所述"。 代码示例: - 展示如何使用BigInt或json-bigint。 生成相关问题: - 基于主题,生成3-4个相关问题。 完整回答: 1. **问题解释**:简要说明为什么精度丢失发生。 2. **解决方案**: - 后端修改:建议后端返回字符串。 - 前端方法: - 使用BigInt。 - 使用json-bigint库。 - 手动解析。 3. **代码示例**:提供JavaScript代码。 4. **相关问题**:在最后生成相关问题。 确保语言流畅、中文。</think>### JavaScript 前端处理 long 类型数值精度丢失问题 在 JavaScript 中,数字类型基于 IEEE 754 双精度浮点数标准,其整数范围被限制在 $[-2^{53}, 2^{53}]$(约 $-9e15$ 到 $9e15$)之间。当后端返回的 long 类型数值(如 Java 中的 64 位整数)超出此范围时,前端解析 JSON 数据时会出现精度丢失问题。例如,数值 $1234567890123456789$ 可能被错误解析为 $1234567890123456800$。以下是系统的解决方案: #### 1. **问题原因分析** - JavaScript 的 `Number` 类型无法精确表示超过 53 位的整数,导致高位数字被截断或四舍五入[^1]。 - 常见场景:后端(如 Java、C#)返回包含 long 类型字段的 JSON 数据,前端通过 `JSON.parse()` 解析时发生精度丢失。 #### 2. **解决方案** ##### (1) 后端配合:返回字符串格式 - 建议后端将 long 类型数值以字符串形式返回,避免直接作为 JSON 数字。例如: ```json // 后端响应示例(Java/Spring Boot) { "id": "1234567890123456789", // 字符串格式 "name": "example" } ``` - 优点:简单可靠,兼容所有浏览器。 ##### (2) 前端处理:使用 BigInt 类型 - **适用场景**:现代浏览器(Chrome 67+、Firefox 68+、Edge 79+)支持 `BigInt`,可直接处理大整数。 ```javascript // 解析 JSON 时手动转换字符串为 BigInt const response = '{"id": "1234567890123456789"}'; const data = JSON.parse(response, (key, value) => { if (key === 'id') return BigInt(value); // 指定字段转换 return value; }); console.log(data.id.toString()); // 输出: "1234567890123456789" ``` - **注意**:`BigInt` 无法直接与 `Number` 运算,需调用 `.toString()` 或使用 `BigInt` 运算符(如 `+` 改为 `+n`)。 ##### (3) 前端处理:使用第三方库(推荐) - **json-bigint 库**:自动解析 JSON 中的大整数为 `BigInt` 或字符串。 1. 安装库: ```bash npm install json-bigint ``` 2. 使用示例: ```javascript import JSONBig from 'json-bigint'; const response = '{"id": 1234567890123456789}'; const data = JSONBig({ storeAsString: true }).parse(response); // 转为字符串 console.log(data.id); // 输出: "1234567890123456789" ``` - **选项**: - `storeAsString: true`:将大整数转为字符串。 - 默认行为:转为 `BigInt` 对象。 - 其他库:`bignumber.js` 或 `decimal.js`,适用于复杂数学运算。 ##### (4) 手动解析:正则替换法 - 如果无法修改后端或使用库,可通过正则表达式预处理 JSON 字符串: ```javascript const response = '{"id": 1234567890123456789}'; const safeResponse = response.replace(/"(\w+)":\s*(\d{15,})/g, '"$1": "$2"'); const data = JSON.parse(safeResponse); // id 自动转为字符串 ``` - **缺点**:可能误替换非 ID 字段,需谨慎使用。 #### 3. **最佳实践** - **优先方案**:后端返回字符串 + 前端使用 `json-bigint` 库,兼顾兼容性和安全性。 - **测试建议**:使用 Jest 等工具验证边界值,如数值 $2^{53} + 1$($9007199254740993$)。 - **性能注意**:`BigInt` 运算比 `Number` 慢,仅在必要时使用。 通过以上方法,可有效避免 long 类型数值的精度丢失问题,确保数据完整性[^1]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

hanlin-hl

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值