spring-boot 雪花ID返回到前端精度丢失
spring-boot snowflow id precision loss
雪花算法产生的是一个 64 位的整数,而 前端的 js 的 number 对象并不能准确展示。
如果使用全局配置将 Long 全部转成 String 似乎不太准确。
了解到 js 的 number 在 10^15 左右还能准确展示,那么编写一个 Json 序列化类,判断当前的数字如果大于 10^15 那么,就序列化为 String,如果小于 10^15 那么还是转成 Long。
jackson
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import java.io.IOException;
public class LongToStringJacksonSerializer extends JsonSerializer<Long> {
public static final long MAX_LONG_TO_STRING = (long) Math.pow(10, 15);
@Override
public void serialize(Long aLong,
JsonGenerator jsonGenerator,
SerializerProvider serializerProvider)
throws IOException {
if (aLong != null) {
if (aLong > MAX_LONG_TO_STRING) {
jsonGenerator.writeString(aLong.toString());
} else {
jsonGenerator.writeNumber(aLong);
}
}
}
}
@Configuration
public class JacksonBeanConfig {
@Bean
public ObjectMapper objectMapper() {
ObjectMapper mapper = new ObjectMapper();
SimpleModule module = new SimpleModule();
module.addSerializer(Long.class, LongToStringJacksonSerializer.instance);
module.addSerializer(Long.TYPE, LongToStringJacksonSerializer.instance);
mapper.registerModule(module);
return mapper;
}
}
fastjson
import com.alibaba.fastjson.serializer.JSONSerializer;
import com.alibaba.fastjson.serializer.ObjectSerializer;
import com.alibaba.fastjson.serializer.SerializeWriter;
import java.io.IOException;
import java.lang.reflect.Type;
public class LongToStringFastJsonSerializer implements ObjectSerializer {
public static final long MAX_LONG_TO_STRING = (long) Math.pow(10, 15);
public static final LongToStringFastJsonSerializer instance = new LongToStringFastJsonSerializer();
@Override
public void write(JSONSerializer serializer,
Object object, Object fieldName, Type fieldType, int features)
throws IOException {
SerializeWriter out = serializer.out;
if (object == null) {
out.writeNull();
return;
}
if (fieldType.getTypeName().equals(Long.class.getTypeName())
|| fieldType.getTypeName().equals(Long.TYPE.getTypeName())) {
long val = (Long) object;
if (val > MAX_LONG_TO_STRING) {
out.writeString(Long.toString(val));
} else {
out.writeLong(val);
}
} else {
out.writeString(object.toString());
}
}
}
@Configuration
public class FastJsonBeanConfig {
@Bean
public FastJsonConfig fastJsonConfig() {
FastJsonConfig fastJsonConfig = new FastJsonConfig();
fastJsonConfig.getSerializerFeatures();
SerializeConfig serializeConfig = SerializeConfig.globalInstance;
serializeConfig.put(Long.class, LongToStringFastJsonSerializer.instance);
serializeConfig.put(Long.TYPE, LongToStringFastJsonSerializer.instance);
fastJsonConfig.setSerializeConfig(serializeConfig);
return fastJsonConfig;
}
}