前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >雪花算法ID之Long类型精度丢失

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

作者头像
BUG弄潮儿
发布2024-01-09 17:28:31
3960
发布2024-01-09 17:28:31
举报
文章被收录于专栏:JAVA乐园JAVA乐园

1、问题概述

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

Java后端数据模型

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

2、后端解决方式

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

2.1、全局设置

  • 在启动类中加 @JsonComponent 注解
  • 在定义如下转换Bean
代码语言:javascript
复制
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类进行转换。
代码语言:javascript
复制
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命令

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

代码语言:javascript
复制
//导入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
})
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2024-01-05,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 BUG弄潮儿 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1、问题概述
  • 2、后端解决方式
    • 2.1、全局设置
    • 2.2、单个设置
    • 3、前端解决方式
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档