long类型怎么转换成string_前后端超大整数传输会有精度损失?看看阿里怎么做

在阅读《阿里巴巴Java开发手册》时,发现有一条关于前后端超大整数返回的规约,这是JavaScript 的一个坑:

89dc079364dae2279afdb9fc0383174c.png

首先我们创建一个Spring Boot项目,然后再新建接口用来返回DbScript对象,其中的id是由mybatis-plus的IdWorker.getld生成的19位long类型的数值。

@RestController @RequestMapping("/dbScrip") public class DbScriptController {     Logger logger = LoggerFactory.getLogger(DbScriptController.class);      @RequestMapping("/info")     public DbScript getDbScript() {         DbScript dbScript = new DbScript();         // id         long id = IdWorker.getId();         dbScript.setId(id);         logger.info("id:{}", id);         return dbScript;     } } 

然后将服务启动,通过浏览器对接口进行访问我们可以发现,通过日志可以看到后端传给前端的id是不同的,在这个传递的过程中产生了损失,后端传的是1304270071757017088但是前端接收的却是1304270071757017000。

我们通过开发手册来查询原因就会了解到,如果返回的数值大于2的53次方,那么就会转换成JS的Number,这些数值就可能在传输的过程中发生精度的损失。

解决方法

针对这项问题,可以采取如下的几种方法

如果这个对象只在这个方法中用到了,可以将该属性直接从Long变为String型。如果这个对象在很多地方都使用了,那么在序列化的过程中,将Long类型转换成String类型。我们也可以通过添加一个新的String属性来处理前后端对于大整数的传输。

方法一:

直接将Long id改成String id;这种方法相对来说比较局限,仅适用于对象只在这个方法中使用。

方法二:

还可以在属性上增加注解。这种方法也是有弊端存在的,如果需要修改的部分比较多,那么逐个添加的工作量还是比较大的,假设使用的是Jackson,那么可以通过WRITE_NUMBERS_AS_STRINGS这个配置参数将所有数字全部转换成字符串强制输出,方法使用也比较简单,优点在于使用方便,几乎不需要调整代码。但是这样做的问题在于颗粒度较大, 将所有的数字都转换成字符串输出后,按照 timestamp 格式输出的时间也会是这样。

方法三:

可以用一个多的属性,例如使用String dbScripId来代替之前的id。

总结

本文针对《阿里巴巴Java开发手册》中的对于需要使用超大整数的场景,服务端一律使用 String 字符串类型返回,禁止使用Long 类型出发,提出了几种解决方法,大家可以根据自己的需求去选择方法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值