• Springboot处理Long类型传给前端导致精度丢失问题


    今天过得不错吧?梦想是不是更远了?

    代码放在https://gitee.com/siumu/blog_code.git

    问题复现

      我们在日常工作中Long类型用的还是很频繁的,但是当我们把Long类型的字段传递给前端的时候,由于长度太长,前端就会产生精度丢失的问题,后面几位数字全部变成了0。
    我们来演示一下,首先我们创建一个User类:

    @Data
    @Accessors(chain = true)
    public class User {
    
        private Long id;
    
        private String username;
    
        private String password;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    然后我们再写一个接口,让它返回一个对象

    @GetMapping("getOneUser")
    public ResultJSON getOneUser(){
        User user = new User().setId(IdWorker.getId())
                .setUsername("朽木")
                .setPassword("123456");
        return ResultJSON.success(user);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    然后我们请求测试一下,它会返回这样的结果

    {
      "code": 200,
      "msg": "success",
      "result": {
        "id": 1543084698014674946,
        "username": "朽木",
        "password": "123456"
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    这个id呢就是一个Long类型,我们在前端试一下看看它会出现什么问题
    请添加图片描述
    如图所示,我们定义一个变量id,把这个Long类型赋值给id,然后再打印出来,我们就发现,后面几位出现了精度丢失的问题。

    如何解决?将Long类型序列化为字符串。

      如果我们把Long序列化为字符串,就能解决前端精度丢失的问题。
    请添加图片描述
    如图所示,当前端接收的是字符串类型的时候,就没有这个问题了。那么如何让后端将Long序列化为字符串类型呢?

    注解的方式,@JsonSerialize(using = ToStringSerializer.class)

    我们在这个Long类型的字段上加上这个注解,就可以将Long序列化为字符串:

    @Data
    @Accessors(chain = true)
    public class User {
    
        @JsonSerialize(using = ToStringSerializer.class)
        private Long id;
    
        private String username;
    
        private String password;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    那么这个接口的返回值就是这样:

    {
      "code": 200,
      "msg": "success",
      "result": {
        "id": "1543097118640582657",
        "username": "朽木",
        "password": "123456"
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    全局处理Long类型

    虽然用注解的方式也可以处理,但是如果说每个类的Long类型都要加上这个注解,感觉还是有点麻烦。我们还有一种全局的方式来处理。

    @Configuration
    public class JacksonConfigurer {
    
        /**
         * Jackson 全局转化 Long 类型为 String,解决 jackson 序列化时 Long 类型缺失精度问题
         * @return Jackson2ObjectMapperBuilderCustomizer 注入的对象
         */
        @Bean
        public Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer() {
            return jacksonObjectMapperBuilder -> {
                jacksonObjectMapperBuilder.serializerByType(Long.TYPE, ToStringSerializer.instance);
                jacksonObjectMapperBuilder.serializerByType(Long.class, ToStringSerializer.instance);
            };
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    写一个这样的配置类,就可以全局处理所有的Long类型,不用额外添加上面那个注解。

    代码放在https://gitee.com/siumu/blog_code.git

  • 相关阅读:
    Git实战技巧-如何查找哪一次提交导致了项目运行错误
    闪存基本原理
    解密Prompt系列13. LLM Agent-指令微调方案: Toolformer & Gorilla
    单元测试Junit使用与详解
    实验5、白盒测试:覆盖测试及测试用例设计
    建立时间和保持时间
    在windows7中运行pycharm报错误“无法定位程序输入点 CreateAppContainerProfile 于动态链接库 USERENV.dll 上
    webpack提升构建速度
    微服务9:服务治理来保证高可用
    js的算法-交换排序(冒泡)
  • 原文地址:https://blog.csdn.net/SiuMu_/article/details/125571491