栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

【排错日记】前端js接收Long丢失精度

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

【排错日记】前端js接收Long丢失精度

一. 问题引出
前段时间上线遇到一个问题,TiDB表的主键使用的是bigint + auto_random,值类似于【2017612633061982209】,查询接口正常返回后,前端读取到的却是【2017612633061982000】,精度丢失了?  
二. 本质原因
 1. js数字的精度是有限的,Java的Long类型的数字超出了JavaScript的处理范围。
 2. 内部只有一种数字类型Number,双精度64位格式存储,即使整数也是如此。
 3. 最大的数值应该是2的53次方-1,十进制是【9007199254740991】,16位。
三. 怎么解决? 前端解决
在浏览器环境中,使用json-bigint库替换默认的JSON库,保证精度不丢失。详细细节留给前端解决了,这里不赘述。
后端解决
  • 方案1. 后端的ID(Long)转成(String), 前端使用String类型的ID。
@Configuration
@Slf4j
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {
 
    
    @Override
    public void configureMessageConverters(List> list) {
        MappingJackson2HttpMessageConverter jsonConverter = new MappingJackson2HttpMessageConverter();
        ObjectMapper objectMapper = jsonConverter.getObjectMapper();
        //序列换成json时,将所有的long变成string
        SimpleModule simpleModule = new SimpleModule();
        simpleModule.addSerializer(Long.class, ToStringSerializer.instance);
        simpleModule.addSerializer(Long.TYPE, ToStringSerializer.instance);
        objectMapper.registerModule(simpleModule);
        list.add(jsonConverter);
    }
}
  • 方案2. 增加配置(全局的)
spring:
  jackson:
    generator:
      write_numbers_as_strings: true

优点:方便。
缺点:所有的数字都被转成字符串输出了,包括按照timestamp格式输出的时间,影响范围大。

  • 方案3. 使用注解(字段级别)
@JsonSerialize(using=ToStringSerializer.class)
private Long bankcardHash;

优点:可在字段级别调整。

缺点:涉及字段多的话,就特别繁琐,改动比较多。

  • 方案4:覆写类方法
@Bean("jackson2ObjectMapperBuilderCustomizer")
public Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer() {
    Jackson2ObjectMapperBuilderCustomizer customizer = new Jackson2ObjectMapperBuilderCustomizer() {
        @Override
        public void customize(Jackson2ObjectMapperBuilder jacksonObjectMapperBuilder) {
            jacksonObjectMapperBuilder.serializerByType(Long.class, ToStringSerializer.instance)
                    .serializerByType(Long.TYPE, ToStringSerializer.instance);
        }
    };
    return customizer;
}
哪个解决方案好点?

抛出问题:总而言之,上面后端的方案可以全局解决Long转string的问题,但有些时候,前端是需要number类型的数据的,这个时候就只能单独再处理了。

????哪个方案?

四.结论
建议前端引入插件【json-bigint】解决Long精度损失的问题,永久解决问题。
五.参考

https://blog.csdn.net/xhdxhdxhd/article/details/109164469

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1031106.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号