如何使用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
相关产品推荐
相关产品推荐

