当前位置: 首页 > news >正文

浏览器中的 preview 和 response 的值不一致和精度问题解决

今天遇到一个问题,数据库数据无误,接口请求数据无误,但在浏览器发起请求后,接口数据在浏览器的 previewresponse 中显示不一致。数据库中的数据类型是 bigint,实体类对应的数据类型是 Long。问题表现如下:

查询数据库的入口和出口加了日志  显示出来都是对的  但是最终返回到浏览器中确不对了

原因

JavaScriptNumber 类型不能完全表示 JavaLong 类型数字。当 Long 类型的长度超过 17 位时,会出现精度丢失的问题。浏览器在解析超过 17 位的数字时,超出的部分会被转换为 0,导致显示不一致。具体原因如下:

  • JavaScript Number 精度限制JavaScript 中的 Number 类型是双精度浮点数,可以安全地表示的整数范围是 -90071992547409919007199254740991(即 15 位数字)。当数字长度超过 15 位时,会发生精度丢失,超过 17 位的部分则会直接变成 0
  • 精度丢失示例:例如,JavaLong 类型值为 1816022064764096513,但在 JavaScript 中,超过 17 位的部分可能会变成 1816022064764096000

解决方案

为了避免精度丢失,可以在后台将超过精度的 Long 型数据转换为 String 类型。这确保了在传输过程中数字不会丢失精度,并且前端可以正确地显示这些数据。

修改方式一:【强烈推荐】

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;import java.io.IOException;/*** Description: [解决 Jackson 导致 Long 型数据精度丢失问题]* Author: [mobaijun]* Date: [2024/8/1 15:58]* IntelliJ IDEA Version: [IntelliJ IDEA 2023.1.4]*/
@Configuration
public class JacksonConfig {// JavaScript 最大安全整数private static final long JS_MAX_SAFE_INTEGER = 9007199254740991L; // 2^53-1private static final long JS_MIN_SAFE_INTEGER = -9007199254740991L;@Beanpublic Jackson2ObjectMapperBuilderCustomizer smartLongSerialization() {return builder -> {builder.serializerByType(Long.class, new SmartLongSerializer());builder.serializerByType(Long.TYPE, new SmartLongSerializer());};}/*** 智能 Long 序列化器:* 1. 当值在JS安全范围内时,保持数字形式* 2. 当值超出安全范围时,转为字符串*/public static class SmartLongSerializer extends JsonSerializer<Long> {@Overridepublic void serialize(Long value, JsonGenerator gen, SerializerProvider provider)throws IOException {if (value != null &&(value > JS_MAX_SAFE_INTEGER || value < JS_MIN_SAFE_INTEGER)) {// 超出安全范围,转为字符串gen.writeString(value.toString());} else {// 在安全范围内,保持数字形式gen.writeNumber(value);}}}
}

修改方式二:【不建议】

对于超过 JavaScript 安全整数范围(2^53-1)的数字:

@JsonSerialize(using = ToStringSerializer.class)
private BigInteger bigNumber; // 对于超大数字使用BigInteger

 方式二是个本版本,只能全部都加。不建议使用

方式一统一处理:推荐使用第一种全局配置方案,这样整个应用中的所有超过进度的 Long 类型都会自动转为字符串

http://www.lryc.cn/news/580077.html

相关文章:

  • Spring Cloud网关与CI文件配置请求安全性对比
  • MySQL/MariaDB数据库主从复制之基于二进制日志的方式
  • 影楼精修-智能修图Agent
  • Python-将多张图片合并成一张图片调整指定区域的颜色选框工具
  • 应急响应靶场——web3 ——知攻善防实验室
  • 【Unity开发】Unity实现glb模型上传到场景中使用功能
  • 秘塔AI搜索的通过Prompt生成互动式网页探索(二)
  • python脚本编程:使用BeautifulSoup爬虫库获取热门单机游戏排行榜
  • Android发展历程
  • 面试版-前端开发核心知识
  • Oracle如何使用序列 Oracle序列使用教程
  • Java 大视界 -- Java 大数据实战:智能安防入侵检测的特征工程与模型融合全解析
  • 硬件嵌入式学习路线大总结(一):C语言与linux。内功心法——从入门到精通,彻底打通你的任督二脉!
  • Java教程——线程池和future
  • Spring Boot 应用启动时,端口 8080 已被其他进程占用,怎么办
  • 批量PDF转换工具,一键转换Word Excel
  • Jenkins 介绍
  • 后端密码加密:守护用户数据的钢铁长城
  • [尚庭公寓]06-Redis快速入门
  • 通过 Ansys Discovery CFD 仿真探索电池冷板概念
  • Excel 如何进行多条件查找或求和?
  • WPF 右键菜单 MenuItem 绑定图片时只显示最后一个 Icon
  • 深度分析:Microsoft .NET Framework System.Random 的 C++ 复刻实现
  • c# 使用GADL: Can‘t load requested DLL错误处理
  • PixiJS教程(004):点击事件交互
  • gic 中断触发类型
  • Python 中线程和进程在实际项目使用中的区别和联系
  • FastAPI 小白教程:从入门级到实战(源码教程)
  • 基于Docker构建OrangePi5 SDK环境
  • 使用mindie:2.0.RC2-800I-A2-py311-openeuler24.03-lts制作一个通用的模型推理性能测试的镜像