奇怪的!春季靴中的长值取整问题 可能的解决方案

问题描述

当我尝试使用杰克逊对象映射器将对象序列化为JSON时,它可以正常工作。

 {"id":1291741231928705024,"uuid":null,"email":"kannanrbk.r@gmail.com"}

当我尝试使用spring rest控制器访问它时。长值数字四舍五入,最后3位数字。

enter image description here

我阅读了stackoverflow中的现有问题,其中大多数建议将数据类型更改为字符串。但是我们在大多数地方使用Long值引用,更改数据类型将需要一些重构。

我做了初步分析:

  1. 我们正在使用杰克逊ObjectMapper
  2. 从Spring开始,它间接调用MappingJackson2HttpMessageConverter
  3. 此问题可能在JSONParser周围的某个地方,它将任何数字都视为双精度数字(15位数字),然后将其四舍五入

有什么办法可以解决此问题?

解决方法

有什么办法可以解决此问题?

Jackson / Java / Spring Boot没问题,但是JavaScript / Browser没问题。

尝试重现该问题,我序列化了同一个对象,并使用curl进行了此操作:

$ curl localhost:8080
{"id":1291741231928705024,"uuid":null,"email":"kannanrbk.r@gmail.com"}

此处数字已正确序列化。

在Firefox中查看的同一json 会被截断

Truncated value in Firefox (JSON tab)

但是,“原始数据”标签会正确显示数字:

Correct value displayed in Firefox ("Raw Data tab")

在JavaScript中,1291741231928705024不是安全的整数(请参见Number.isSafeInteger()):

Number.isSafeInteger(1291741231928705024);
false

该数字大于2^53 - 1,因此会四舍五入。 JavaScript中甚至可能出现更多令人困惑的情况:

> 1291741231928705024 === 1291741231928705022
true

可能的解决方案

首先检查您的客户以防此类问题。如果它可以安全地反序列化此类数字,那么您就安全了。

或者您可以将long序列化为String (如您在问题中提到的那样),这就是Twitter在其Twitter IDs (snowflake)文章中提出的建议:

要允许Javascript和JSON解析器读取ID,在使用JSON响应时,Twitter对象包括任何ID的字符串版本。因此,Twitter API中的状态,用户,直接消息,已保存的搜索以及其他ID在JSON响应中以整数和字符串形式返回。

,

尝试使用bigInt作为主键

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...