一、问题根源
JavaScript的 Number
类型安全精度最大为16位(IEEE 754标准),而雪花算法生成的ID通常为18-19位(如1896876827460800512
),超出安全范围导致末2-3位精度丢失,前端则显示为( 1896876827460800500)。
二、解决方案
1. 全局配置Jackson序列化规则
通过ObjectMapper将Long类型序列化为String,确保前端接收为字符串类型:
@Bean
public ObjectMapper objectMapper() {
ObjectMapper objectMapper = new ObjectMapper();
SimpleModule module = new SimpleModule();
module.addSerializer(Long.class, ToStringSerializer.instance);
objectMapper.registerModule(module);
return objectMapper;
}
●效果:id字段从数字(如1896876827460800512)转为字符串,如"1896876827460800512"),避免精度丢失 。
2. 实体类必须使用Long封装类
若实体类字段声明为基本类型long,Jackson不会触发序列化规则,因为:
●ToStringSerializer仅对Long封装类生效(long是基本类型,不在处理范围内)。
●正确声明方式:private Long id;
3. 检查其他可能覆盖配置的因素
●局部注解覆盖:若某些字段使用了@JsonFormat或@JsonSerialize,需移除或统一配置。
●全局与局部优先级:确保自定义ObjectMapper未被其他配置覆盖(如application.yml中的Jackson配置)。
4. 数据库与接口文档调整
●数据库字段类型:保持BIGINT(雪花ID兼容)。
●接口文档标注:明确说明id为字符串类型(如Swagger添加@Schema注解),避免前端误解析为数字。
5. 测试验证
通过Postman或浏览器检查响应,确认id字段类型已转为字符串:
{
"id": "1896876827460800512",
"taskId": "1896866728268828672"
}
三、扩展建议
-
前端兼容性:提醒前端避免对
id
进行数值运算(如加减),始终以字符串处理。 -
分布式系统一致性:确保所有服务使用相同的序列化配置,避免部分接口返回数字、部分返回字符串。
-
性能优化:若接口性能敏感,可针对特定字段(而非全局)使用
@JsonSerialize(using = ToStringSerializer.class)。
四、总结
通过全局序列化配置 + 实体类使用Long
封装类的组合方案,可彻底解决雪花ID精度丢失问题。