为什么通过TestRestTemplate获取的响应id会出现自动递增问题?
问题原因
这个问题90%以上是JSON序列化/反序列化过程中的大数精度丢失导致的,具体可以分为以下几种常见场景:
- 你使用的MongoDB ObjectId如果被强制序列化为数字类型(而非默认的24位十六进制字符串),数值会远大于JSON标准支持的精确整数上限(2^53 - 1),序列化时会自动舍入导致数值偏差1
- 测试侧
Patient类的id字段类型和接口返回的类型不匹配:比如接口返回的是字符串格式的ObjectId,但测试类id字段声明为Long类型,反序列化时的强制转换会出现精度错误 - RestTemplate默认的Jackson序列化配置存在问题,没有开启大整数的精确处理配置
排查步骤
- 首先打印接口返回的原始字符串响应,确认问题出在序列化还是反序列化阶段:
// 替换原来的getForEntity调用,先拿原始响应 val rawResponse = restTemplate.getForEntity( getRootUrl() + "/$defaultPatientId", String::class.java ) println(rawResponse.body)
如果打印出的id本身就和预期不符,说明是后端序列化阶段的问题;如果打印的id正确,说明是测试侧反序列化阶段的问题
解决方案
- 优先使用字符串类型传输ObjectId:给后端
Patient实体的id字段加上@JsonSerialize(using = ToStringSerializer::class)注解,强制序列化为字符串,同时保证测试侧的Patient类id字段类型为ObjectId或者String,避免强制转换 - 如果必须使用数字类型传输id,调整Jackson全局配置,开启大整数精确处理:
@Bean fun customObjectMapper(): ObjectMapper { return ObjectMapper() .configure(DeserializationFeature.USE_LONG_FOR_INTS, true) .configure(SerializationFeature.WRITE_BIGDECIMAL_AS_PLAIN, true) }
- 检查测试代码中的
Patient类和业务代码中的Patient类定义是否完全一致,避免字段类型、注解配置不同导致的反序列化异常
内容的提问来源于stack exchange,提问作者Leandro Lima
相关产品推荐
相关产品推荐

