19

如何在 Play 中替换 JSON 值中的值?
代码说明:

def newReport() = Action(parse.json) { request =>
    var json = request.body
    if((json \ "customerId").as[Int] == -1){
      // replace customerId after some logic to find the new value
    }
    json.validate[Report](Reports.readsWithoutUser).map {
      case _: Report =>
4

5 回答 5

35

根据Play Documentation,JsObjects 有一个方法++可以合并两个 JsObjects。因此,当您拥有新的整数值时,您只需要:

val updatedJson = json.as[JsObject] ++ Json.obj("customerId" -> newValue)

从 Play 2.4.x 开始,您可以使用+

val updatedJson = json.as[JsObject] + ("customerId" -> newValue)

(注意:该+方法已在 2.1.x 中添加,但向对象添加了重复字段,而不是替换 2.4.x 之前版本中的现有值)

于 2013-08-05T23:36:34.243 回答
4

正如 Marc B 所说,一种方法是将 JSON 转换为类似案例类的东西,对其进行操作,然后创建一个新的 JSON。

但是,您也可以使用 JSON“转换器”。实际上,您所做的是构建一个 Reads[SomeThing] 对象。该对象被传递给您在 JSON 对象上调用的转换方法。它将更改 JSON 对象并返回 Success(result) 或 Failure(error),其中 result 是新修改的 JSON。这是一个(比较)非常简单的例子:

使用 json 格式:{key -> value}

def jsonXForm(value: String) = (__ \ "customerId").json.update(
  (__ \ "customerId").json.put(JsString(value))
)
json.transform(jsonXForm(yourNewValue)) match {...}`

这里有一个不错的指南

于 2016-02-25T22:01:01.740 回答
2

我正在考虑放弃所有那些不可变的“JSON”解决方案。它只是使代码变得一团糟。这就是它在JSON 的 SON 中的样子:

import nl.typeset.sonofjson._

val json = …
if (json.customerId.as[Int] == -1) {
  json.customerId = 987938
}
于 2014-09-21T10:44:58.137 回答
2

类似于以下内容:

val updatedJson = if((request.body \ "customerId").as[Int] == -1){
  val newId = JsObject(Seq(("customerId",JsString("ID12345"))))
  (request.body ++ newId).as[JsValue]
} else request.body

updatedJson.validate[Report](Reports.readsWithoutUser).map {
  case _: Report =>
于 2013-02-08T00:31:04.867 回答
0

使用隐式转换的 Zeimyth 答案的美化版本

implicit class JsObjectEnhancer(jsObject: JsObject) {
  def update(args: (String, Json.JsValueWrapper)*): JsObject = {
    jsObject ++ Json.obj(args: _*)
  }
}

用法(json 必须是 JsObject 类型并且隐式类应该在范围内)

json.update("customerId", 1000)
于 2017-01-03T04:34:25.380 回答