如何在Scala Play 2.6.10中处理JSON:将_id字段的嵌套$oid结构转换为直接字符串值
我懂你这种感觉——Play JSON的transformer API刚接触的时候确实有点晦涩,尤其是要把嵌套的对象拆成平级字段的时候。针对你在Play 2.6.10里的需求,我给你两种实用方案,一种是用官方的transformer组合(理解后会很灵活),另一种是更直观的手动处理方式,你可以根据场景选择:
方案一:用Play JSON Transformer API实现
虽然官方文档看起来复杂,但针对这个需求,我们只需要组合提取值和更新字段两个操作就可以完成:
首先导入必要的包:
import play.api.libs.json._
然后定义转换器并使用:
// 定义转换器:提取_id.$oid的值,替换原_id字段 val oidTransformer = (__ \ '_id).json.update( (__ \ '$oid).json.pick // 提取嵌套在_id下的$oid对应的值(JsString类型) ) // 原JSON数据 val originalJson = Json.parse("""{"_id": {"$oid": "VALUE"}, "anotherField": "anotherValue"}""") // 执行转换 val transformedResult = originalJson.transform(oidTransformer) // 处理转换结果 transformedResult match { case JsSuccess(transformedJson, _) => println(transformedJson) // 输出:{"_id":"VALUE","anotherField":"anotherValue"} case JsError(errors) => println(s"转换失败:$errors") }
代码解释:
(__ \ '_id).json.update(...):定位到_id字段,执行更新操作(__ \ '$oid).json.pick:从_id的嵌套对象中提取$oid对应的值(而不是分支结构),用这个值直接替换原来的_id字段- 整个转换完成后,原有的
{"$oid": "VALUE"}嵌套结构会被完全替换成字符串"VALUE",不需要额外的prune操作
方案二:更直观的手动重组JSON
如果觉得transformer API太绕,直接手动提取字段并重组JSON会更简单,尤其适合字段不多的场景:
import play.api.libs.json._ val originalJson = Json.parse("""{"_id": {"$oid": "VALUE"}, "anotherField": "anotherValue"}""") // 方式1:用for推导式安全提取字段并重组 val transformedJson = for { oid <- (originalJson \ "_id" \ "$oid").validate[String] anotherField <- (originalJson \ "anotherField").validate[String] } yield Json.obj( "_id" -> oid, "anotherField" -> anotherField ) // 方式2:直接操作JsObject(适合确定字段存在的场景) val originalObj = originalJson.as[JsObject] val oid = (originalObj \ "_id" \ "$oid").as[String] val transformedObj = originalObj - "_id" + ("_id" -> JsString(oid))
两种方式最终都会得到你想要的结果,方式2更简洁,但前提是你能确保_id和$oid字段一定存在;方式1用validate做了安全校验,避免字段缺失时抛出异常。
额外建议
如果你的项目经常需要处理MongoDB的BSON格式JSON(比如这种$oid嵌套),可以考虑使用Play官方的MongoDB集成库,里面有现成的序列化/反序列化工具,能自动将MongoDB的ObjectId转换成直接的字符串_id,不用自己手动写转换逻辑。
内容的提问来源于stack exchange,提问作者Capacytron
相关产品推荐
相关产品推荐

