雪花算法ID之Long类型精度丢失

1、问题概述

项目中使用雪花ID作为主键,雪花ID是19位Long类型数字,数据返回到前端会出现精度丢失问题,数字已经超过了前端浏览器或JS的最大值。

Java后端数据模型

ad0288a7528202e5fe5944a0c5cac992.png

返回到浏览器后的数据模型,前后数据不一致

28f6d8f70016365a78f1cdc00f77f25a.png

2、后端解决方式

序列化时将Long类型转成String类型

2.1、全局设置

  • 在启动类中加 @JsonComponent 注解

  • 在定义如下转换Bean

package com.olive.config;
 
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
 
/**
 * 全局序列化配置类
 */
@Configuration
public class JsonConfig {
 
    /**
     * 创建Jackson对象映射器
     *
     * @param builder Jackson对象映射器构建器
     * @return
     */
    @Bean
    public ObjectMapper getJacksonObjectMapper(Jackson2ObjectMapperBuilder builder) {
        ObjectMapper objectMapper = builder.createXmlMapper(false).build();
        //序列换成json时,将所有的long变成string.因为js中得数字类型不能包含所有的java long值,超过16位后会出现精度丢失
        SimpleModule simpleModule = new SimpleModule();
        simpleModule.addSerializer(Long.class, ToStringSerializer.instance);
        simpleModule.addSerializer(Long.TYPE, ToStringSerializer.instance);
        objectMapper.registerModule(simpleModule);
        return objectMapper;
    }
}

2.2、单个设置

  • 在实体类中,将Long类型的属性添加上注解@ToString.Exclude,表示不需要转换为String类型。

  • 在需要转换的属性上添加注解@JsonSerialize(using = ToStringSerializer.class),表示使用ToStringSerializer类进行转换。

import com.fasterxml.jackson.databind.annotation.JsonSerialize; 
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; 
import lombok.Data; 
import lombok.ToString; 
 
@Data 
@ToString 
public class UserDTO { 

   @JsonSerialize(using = ToStringSerializer.class) 
    private Long id; 
 
    @ToString.Exclude 
    private Long salary; 
 
}

3、前端解决方式

在前端使用JSONbig将大数字做安全处理

在package.json中引入JSONbig, "json-bigint": "^1.0.0" ,执行npm install命令

f8f8b8e0666b377e8f8df9dd14026e8f.png

在requesst.js中创建axios实例时增加代码处理,导入JSONbig和添加transformResponse属性,相当于拦截器,请求相应后处理先处理一下

//导入JSONbig
import JSONbig from 'json-bigint'
// 在创建axios实例中增加transformResponse属性
const service = axios.create({
  // axios中请求配置有baseURL选项,表示请求URL公共部分
  baseURL: process.env.VUE_APP_BASE_API,
  transformResponse: [function(data) {
    try {
      // 作用1:把json字符串转为js对象
      // 作用2:把里面的大数字做安全处理
      return JSONbig.parse(data)
    } catch (e) {
      return data
    }
  }],
  // 超时
  timeout: 10000
})

3e4fff417b34c237776f074ee04fa735.gif

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值