基本创建自 Json 方法演练

Basic Create-from-Json Method Walkthrough

我是 scala 和 reactivemongo 的新手,想知道是否有人可以用通俗易懂的语言向我解释以下代码。

def createFromJson = Action.async(parse.json) { request =>
import play.api.libs.json.Reads._

val transformer: Reads[JsObject] =
  Reads.jsPickBranch[JsString](__ \ "name") and
    Reads.jsPickBranch[JsNumber](__ \ "age") and
    Reads.jsPut(__ \ "created", JsNumber(new java.util.Date().getTime())) reduce

request.body.transform(transformer).map { result =>
  collection.insert(result).map { lastError =>
    Logger.debug(s"Successfully inserted with LastError: $lastError")
    Created
  }
}.getOrElse(Future.successful(BadRequest("invalid json")))}

我知道它从具有姓名和年龄属性的 JSON 用户创建了一个用户。我不明白的是在这种方法中读取输入 JSON 的方式。还有 Action.async(par.json)、request => getorElse、Future 等概念

此外,任何 easier/simpler 编写此方法的方式都将不胜感激。

提前致谢!

我相信您是在我根据出色的响应式 mongo 文档制作的模板中找到此代码的。

我觉得有必要解释一下。让我们运行通过代码。

def createFromJson = Action.async(parse.json) { request =>

函数 createFromJson 将 return 一个处理 json 格式主体的异步操作(return 是结果的未来)。为此,它将使用请求。

文档: https://www.playframework.com/documentation/2.5.x/ScalaAsync

A json 可以是遵循 json 格式的任何内容,例如数组、字符串、对象...

我们的转换器将只从 json 中获取我们感兴趣的数据,并将 return 一个干净的 json 对象

val transformer: Reads[JsObject] =
  Reads.jsPickBranch[JsString](__ \ "name") and
    Reads.jsPickBranch[JsNumber](__ \ "age") and
    Reads.jsPut(__ \ "created", JsNumber(new java.util.Date().getTime())) reduce

如您所见,它将选择分支 name 作为字符串,选择分支 age 作为数字。它还会向最终 json 对象添加一个字段 created 以及创建时间。

如您所见,我们没有将它转换为 Person 实例,它只是一个 JsObject 实例,正如它在

中定义的那样
val transformer: Reads[JsObject] ....

Play 为您提供了几种以更简单的方式处理 json 的方法。此示例试图展示直接操作 json 值而不转换为模型的强大功能。 例如,如果您有一个案例 class

case class Person(name: String, age: Int)

您可以从中自动创建读取,

val personReads: Person[Person] = Json.reads[Person]

但只是将其存储在 Mongo DB没有理由构建这个实例然后再次将其转换为json。 当然,如果您需要在插入模型之前对模型进行一些逻辑处理,您可能需要创建模型。

文档:

考虑到这一点,剩下的代码应该就清楚了

request.body.transform(transformer).map { result =>
  collection.insert(result).map { lastError =>
    Logger.debug(s"Successfully inserted with LastError: $lastError")
    Created
  }
}

从请求中,我们获取正文(一个 JsValue),将其转换为 JsObject(结果),然后将其插入集合中。 插入 returns 带有最后一个错误的 Future,当 Person 被存储时,最后一个错误将被记录并且一个 Created(201 代码)将被 returned 到 API 的客户端。

最后一点现在应该也清楚了

}.getOrElse(Future.successful(BadRequest("invalid json")))

如果在解析请求的 json 主体并将其转换为我们的 JsObject 时出现任何问题,一个已经完成的未来结果 BadRequest(400 代码)将被 return 发送给客户端。 这是一个未来,因为 Action.Async 需要结果的未来作为 return 类型。

享受 scala。