記一次雪花算法 ID 精度丟失的Bug:前端接收到的 Long 被“四舍五入”了?

后端生成的 ID:1961005746230337538
前端收到的 ID:1961005746230337500
—— 少了 38?!這不是 Bug,是 JavaScript 的“安全整數”陷阱!

本文記錄一次真實項目中因 雪花算法 ID 精度丟失 導致的線上問題,并給出徹底、可復用的解決方案。


🐛 問題現象:Long 類型在前后端傳輸中“變短”了

? 看似正常的后端代碼

// 使用雪花算法生成 ID
@TableName("user")
public class User {@TableId(type = IdType.ASSIGN_ID)private Long id; // 1961005746230337538private String name;// getter/setter...
}

接口返回:

{"id": 1961005746230337538,"name": "Chaya"
}

前端接收到的數據

console.log(user.id); // 輸出:1961005746230337500

末尾的 38 沒了!被“四舍五入”了!

根本原因:JavaScript 的 Number 精度限制

  • JavaScript 的?Number?類型是?雙精度浮點數(64-bit)
  • 它能安全表示的整數范圍是:-2^53 + 1?到?2^53 - 1(即?±9,007,199,254,740,991)。
  • 而雪花算法生成的 ID 通常是?19 位 Long,遠超 JS 安全范圍。
  • 瀏覽器在解析 JSON 時,會自動將大整數轉換為?Number,導致精度丟失

📌 舉例:1961005746230337538 超過 2^53,JS 無法精確表示,自動“對齊”到最近的可表示值 → 1961005746230337500

解決方案:后端將 Long 序列化為字符串!

核心思路

在 Spring Boot 返回 JSON 時,將所有 Long 類型字段自動序列化為字符串,避免前端解析時精度丟失。

配置方式

@Configuration
public class WebConfig extends WebMvcConfigurationSupport {@Beanpublic MappingJackson2HttpMessageConverter customJackson2HttpMessageConverter() {MappingJackson2HttpMessageConverter jsonConverter = new MappingJackson2HttpMessageConverter();ObjectMapper objectMapper = new ObjectMapper();SimpleModule simpleModule = new SimpleModule();simpleModule.addSerializer(Long.class, ToStringSerializer.instance);simpleModule.addSerializer(Long.TYPE, ToStringSerializer.instance);objectMapper.registerModule(simpleModule);jsonConverter.setObjectMapper(objectMapper);return jsonConverter;}@Overridepublic void configureMessageConverters(List<HttpMessageConverter<?>> converters) {converters.add(customJackson2HttpMessageConverter());super.addDefaultHttpMessageConverters(converters);}}

🔍 關鍵代碼解析

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

? 作用:注冊一個 Jackson 模塊,告訴 ObjectMapper:

  • 所有?Long?和?long?類型,在序列化成 JSON 時,不要轉成數字,而是轉成字符串!

? 效果對比

類型原始 JSON修復后 JSON
Long ID"id": 1961005746230337538"id": "1961005746230337538"
前端接收? 精度丟失? 完整字符串,無損

其他解決方案對比

方案優點缺點
全局 Long 轉 String(本文方案)一勞永逸,無需改實體類所有 Long 都變字符串
@JsonFormat(shape = JsonFormat.Shape.STRING)精準控制字段每個字段都要加,易遺漏
前端使用?BigInt不改后端兼容性差,JSON 不支持?BigInt
ID 返回為 String 類型類型安全實體類不“純潔”,影響數據庫映射

推薦:全局配置 + 按需排除(如某些計數字段仍保留 Long)

如果某些 Long 字段不需要轉字符串(如 agecount),可以自定義序列化器:

public class CustomLongSerializer extends JsonSerializer<Long> {@Overridepublic void serialize(Long value, JsonGenerator gen, SerializerProvider serializers) throws IOException {// 根據字段名或注解判斷是否轉字符串if (isIdField(gen)) {gen.writeString(value.toString());} else {gen.writeNumber(value);}}
}

但大多數場景下,統一轉字符串更簡單可靠

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/94955.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/94955.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/94955.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

零知開源——基于STM32F407VET6和ADXL345三軸加速度計的精準運動姿態檢測系統

?零知IDE 是一個真正屬于國人自己的開源軟件平臺&#xff0c;在開發效率上超越了Arduino平臺并且更加容易上手&#xff0c;大大降低了開發難度。零知開源在軟件方面提供了完整的學習教程和豐富示例代碼&#xff0c;讓不懂程序的工程師也能非常輕而易舉的搭建電路來創作產品&am…

Android14 init.qcom.usb.rc詳解

本文以高通平臺為例&#xff0c;介紹其USB子系統啟動以及USB各種配置動態切換的邏輯&#xff0c;它是以configfs架構實現動態配置USB。 相關文檔 1. USB子系統的啟動 1.1 on boot階段 1.1.1 重啟恢復用戶選擇的USB配置 當設備重啟時恢復用戶選擇的USB配置&#xff0c;避免每…

Docker的常用命令及簡單使用

1、docker的常用命令 1.1、幫助命令 docker version # 顯示docker的版本信息 docker info # 顯示docker的系統信息&#xff0c;包括鏡像和容器的數量 docker 指令 --help # 查看某個指令的幫助命令可以通過docker --help查看docker常用命…

HGDB全文檢索/中文分詞的使用

文章目錄文檔用途詳細信息文檔用途 本文用于HGDB全文檢索/中文分詞的介紹&#xff0c;其介紹內容在附件&#xff0c;使用案例見正文 詳細信息 一、創建擴展 highgo# create extension zhparser;CREATE EXTENSION highgo# \dFp List of text search parsers Schema…

baijian xiaomaodawang

我將為你創建一個基于Go 1.20.8和Gin框架的博客系統項目。以下是完整的實現方案&#xff1a; 項目創建流程 打開Goland&#xff0c;創建新項目選擇Go項目&#xff0c;設置GOROOT為Go 1.20.8項目名稱&#xff1a;blog-system啟用Go Modules 項目結構 blog-system/ ├── cmd/ │…

Node.js的特性

Node.js的特性 Node.js具有幾個顯著特性&#xff1a; 事件驅動&#xff1a;Node.js采用事件驅動機制來處理請求和響應&#xff0c;這種機制可以幫助開發者處理大量并發請求&#xff0c;提高系統的性能和可靠性。 非阻塞I/O&#xff1a;Node.js使用異步I/O原語來實現非阻塞I/O操…

交叉編譯linux-arm32位程序

目標平臺rv1126 芯片 arm32位架構 在ubuntu22.04上交叉編譯&#xff1a; 編譯器下載地址&#xff1a; Linaro Releases 或者&#xff1a; wget http://releases.linaro.org/components/toolchain/binaries/6.4-2017.11/arm-linux-gnueabihf/gcc-linaro-6.4.1-2017.11-x86_6…

S 3.1深度學習--卷積神經網絡

卷積層 圖像原理 卷積神經網絡&#xff08;Convolutional Neural Network, CNN&#xff09; 圖像在計算機中是一堆按順序排列的數字&#xff0c;數值為 0 到 255。0 表示最暗&#xff0c;255 表示最亮。 圖像識別 上圖是只有黑白顏色的灰度圖&#xff0c;而更普遍的圖片表達…

【7】SQL 語句基礎應用

SQL 語句基礎應用where (篩選)where 子句可使用到運算符查詢表中所有的數據查詢表中的數據&#xff0c;必須滿足 11&#xff08;相當于恒成立&#xff09;查詢表中的 分數(score) 大于 80 分的學生查詢表中 名稱(name) 是 趙六 的數據查詢表中 名稱(name) 不等于 哈哈 的數據.查…

android 嵌套webview 全屏展示 頁面延伸到狀態欄且不被底部導航欄遮擋

我的項目是使用webview嵌套了一個uniapp打包出的h5 本來展示很正常&#xff0c;某天突然發現uniapp的底部導航被手機底部的導航欄擋住了&#xff0c;離奇&#xff0c;某天突然出現的 有些手機會設置展示底部導航按鈕&#xff0c;有些手機會關閉底部導航 以下代碼對這兩種情況通…

【大前端】React Native 調用 Android、iOS 原生能力封裝

&#x1f4d6; React Native 調用 Android、iOS 原生能力封裝 1. 原理 React Native 的 核心思想&#xff1a;JS 層&#xff08;React 代碼&#xff09;不能直接調用 Android/iOS 的 API。RN 提供了 Native Module 機制&#xff1a; Android&#xff1a;Java/Kotlin → 繼承 Re…

HOOK安卓木馬重大升級,勒索功能擴展至107項

勒索覆蓋屏成新特征網絡安全研究人員發現名為HOOK的安卓銀行木馬新變種&#xff0c;該惡意軟件新增勒索軟件式覆蓋屏功能用于顯示勒索信息。Zimperium zLabs研究員Vishnu Pratapagiri表示&#xff1a;"最新變種的顯著特征是能夠部署全屏勒索覆蓋界面&#xff0c;旨在脅迫受…

GeoScene Maps 完整入門指南:從安裝到實戰

什么是GeoScene MapsGeoScene Maps是一套功能強大的Web地圖開發平臺&#xff0c;它基于現代Web技術構建&#xff0c;為開發者提供了豐富的地圖服務和開發工具。與其他地圖API相比&#xff0c;GeoScene Maps具有以下特點&#xff1a;核心優勢全面的地圖服務&#xff1a;支持2D/3…

本地大模型部署:Ollama 部署與 Python 接口調用全攻略

本地大語言模型實踐&#xff1a;Ollama 部署與 Python 接口調用全攻略 一、引言 過去我們使用大語言模型&#xff08;LLM&#xff09;&#xff0c;更多依賴于 OpenAI API、Claude API 等云端服務。它們雖然強大&#xff0c;但存在兩大問題&#xff1a; 隱私與數據安全&#xff…

OpenFeign:讓微服務間調用像本地方法一樣簡單

引言&#xff1a;微服務通信的演進之路什么是OpenFeign&#xff1f;核心特性概覽快速開始&#xff1a;搭建OpenFeign環境環境準備與依賴配置啟用OpenFeign功能基礎用法&#xff1a;從簡單示例開始定義第一個Feign客戶端在服務中調用Feign客戶端進階配置&#xff1a;深度定制Ope…

openharmony之一多開發:產品形態配置講解

OpenHarmony 的“一多開發”指的是 一次開發&#xff0c;多端部署&#xff08;簡稱“一多”&#xff09;&#xff0c;即使用 一套代碼工程&#xff0c;一次開發上架&#xff0c;按需部署到不同終端設備上 &#x1f3af; 核心概念速覽 產品形態定義 寫在前面&#xff1a;1.不同的…

被迫在linux上用R(真的很難用啊)之如何在linux上正常使用R

總有一些情況&#xff0c;讓你不得不在linux上使用R。。。 在我不斷試錯&#xff0c;不斷嘗試過程中&#xff08;恩&#xff0c;新手瘋狂踩坑&#xff09; 發現最簡單的辦法是&#xff1a; 1 mamba創建一個新環境&#xff0c;在新環境中使用R 2 轉變思維&#xff0c;都在linux上…

【STM32】G030單片機的獨立看門狗

目錄 一、簡單介紹 二、特性 三、窗口選項 四、cubeMX配置 不使用窗口功能 使用窗口功能 五、工程鏈接 一、簡單介紹 獨立看門狗&#xff0c;顧名思義&#xff0c;是不依靠系統而獨立存在的看門狗 可以脫離應用運行&#xff0c;但缺陷在于時序精度比窗口看門狗低 主要…

VR黨建工作站-紅色教育基地

近幾年在市場爆火的VR黨建工作站提升了傳統的黨建方式&#xff0c;利用VR/AR技術&#xff0c;為廣大黨員提供沉浸式、多維度的黨建學習。佩京利用VR技術搭建的教育場景&#xff0c;可以更加直觀地了解黨的發展歷程&#xff0c;提高學習效果&#xff0c;激發奮斗精神。VR黨建工作…

配置 Gitlab 和 Elasticsearch/Zoekt 并使用 Docker Metadata 數據庫、Camo 代理服務

配置 Gitlab 和 Elasticsearch/Zoekt 并使用 Docker Metadata 數據庫、Camo 代理服務 本文章首發于&#xff1a;連接 Gitlab 和 Elasticsearch/Zoekt 并使用 Docker Metadata 數據庫、Camo 代理服務 - Ayaka 的小站 為確保更好閱讀格式和閱讀體驗&#xff0c;更建議前往個人博客…