玩Scala JSON:结合属性

时间:2015-08-01 14:48:14

标签: json scala playframework

我有以下案例类:

case class User(name: String)

我正在尝试为它实现JSON Reads转换器,因此我可以执行以下操作:

val user = userJson.validate[User]

...但传入的JSON结构略有不同:

{ "firstName": "Bob", "lastName": "Dylan" }

如何实施我的JSON Reads转换器,将JSON字段firstNamelastName合并到我班级的name媒体资源中?

1 个答案:

答案 0 :(得分:3)

这应该可以解决问题:

  implicit val userReads: Reads[User] = 
      for {
        first <- (__ \ "firstName").read[String]
        last <- (__ \ "lastName").read[String]
      } yield User(s"$first $last")

修改 不使用for comprehension

implicit val userReads = 
  { 
    (__ \ "firstName").read[String] and 
    (__ \ "lastName"
  }.read[String] ).tupled.map(t => User(s"${t._1} ${t._2}"))

在您要使用它的范围内引入userReads将允许您解析您提供的JSON。

Reads本质上是从JsValueJsResult的函数,意味着userReads代表来自JsValue -> JsResult的函数。在该功能中,它首先检查提供的JSON&amp;试图读出一个名为&#34; firstName&#34;从当前的JSON路径(__是此简写)。 \表示其查找的字段位于根目录下方的一个级别,read[String]表示与&#34; firstName&#34;相关联的值。 key应该作为字符串读取。对于&#34; lastName&#34;同样如下。

修改 在没有for comprehension的版本中,它首先创建一个中间对象FunctionalBuilder[Reads]#CanBuild[String, String],这是一种复杂的方式,它说它从Json读取两个不同的字符串。接下来,它通过Reads[(String, String)]将该复杂对象转换为tupled。最后,它将这对字符串映射为User

你是否尝试在没有&#34; firstName&#34;的情况下验证一些JSON。 &安培; &#34; lastName&#34;,这将失败,并显示缺少路径的验证错误。