首页 > 其他分享 >Long类型后端到前端精度丢失问题

Long类型后端到前端精度丢失问题

时间:2024-10-26 13:16:05浏览次数:3  
标签:后端 Spring Boot Long JSON 丢失 序列化 ObjectMapper

 在开发中,后端经常需要处理一些大数值的 Long 类型数据(id等)。但当这些数据通过接口传递到前端时,可能会出现精度丢失的问题。

原因:JavaScript 的 Number 类型遵循 IEEE 754 双精度浮点数标准,只能精确表示范围在 -(2^53 - 1)2^53 - 1 之间的整数(约等于 -90071992547409919007199254740991)。这意味着,任何超过这个范围的整数在 JavaScript 中都无法精确表示。例如:

console.log(9007199254740991);    // 输出:9007199254740991(准确)
console.log(9007199254740992);    // 输出:9007199254740992(准确)
console.log(9007199254740993);    // 输出:9007199254740992(精度丢失)

 在后端(例如 Java)中,Long 类型的范围是 -2^632^63 - 1,即 -92233720368547758089223372036854775807。这种数值在 Java 中可以被精确表示,但当通过 JSON 传递到前端的 JavaScript 环境时,由于 JavaScript 数字精度限制,往往会出现 精度丢失 的问题。

典型场景

当后端返回一个 ID 值 1234567890123456789,前端可能会收到 1234567890123456000,这样就导致了数据的错误。

解决方案

方案一:后端将 Long 类型序列化为 String 类型

一种简单有效的解决方案是,将后端的 Long 类型值序列化为 String,这样前端会将其当作字符串处理,从而避免了精度丢失的问题。下面是具体的实现方法。

1. 使用 @JsonSerialize 注解单独处理字段

如果只是需要处理某个特定字段(例如 id),可以在字段上添加 @JsonSerialize 注解,指定 Jackson 使用 ToStringSerializer 序列化器。

import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;

public class PassengerQueryResp {

    @JsonSerialize(using = ToStringSerializer.class)
    private Long id;

    private Long memberId;
    private String name;
    private String idCard;

    // Getter 和 Setter
}

 配置了这个 ObjectMapper 之后,所有的 Long 类型字段在序列化时都会被转换为字符串格式,不再需要逐个字段添加注解。

2. 配置全局的 ObjectMapper 设置

如果需要对所有 Long 类型的字段进行字符串处理,可以在 Spring Boot 的配置类中定义一个全局 ObjectMapper Bean,使用 SimpleModule 注册 ToStringSerializer,这会对所有 Long 类型字段生效。

@Configuration
public class JacksonConfig {
    @Bean
    public ObjectMapper jacksonObjectMapper(Jackson2ObjectMapperBuilder builder) {
        ObjectMapper objectMapper = builder.createXmlMapper(false).build();
        SimpleModule simpleModule = new SimpleModule();
        simpleModule.addSerializer(Long.class, ToStringSerializer.instance);
        objectMapper.registerModule(simpleModule);
        return objectMapper;
    }
}

配置类的作用详解

JacksonConfig 类中,通过以下代码将 Long 类型序列化为 String

SimpleModule simpleModule = new SimpleModule();
simpleModule.addSerializer(Long.class, ToStringSerializer.instance);
objectMapper.registerModule(simpleModule);

具体工作原理

  1. Spring Boot 自动配置 ObjectMapper
    Spring Boot 自带 Jackson 作为默认的 JSON 处理库,并在后台自动配置了 ObjectMapper。当你在项目中引入 Jackson 时,Spring Boot 会自动加载一个全局共享的 ObjectMapper 实例,用于所有 JSON 序列化和反序列化操作。

  2. 控制器的自动 JSON 转换
    在 Spring MVC 中,控制器(@RestController@Controller)中的方法返回值会被自动转换为 JSON 格式,这个转换由 Spring Boot 的 ObjectMapper 处理。例如:

@RestController
public class UserController {
    @GetMapping("/user")
    public User getUser() {
        return new User(123456789012345L, "Alice");
    }
}
  • User 对象被返回时,Spring MVC 会自动使用 ObjectMapper 将其序列化为 JSON 响应发送给客户端。如果你配置了 JacksonConfig 类,Spring 会使用你配置的 ObjectMapper,因此所有 Long 类型字段会自动以字符串形式输出,避免精度丢失。

3.自定义 ObjectMapper 配置的全局效果
通过自定义 JacksonConfig,实际上是让 Spring Boot 使用你定义的 ObjectMapper Bean 作为全局配置。Spring Boot 会自动检测应用中的 ObjectMapper Bean,并将其用于所有 JSON 序列化和反序列化操作,这包括:

  • @RestController 返回的对象。
  • @RequestBody@ResponseBody 注解处理的 JSON 请求和响应。
  • 其他 Spring Boot 内部或第三方库需要 JSON 处理的地方。

总结

在后端开发中处理 Long 类型数据时,注意 JavaScript 的精度限制十分重要。通过配置 Jackson 的 ObjectMapper,可以让所有 Long 类型字段序列化为字符串,从而避免精度丢失的问题。Spring Boot 的自动化配置特性让我们无需手动调用 ObjectMapper,就能在全局范围内应用此配置,使得后端传递到前端的数据在大数值时也能准确无误。

标签:后端,Spring,Boot,Long,JSON,丢失,序列化,ObjectMapper
From: https://blog.csdn.net/qq_44199605/article/details/143252246

相关文章

  • LongRAG: 突破长文本理解的新范式
    在人工智能飞速发展的今天,大型语言模型(LLM)已经在多个领域展现出惊人的能力。然而,在处理长文本问答任务时,它们仍然面临着不少挑战。最近,来自中国科学院、清华大学等机构的研究团队提出了一个创新性的解决方案-LongRAG系统。这个系统巧妙地解决了现有技术的局限性,为......
  • Windows11系统imkrudt.dll文件丢失问题
    其实很多用户玩单机游戏或者安装软件的时候就出现过这种问题,如果是新手第一时间会认为是软件或游戏出错了,其实并不是这样,其主要原因就是你电脑系统的该dll文件丢失了或没有安装一些系统软件平台所需要的动态链接库,这时你可以下载这个imkrudt.dll文件(挑选合适的版本文件)把它放......
  • Windows11系统imkrmig.dll文件丢失问题
    其实很多用户玩单机游戏或者安装软件的时候就出现过这种问题,如果是新手第一时间会认为是软件或游戏出错了,其实并不是这样,其主要原因就是你电脑系统的该dll文件丢失了或没有安装一些系统软件平台所需要的动态链接库,这时你可以下载这个imkrmig.dll文件(挑选合适的版本文件)把它放......
  • 游戏《波西亚时光》启动错误:如何应对d3dx9_42.dll丢失导致的启动问题
    一、引言《波西亚时光》是一款深受玩家喜爱的游戏,但在玩家启动游戏时,有时可能会遇到“d3dx9_42.dll丢失”的错误提示,这使得玩家无法顺利进入游戏,影响了游戏体验。本文将详细探讨d3dx9_42.dll文件在游戏中的作用、丢失的原因以及有效的解决方法,帮助玩家解决这一启动问题,......
  • Windows系统出现cygwin1.dll缺失怎么解决,分享几个好用的cygwin1.dll丢失解决办法
    一、引言在使用Windows系统的过程中,用户可能会遇到各种DLL(动态链接库)文件缺失的问题,其中cygwin1.dll缺失是较为常见的一种。当系统提示cygwin1.dll丢失时,可能会导致相关程序无法正常运行,给用户带来不便。本文将详细探讨cygwin1.dll文件的作用、缺失的原因,并分享一些......
  • 数字IC后端实现 | Innovus各个阶段常用命令汇总
    应各位读者要求,小编最近按照Innovus流程顺序整理出数字IC后端项目中常用的命令汇总。限于篇幅,这次只更新到powerplan阶段。有了这份Innovus常用命令汇总,学习数字IC后端从此不再迷路!如果大家觉得这个专题还不错,想继续看数字IC后端实现powerplan之后的内容,欢迎在文末留言区留......
  • 基于SpringBoot+Vue的前后端分离的人工智能模型销售平台
    ✌全网粉丝20W+,csdn特邀作者、博客专家、CSDN新星计划导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌......
  • 前端用uni开发的陪玩系统,该如何使用呢?源码交付支持二开!后端使用php语言。
    使用前端用uni开发的陪玩系统,用户通常可以按照以下步骤进行操作:一、系统下载与安装下载uni-app开发工具:用户可以从uni-app的网站下载最新的开发工具。安装与配置:安装下载的开发工具,并按照官方文档或教程进行配置。如果系统需要依赖特定的插件或库,也应在此时进行安装......
  • 全面解读icudt52.dll丢失:专家视角下的Unicode与国际化恢复方案
    icudt52.dll是ICU(InternationalComponentsforUnicode)库的一部分,它提供了Unicode字符集和相关国际化功能的支持。当这个DLL文件丢失时,依赖于ICU库的应用程序可能无法正确显示和处理Unicode字符,从而导致国际化功能失效。以下是从专家视角出发,对icudt52.dll丢失问题的全面解读......
  • 《苍翼混沌效应》游戏启动提示bdlogmgr.dll文件丢失?简单几步轻松修复
    当您在启动《苍翼混沌效应》(BlazBlue:ChaosEffect)或任何其他游戏时遇到提示丢失bdlogmgr.dll文件的问题,通常这意味着您的游戏缺少了某个重要的动态链接库(DLL)文件。以下是一些可能的解决方法:重新安装游戏尝试卸载游戏,然后从官方渠道重新下载并安装最新版本的游戏。这可以确......