0

我是新手,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 等的概念。

也将不胜感激任何更简单/更简单的编写此方法的方法。

提前致谢!

4

1 回答 1

2

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

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

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

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

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

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

我们的转换器将只从 json 中获取我们感兴趣的数据,并返回一个干净的 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

如您所见,它将选择分支名称作为字符串,选择分支年龄作为数字。它还将向最终的 json 对象添加一个在创建时创建的字段。

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

val transformer: Reads[JsObject] ....

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

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(结果)并将其插入到集合中。插入返回带有最后一个错误的 Future,当存储 Person 时,将记录最后一个错误,并将 Created(201 代码)返回给 API 的客户端。

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

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

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

享受斯卡拉。

于 2016-03-15T09:46:27.527 回答