简而言之,我处理JSON必须看起来像:
{
"data": JSON.stringify(...), // eg. JSON.stringify(null) or JSON.stringify({p: "v"})
...
}
我希望将其解析为类似于以下内容的案例类:
case class Foo(data: JsObject, ...)
我定义的Reads [Food]看起来像这样:
val fooReads: Reads[Foo] = (
(__ \"data").readNullable[String].map(_.filter(s => s != null && !s.isEmpty).map(Json.parse(_).as[JsObject]).getOrElse(JsObject(Seq()))),
...
)
但我一直收到以下错误:
ValidationError(error.expected.jsobject,WrappedArray())
我很确定我的Reads [Foo]现在类似于一个不需要存在的丑陋肿瘤,所以一些帮助会很好。
答案 0 :(得分:0)
此?我确实使用了上面的JSON校正版本。你上面有readNullable但是案例类数据不是一个选项,所以我删除了它。
implicit val reads = (__ \ "data").read[JsObject].map { data => Foo(data)}
更多的FYI但Play JSON组合器不适用于包含一个字段的案例类:How to turn json to case class when case class has only one field
Nullable版本:
case class Foo(data: Option[JsObject])
implicit val reads:Reads[Foo] = (__ \ "data").readNullable[JsObject].map { data => Foo(data)}
更新版本以读取JSON字符串的序列化版本:
implicit val reads:Reads[Foo] = (__ \ "data").readNullable[String].map{
case Some(x) => Foo(data = Json.parse(x).asOpt[JsObject])
case _ => Foo(data=None)
}
我为String读取保留了readNullable,因此库将处理检查String是否为空或null。
答案 1 :(得分:0)
我给出的解决方案,给出以下JSON(具有多个属性):
{
"data": "null", // JSON.stringify({p: "v"}) or JSON.stringify(null)
"fullName": "JohnDoe"
}
Scala代码:
implicit val fooReads: Reads[Foo] = (
(__ \ "data").read[String].map(Json.parse(_).asOpt[JsObject]) and
(__ \ "fullName").read[String]
)
case class Foo(data: Option[JsObject], fullName: String)
仍然没有处理缺少数据属性的情况,而且我不确定使用asOpt[JsObject]
是否有任何缺点,因此可能需要对此进行改进。