我想用Play库解析一些“复杂”的JSON。
import play.api.libs.json._
假设我从服务器获得一个包含许多JSON对象的数组,我无法修改。每个条目看起来都与此类似:
{
"id": 1,
"urn": "urn:article:5",
"key": "post",
"foo": "useless"
}
最后,我想将此结构映射到具有以下值的Scala对象:
最有效的方法是什么?将JSON框架内的结构映射到我的需要,或者应该尽快使用中间案例类将它们映射到我的自定义结构中?
我浏览了official documentation,但他们似乎没有讨论这个问题。
目前我将创建一个中间案例类,它只是从JSON中提取相关属性(id,urn,key),并在下一步中将这些对象映射到自定义的所需结构。我不知何故觉得这不是可行的方法。
答案 0 :(得分:2)
您可以在自定义读取/写入序列化程序中添加此类逻辑。请参阅我的答案,了解如何添加自定义JSON Writer for Seq of Tuple。在这种情况下,我执行Writes
,在您的情况下,您将创建一个Reads
,因为您正在阅读JSON并转换为类的实例,很可能是一个案例类。
例如
case class Wombat(id: Int, urn: String, `type`: String)
implicit val myWombatReads = new Reads[Wombat] {
def reads(js: JsValue): JsResult[Wombat] = {
val id = (js \ "id").as[Int]
val urn = (js \ "urn").as[String]
val key = (js \ "key").as[String]
JsSuccess(Wombat(id, urn, urn.split(":")(1) + "_" + key))
}
}
我没有测试你的自定义逻辑,但你得到了图片。您还可以添加验证器等。
答案 1 :(得分:1)
您需要使用Json transformer
"Fatal error: Class 'Expression' not found in
C:\Users\nobis\code\testing2\tests\ExpressionTest.php on line 8"
您的转换结果示例:
import play.api.libs.functional.syntax._
import play.api.libs.json.Reads._
import play.api.libs.json._
val t = (
(__ \ "id").json.copyFrom( (__ \ "id").json.pick) and
(__ \ "urn").json.copyFrom( (__ \ "urn").json.pick) and
( __ \ "type").json.copyFrom(
(__ \ "urn").read[String].flatMap(urn =>
(__ \ "key").read[String].map(key =>
JsString(urn.split(":")(1) + "_" + key)
)
)
)
).reduce
您还可以添加一些验证。 coast-to-coast desig的精彩文章。