Springboot Long类型数据太长返回给前端,精度丢失问题 复现解决

Posted 小目标青年

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Springboot Long类型数据太长返回给前端,精度丢失问题 复现解决相关的知识,希望对你有一定的参考价值。

前言

惯例,收到兄弟求救,关于long类型丢失精度的问题:

存在一个初学者不会,就会有第二个初学者不会,所以我出手。

正文

不多说,开搞。



如题, 后端返回的数据 给到 前端, Long类型数据太长导致精度丢失。

复现示例



比如我们写个接口:

我们特意去把 Long类型 14位 到 20位的数据都 塞到返回值里面
 

    @RequestMapping("/test")
    @ResponseBody
    public TestDTO test()
        TestDTO testDTO=new TestDTO();
        testDTO.setNumStr("12345678901234568901234567890123456890");
        testDTO.setNum14(12345678901234L);
        testDTO.setNum15(123456789012345L);
        testDTO.setNum16(1234567890123456L);
        testDTO.setNum17(12345678901234567L);
        testDTO.setNum18(123456789012345678L);
        testDTO.setNum19(123456789012345689L);
        testDTO.setNum20(1234567890123456890L);
        return testDTO;
    

TestDTO.java:
 

public class TestDTO 

    private String numStr;

    private Long num14;
    private Long num15;
    private Long num16;
    private Long num17;
    private Long num18;
    private Long num19;
    private Long num20;
  
    //省略set、get

这时候前端调用看看效果,可以看到出现了精度丢失的场景:

原因

 js数字的精度是有限的,Java的Long类型的数字超出了javascript的处理范围。
 内部只有一种数字类型Number,双精度64位格式存储,即使整数也是如此。
 最大的数值应该是2的53次方-1,十进制是【9007199254740991】,16位。
 所以说超过16位,那么如果属于Number类型去解析的,就会丢失精度。

解决方案:

@JsonSerialize(using=ToStringSerializer.class)



 看看效果:

 好了,该篇就到这。

浏览器响应数据long型超长自动转换精度丢失-JavaScript 整数精度丢失问题-springboot解决Long类型数据传入前端损失精度

最近在洗敏感数据id,用类似snowflake算法加入分表基因生成新的ID,返回给前端,前端整数显示不正常。

java中long的最大值:9223372036854775807

看看在浏览器中的显示:

Google Chrome

版本 79.0.3945.117(正式版本) (64 位)

 

后面好几位不一样了,看看JavaScript中整数的最大值:

看来JavaScript的整数要比java的小。

 

如何解决:

前端可以做,后端序列化生字符串就行;

 

比如spring boot应用统一解决:

 

/**
 * @author sdcuike
 * @DATE 2020/1/17
 */
@Configuration
public class Jackson2Customizer 

    public static final String DATE_FORMAT = "yyyy-MM-dd";
    public static final String DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";

    @Bean
    public Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer() 
        return jacksonObjectMapperBuilder -> 
            //修复:前端js 精度问题
            jacksonObjectMapperBuilder.serializerByType(Long.class, ToStringSerializer.instance);
            jacksonObjectMapperBuilder.serializerByType(Long.TYPE, ToStringSerializer.instance);
            jacksonObjectMapperBuilder.simpleDateFormat(DATE_TIME_FORMAT);
        ;
    

或者使用注解在属性上加:

@JsonSerialize(using = ToStringSerializer.class)

 

 

以上是关于Springboot Long类型数据太长返回给前端,精度丢失问题 复现解决的主要内容,如果未能解决你的问题,请参考以下文章

插入oracle的long类型,报字符串过长怎么解决

springboot+mybatisplus+lombook项目中数据问题。

java 方法返回值类型 Long与long

接口数据返回---标准格式

返回long类型精度丢失

web api c#为带有角度的long数据类型返回另一个值