前端接收Long类型数据精度丢失问题

项目场景:

后端数据库中主键使用Bigint类型,新增时通过MyBatis-Plus设置ID策略为雪花ID,后端接口返回主键为Long类型。


问题描述

后端接口编写完成后,在postman中测试新增、修改、删除和详情接口都正常。在同前端调试过程中发现无法通过主键对后端数据进行操作。


原因分析:

首先听到前端反馈这个问题时,内心深处在想这个前端怎么回事,怎么接口都不会调用(PS:我写的接口怎么可能有BUG),保险起见还是暗戳戳的通过postman测试了一遍接口发现一切正常,又打开测试环境通过浏览器检查查看接口调用情况,发现前端传递到后端的主键同后端返回的主键不相同。(PS:看果然是你前端的问题吧)


解决方案:

查询资料后发现前端的数据格式没有Long类型只有Number 和 BigInt,在接收后端数据时默认为Number 类型,当超出其安全范围(即大于 2^53 - 1)的整数,会丢失精度。
解决方案一:后端通过拦截器的方式在接口返回时将全部的Long类型转换为String类型返回到前端
解决方案二:前端在接收时强制转换为BigInt
解决方案三:前端使用支持大整数的库
本人更加倾向于采用第一种解决方案来解决这个问题,毕竟这个处理更加简单方便,代码如下:

/**
 * 序列化为json时,将所有的long变成string,js中数字类型长度小于java中long值长度
 * EnableWebMvc 开启springmvc的一个注解
 */
@EnableWebMvc
@Configuration
public class JacksonConfig implements WebMvcConfigurer {

    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        MappingJackson2HttpMessageConverter jackson2HttpMessageConverter = new MappingJackson2HttpMessageConverter();
        ObjectMapper objectMapper = new ObjectMapper();
        SimpleModule simpleModule = new SimpleModule();
        simpleModule.addSerializer(Long.class, ToStringSerializer.instance);
        simpleModule.addSerializer(Long.TYPE, ToStringSerializer.instance);
        simpleModule.addSerializer(BigInteger.class, ToStringSerializer.instance);
        // 反序列化时忽略多余字段
        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        // 注册
        objectMapper.registerModule(simpleModule);
        jackson2HttpMessageConverter.setObjectMapper(objectMapper);
        converters.add(jackson2HttpMessageConverter);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值