一次由「雪花 ID」引发的前后端联调踩坑记录

来公司实习半个多月,前几天终于在测试环境部署了我负责的第一个功能模块
当服务跑起来、接口自测全部通过的时候,心里还是挺有成就感的。

但没高兴多久,前端同学就在钉钉上找我了:

“xxx 接口好像不好使,返回的数据有问题。”

1. 问题出现:Postman 没问题,前端却报错?

我第一反应是:
“不可能啊,我刚在 Postman 里测过,完全没问题。”

于是我又打开 Postman,把接口重新跑了一遍:

  • 参数正常
  • 返回正常
  • 根据返回的 ID 再查详情,也完全 OK

但前端那边:

  • 列表接口能返回
  • 点进详情页就 404 / 查不到数据

一时间我有点懵:
“同一个接口,为什么在我这没问题,在前端就不行?”


2. 转机:一句「主键 ID 要用字符串」

在来回确认参数后,前端同学提到了一句关键的话:

“我们问了下组里的前辈,说这种主键 ID 要当字符串传。”

我当时的第一反应其实是抗拒的

  • 主键不是 Long 吗?
  • 自增 ID / 雪花 ID 怎么可能用 String
  • 用字符串做主键不会影响查询性能吗?

这和我之前学习中的认知是冲突的。

但也正是这个冲突,逼着我去认真查了一下资料。


3. 真正的原因:不是数据库的问题,是 JavaScript 的精度问题

查资料之后,问题一下子就清楚了。

3.1 后端:雪花 ID 是 Long(64 bit)

后端使用的是 雪花 ID

  • Java 中的 Long 类型
  • 64 位有符号整数
  • 最大可到 9.22e18

完全没问题。

3.2 前端:JavaScript 的 Number 只有 53 bit 精度

但前端是 JavaScript

Java Long   → 64 bit
JS Number  → 53 bit 有效精度

当雪花 ID 大于 2^53 - 1 时,例如:

2001571558761857024

在前端被当成 Number 解析后,会变成一个不精确的值

结果就是:

  • 后端返回的 ID 是对的
  • 前端“看到”的 ID 已经变了
  • 前端再拿这个 ID 调详情接口
  • 后端自然查不到这条数据

👉 问题的根源不在数据库,也不在雪花算法,而在 JS 的数值精度限制。


4. 正确认知:前端说的“字符串”,并不是“字符串主键”

这里是我一开始理解错的地方。

前端说的“ID 用字符串”,
并不是数据库用字符串当主键

而是:

  • 数据库BIGINT / Long
  • 后端实体Long
  • 接口 JSON 返回String
  • 前端使用String

也就是说:

字符串只存在于「接口传输层」,并不影响数据库查询性能。


5. 解决方案:后端统一把 Long 序列化成 String

解决方式其实很成熟,也很简单。

5.1 后端配置全局序列化策略

在 Spring Boot 中,通过 Jackson 全局配置:

@Configuration
public class JacksonConfig {

    @Bean
    @Primary
    public ObjectMapper objectMapper() {
        ObjectMapper mapper = new ObjectMapper();
        SimpleModule module = new SimpleModule();
        module.addSerializer(Long.class, ToStringSerializer.instance);
        module.addSerializer(Long.TYPE, ToStringSerializer.instance);
        mapper.registerModule(module);
        return mapper;
    }
}

这样做之后:

  • 所有 Long 类型字段
  • 在返回给前端时
  • 统一序列化成字符串

前端接收就不会再发生精度丢失。


6. 那前端传回来的 String,后端怎么办?

这一点也是我后来才意识到的:

Spring MVC 已经帮我们做好了。

当前端传:

GET /order/detail?id=2001571558761857024

而 Controller 是:

@GetMapping("/order/detail")
public OrderVO detail(@RequestParam Long id) {
    ...
}

Spring MVC 会在参数绑定阶段

  • 自动把字符串
  • 转换为 Long
  • 不需要我们写任何额外代码

👉 这是框架层已经处理好的事情。


7. 这次踩坑给我的几个反思

  1. 接口“在 Postman 没问题”,不代表前后端联调没问题

  2. 技术问题往往出现在“边界”上(这里是 Java ↔ JavaScript)

  3. 不要先否定同事的结论,很多“看起来不合理”的建议,背后都有原因

  4. 真正成熟的系统,会明确区分:

    • 存储层
    • 业务层
    • 接口传输层

8. 一句话总结

雪花 ID + 前端报错,不是雪花的问题,也不是数据库的问题,
而是 JavaScript Number 精度限制导致的经典坑。

而这个坑,
如果你第一次做前后端联调,大概率也会踩到。

posted @ 2025-12-18 16:54  jiangyang1556  阅读(1)  评论(0)    收藏  举报