雪花算法踩坑 - Long 类型 id 返回前端精度丢失 (通过序列化解决)

Posted Hepburn Yang

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了雪花算法踩坑 - Long 类型 id 返回前端精度丢失 (通过序列化解决)相关的知识,希望对你有一定的参考价值。

能看到这里大概率说明你已经踩到这个坑了。

原因:

js 的 number 类型支持的最大值是9007199254740992 (2 的 53次方 -1),溢出之后的精度会丢失,导致前后端的值不一致。
java 的 long 类型最大值为 9223372036854775807,远高于 js number类型的最大值,所以这个坑就出现了。

解决方案:

方案一

  1. id-type: ID_WORKER_STR
    简单来说就是 id 转 为string类型,db和生成的id数据类型都改为 string 类型
    缺点:牺牲了 long 类型的性能优势

方案二

  1. 可以在每个实体类的id字段上加注解
	@JsonFormat(shape = JsonFormat.Shape.STRING)
	private Long id;

方案三

  1. 通过 json 序列化做全局处理,传给前端的是字符串,到后台依然是 long 类型

import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.serializer.ValueFilter;
import com.alibaba.fastjson.support.config.FastJsonConfig;
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
import org.apache.commons.lang3.StringUtils;
import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.HttpMessageConverter;

import java.util.ArrayList;
import java.util.List;

/**
 * @author :XiaoHui Yang
 * @version : 1.0.0
 * @description: 自定义JsonHttpMessageConverter解决long类型id丢精度问题
 * @date :Created in 2020/6/28 14:41
 * @modified By:
 */
@Configuration
public class CustomFastJsonHttpMessageConverter 

    @Bean
    public HttpMessageConverters fastJsonHttpMessageConverters() 
        FastJsonHttpMessageConverter fastConverter = new FastJsonHttpMessageConverter();
        FastJsonConfig fastJsonConfig = new FastJsonConfig();

        List<SerializerFeature> list = new ArrayList<>();
        list.add(SerializerFeature.PrettyFormat);
        list.add(SerializerFeature.WriteMapNullValue);
        list.add(SerializerFeature.WriteNullStringAsEmpty);
        list.add(SerializerFeature.WriteNullListAsEmpty);
        list.add(SerializerFeature.QuoteFieldNames);
        list.add(SerializerFeature.WriteDateUseDateFormat);
        list.add(SerializerFeature.DisableCircularReferenceDetect);
        list.add(SerializerFeature.WriteBigDecimalAsPlain);

        fastJsonConfig.setSerializerFeatures(list.toArray(new SerializerFeature[list.size()]));

        fastConverter.setFastJsonConfig(fastJsonConfig);
        HttpMessageConverter<?> converter = fastConverter;
        fastJsonConfig.setSerializeFilters(new ValueFilter() 
            @Override
            public Object process(Object object, String name, Object value) 
                if ((StringUtils.endsWith(name, "Id") || StringUtils.equals(name,"id")) && value != null
                        && value.getClass() == Long.class) 
                    return String.valueOf(value);
                
                return value;
            
        );
        return new HttpMessageConverters(converter);
    


感谢阅读,希望对你有帮助~

以上是关于雪花算法踩坑 - Long 类型 id 返回前端精度丢失 (通过序列化解决)的主要内容,如果未能解决你的问题,请参考以下文章

雪花算法踩坑 - Long 类型 id 返回前端精度丢失 (通过序列化解决)

雪花算法生成唯一ID,前后端不一致

Springboot解决雪花算法ID到前端精度丢失

雪花算法生成的ID在返回给前端之后和生成的不一样,到底是什么原因?

雪花算法生成的ID在返回给前端之后和生成的不一样,到底是什么原因?

前端解析17位Long类型数据,精度丢失导致id不同