Spring/Mongo-RestController返回ObjectId带时间戳的原因及解决方法
问题原因与解决方案
问题原因
Spring Boot默认用Jackson做JSON序列化工具,而MongoDB的ObjectId类本身包含timestamp、date等内部属性,Jackson序列化时会递归解析这些属性,导致接口返回的JSON里id字段变成包含这些属性的对象。mongosh里显示的是MongoDB自身对ObjectId的字符串化展示,和Jackson的序列化逻辑不一样。
解决方案
有三种常用解决方式,按需选择:
1. 修改实体类id类型为String
直接把实体类的id字段类型从ObjectId改成String,Spring Data MongoDB会自动处理ObjectId和字符串的互转,读写都不受影响:
@Document(collection = "products") data class Product( @Id val id: String = ObjectId.get().toHexString(), val name: String, val identifier: String, val owners: List<String> = listOf() )
这样接口返回的id就会是"6404979bbaa085d5514f0d9d"这类字符串格式。
2. 用@JsonSerialize指定序列化器
在id字段上添加Jackson序列化注解,指定使用Spring Data MongoDB提供的ObjectIdSerializer来序列化:
@Document(collection = "products") data class Product( @Id @JsonSerialize(using = ObjectIdSerializer::class) val id: ObjectId = ObjectId.get(), val name: String, val identifier: String, val owners: List<String> = listOf() )
这种方式可以保留ObjectId类型,同时让序列化结果为字符串。
3. 全局配置Jackson序列化规则
如果项目里有多处用到ObjectId,可以全局配置Jackson,让所有ObjectId都序列化为字符串:
创建配置类:
import com.fasterxml.jackson.databind.module.SimpleModule import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Configuration import org.springframework.data.mongodb.core.serialization.ObjectIdSerializer import org.bson.types.ObjectId @Configuration class JacksonConfig { @Bean fun objectIdModule(): SimpleModule { val module = SimpleModule() module.addSerializer(ObjectId::class.java, ObjectIdSerializer()) return module } }
配置后所有返回的ObjectId都会自动序列化为字符串,无需逐个字段加注解。
内容的提问来源于stack exchange,提问作者Gerrit
相关产品推荐
相关产品推荐

