我有以下案例类:
case class User(name: String)
。
我正在尝试为它实现JSON Reads
转换器,因此我可以执行以下操作:
val user = userJson.validate[User]
...但传入的JSON结构略有不同:
{ "firstName": "Bob", "lastName": "Dylan" }
。
如何实施我的JSON Reads
转换器,将JSON字段firstName
和lastName
合并到我班级的name
媒体资源中?
答案 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
本质上是从JsValue
到JsResult
的函数,意味着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;,这将失败,并显示缺少路径的验证错误。