简体   繁体   English

播放Scala JSON:合并属性

[英]Play Scala JSON: combine properties

I have the following case class: 我有以下案例类:

case class User(name: String) . case class User(name: String)

I am trying to implement a JSON Reads converter for it, so I can do the following: 我正在尝试为其实现JSON Reads转换器,因此我可以执行以下操作:

val user = userJson.validate[User]

… but the incoming JSON has slightly different structure: …但是传入的JSON的结构略有不同:

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

How can I implement my JSON Reads converter to combine the JSON fields firstName and lastName into a name property on my class? 如何实现JSON Reads转换器以将JSON字段firstNamelastName合并为类的name属性?

This should do the trick: 这应该可以解决问题:

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

EDIT Without using a for comprehension 编辑 而不使用for理解

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

Bringing userReads in scope where you want to use it will let you parse the JSON you provided. userReads放在要使用的范围内,将使您可以解析提供的JSON。

Reads is essentially a function from JsValue to JsResult , meaning userReads represents a function from JsValue -> JsResult . Reads本质上是从JsValueJsResult的函数,这意味着userReads表示从JsValue -> JsResult的函数。 Within the function, it first inspects the provided JSON & tries to read out a property named "firstName" from the current JSON path ( __ is shorthand for this). 在该函数中,它首先检查提供的JSON并尝试从当前JSON路径中读取名为“ firstName”的属性( __是该方法的简写)。 \\ indicates that the field its looking for is one level beneath the root, and read[String] means the value associated with the "firstName" key should be read as a string. \\表示要查找的字段位于根目录下一级,并且read[String]表示与“ firstName”键关联的值应作为字符串读取。 Same follows for "lastName". “ lastName”也一样。

Edit In the version without the for comprehension, it first creates an intermediary object FunctionalBuilder[Reads]#CanBuild[String, String] , which is a complicated way of saying it reads two distinct strings from the Json. 编辑在没有for理解的版本中,它首先创建一个中间对象FunctionalBuilder[Reads]#CanBuild[String, String] ,这是一种复杂的说法,它表示从Json读取两个不同的字符串。 Next it converts that complex object into a Reads[(String, String)] by way of tupled . 接着将其转换该复杂的对象成Reads[(String, String)]通过方式的tupled Finally it maps the pair of strings into a User . 最后,它将字符串对映射到User

Were you to try validating some JSON without "firstName" & "lastName", this will fail with a validation error for a missing path. 如果您尝试验证一些没有“ firstName”和“ lastName”的JSON,这将因缺少路径的验证错误而失败。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM