一、问题根源

      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精度丢失问题。

三、补充时间格式

    如果遇到了时间被转换为时间戳(数字)的情况,通常是因为 ObjectMapper 默认将 java.util.Date 或 java.time 系列对象序列化为时间戳。要解决时间格式变成数字的问题,需要配置 ObjectMapper 禁用时间戳输出,并指定日期格式。

@Bean
public ObjectMapper objectMapper() {
    ObjectMapper objectMapper = new ObjectMapper();
    
    // 1. 保持原有的 Long 转 String 配置 (防止前端精度丢失)
    SimpleModule module = new SimpleModule();
    module.addSerializer(Long.class, ToStringSerializer.instance);
    objectMapper.registerModule(module);

    // 2. 【关键】禁用将日期序列化为时间戳 (默认是 true,即输出为数字)
    objectMapper.disable(com.fasterxml.jackson.databind.SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);

    // 3. 【可选】设置具体的日期格式化模式,例如 "yyyy-MM-dd HH:mm:ss"
    objectMapper.setDateFormat(new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));

    return objectMapper;
}

更多推荐