Java/Spring应用如何从MongoDB读取无包装器的时间戳
解决MongoDB返回时间戳时的包装器问题
嘿,我太懂你这种头疼的感觉了——手动移除$numberLong或者$Date包装器真的挺繁琐,和客户端交互JSON的时候,纯数字时间戳才是最省心的。下面给你几个直接落地的解决方案:
1. 用MongoDB Java驱动的JsonWriterSettings输出纯数字JSON
当你从MongoDB拿到Document对象后,别用默认的toJSON()方法,而是配置JsonWriterSettings为RELAXED模式,它会自动去掉BSON的类型包装,直接输出纯数字:
// 配置JSON输出设置 JsonWriterSettings relaxedSettings = JsonWriterSettings.builder() .outputMode(JsonMode.RELAXED) .build(); // 转换为无包装器的干净JSON字符串 String cleanJson = yourDocument.toJson(relaxedSettings);
这样输出的StartTime就会是"StartTime": 1549640550000,完全符合你要的格式。
2. 用Spring Data MongoDB的实体类映射(长期优雅方案)
如果你是用Spring Data操作MongoDB,直接定义实体类并使用long类型存储时间戳,Spring会自动处理MongoDB的类型映射,返回给客户端时Jackson会直接序列化为纯数字:
import org.springframework.data.mongodb.core.mapping.Document; @Document(collection = "your_collection") public class YourEntity { // 直接用long类型存储毫秒时间戳 private long startTime; // getter和setter public long getStartTime() { return startTime; } public void setStartTime(long startTime) { this.startTime = startTime; } }
当你用MongoTemplate或者MongoRepository查询时,返回的实体类序列化为JSON后,startTime就是纯数字,完全不需要手动处理包装器。
3. 聚合管道强制转换(适合特定查询场景)
如果某些查询需要在MongoDB端直接转换为纯数字,可以用聚合管道的$toLong操作符(不过如果存储的已经是NumberLong类型,其实直接投影就行):
import org.springframework.data.mongodb.core.aggregation.Aggregation; Aggregation aggregation = Aggregation.newAggregation( Aggregation.project() .and("StartTime").as("startTime") ); List<YourEntity> results = mongoTemplate.aggregate(aggregation, "your_collection", YourEntity.class).getMappedResults();
这个方案适合需要在数据库层面做转换的场景,但一般来说前两种方案更高效。
另外提一句,你用到的document.toString()是调试用的输出格式,不适合生产环境生成JSON;而弃用的toJSON()默认用的是STRICT模式,才会输出带类型包装的JSON,切换到RELAXED模式就彻底解决了。
内容的提问来源于stack exchange,提问作者FishingIsLife
相关产品推荐
相关产品推荐

