You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Scala Play Framework替换嵌套JSON节点而非追加?

解决Scala Play Framework中JSON字段替换而非追加的问题

我明白你的问题了——你想完全替换counter_holders字段的内容,但当前的update操作却把新的键值对追加到了原有对象里。这是因为Play Framework的JSON Transformer在处理JsObject类型的update时,默认会将新返回的JsObject与原有对象合并(保留原有键,添加新键),而不是直接替换整个字段。

解决方案:使用put直接替换字段值

最直接的方式是放弃update,改用put方法直接替换counter_holders的整个值:

val newJsonString = """{"P123": 25}"""
val jsonStringAsJsValue = Json.parse("""{"counter_holders": {"Peter": 25}}""")

// 直接替换counter_holders字段为新的JsValue
val jsonTransformer = (__ \ "counter_holders").json.put(Json.parse(newJsonString))

val result = jsonStringAsJsValue.transform(jsonTransformer).get
// 输出结果:{"counter_holders":{"P123":25}}

为什么原来的代码会产生追加效果?

你原来的代码中:

val jsonTransformer = (__ \ "counter_holders" ).json.update(__.read[JsValue].map{o => Json.parse(newJsonString)})

这里的update操作针对的是counter_holders内部的结构,Play会把你map返回的新JsObject({"P123":25})和原有的JsObject({"Peter":25})执行合并操作(类似JsObject的++方法),最终得到两个键都存在的对象,也就是你看到的追加效果。

额外说明:如果一定要用update的场景

如果你因为某些原因必须使用update(比如需要先读取原有值做判断再替换),可以明确返回新的JsObject来覆盖原有对象:

val jsonTransformer = (__ \ "counter_holders").json.update(
  __.read[JsObject].map(_ => Json.parse(newJsonString).as[JsObject])
)

不过这种方式和put的效果一致,不如直接用put简洁直观。

内容的提问来源于stack exchange,提问作者trp86

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 13:57:58