scala 如何在 Play 中替换 JSON 值

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14649141/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-22 04:54:55  来源:igfitidea点击:

How to replace a JSON value in Play

jsonscalaplayframework-2.0playframework-2.1

提问by Farmor

How do I replace a value in a JSON value in Play?
Code to illustrate:

如何在 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 =>

回答by Zeimyth

According to the Play Documentation, JsObjects have a method ++that will merge two JsObjects. So, when you have your new integer value, you simply need:

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

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

As of Play 2.4.x you can use +:

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

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

(NOTE: the +method was added already in 2.1.x but adds a duplicate field to the object instead of replacing the existing value in versions prior to 2.4.x)

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

回答by JMess

One approach is, as Marc B says, convert the JSON to something like a case class, manipulate that, and then create a new JSON.

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

However you can also use JSON 'transformers'. Effectively what you do is build a Reads[SomeThing] object. This object is passed to the transform method which you call on your JSON object. It will change the JSON object and return a Success(result) or Failure(error) where result is the new modified JSON. Here's a (comparatively)verysimple example:

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

using json of format: {key -> value}

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

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

There is a decentguide here

有一个体面的指南这里

回答by scalapeno

Something along the lines of:

类似的东西:

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 =>

回答by Wilfred Springer

I'm considering moving away of all of those immutable "JSON" solutions. It's just making the code a horrible mess. This is how it would look in SON of JSON:

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

import nl.typeset.sonofjson._

val json = …
if (json.customerId.as[Int] == -1) {
  json.customerId = 987938
}

回答by rogue-one

a glorified version of Zeimyth's answer that uses implicit conversion

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

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

usage(json must be of type JsObject and the implicit class should be in scope)

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

json.update("customerId", 1000)