将键/值添加到Scala中的现有JsValue

时间:2016-08-31 05:56:46

标签: json scala playframework

我是Scala的新手,我正在试图弄清楚如何为JsValue添加键/值。在JavaScript中,您可能会执行SomeObject.newKey = newValue之类的操作。这是我的真实用例:

  def doAccountUpdate(account: db.models.Account, config: JsObject, job: JsValue) : JsValue = {
    val passwordParam = (job \ "params" \ "password")
    if (passwordParam.toOption.isDefined) {
      val password = (job \ "params" \ "password").get.as[String]
      val encrypted_password = Auth.passwordEncrypt(password)
      // ADD `encrypted_password`'s value TO `job \ params` so its `job \ params \ encryptedPassword`
    }

    Account.update(account, config, job)
  }

Account.update实际上更新了数据库,因此在doAccountUpdate我正在准备数据。我需要准备的其中一项是密码,方法是在将密码传递给Account.update之前对其进行加密。我该怎么做?

修改

为了解释为什么这个被标记为重复的问题对我来说不起作用,这就是他们的例子:

jsonObject.as[JsObject] + ("c" -> Json.toJson(3))

如果我在我的代码中复制它,它将如下所示:

updateJob = job.as[JsObject] + ("encryptedPassword" -> Json.toJson(encrypted_password))

但是输出:

{
    "id":"...",
    "params": {
        "password":"Programmer2!"
    },
    "encryptedPassword":"$2a$10$EHnJHXh1sTORxliPocWfDuHnlRzu1YwG.kyBee.u85apCXTuLij.y"
}

请注意encryptedPassword

中的params不是多少

1 个答案:

答案 0 :(得分:1)

正如@danielnixon建议的那样,你可以使用JSON变换器。这是一个例子:

val encryptPassword: Reads[JsObject] = (__ \ "params").json.update(
  (__ \ "password").read[String].flatMap(pw =>
    (__ \ "encryptedPassword").json.put(JsString(Auth.passwordEncrypt(pw)))
  )
)

这说我们会:

  1. 更新params对象
  2. 阅读现有密码
  3. encryptedPassword对象
  4. 中添加了一个新的params分支

    当您将job.transform(encryptPassword)应用于JsResult时,您将获得password,如果params对象存在并且JsSuccess字段带有字符串值,则为{{} 1}} - 否则你将获得JsError。您可以使用以下内容处理:

    def doAccountUpdate(account: db.models.Account, config: JsObject, job: JsValue) : JsValue = {
      job.transform(encryptPassword) match {
        case JsSuccess(newJob, _) => Account.update(account, config, newJob)
        case JsError(errors) => sys.error("No password supplied!")
      }
    }