使用一个值定义JSON属性的读取,该值本身是可能为null值的序列化JSON对象

时间:2014-12-11 20:34:06

标签: scala playframework

简而言之,我处理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]现在类似于一个不需要存在的丑陋肿瘤,所以一些帮助会很好。

2 个答案:

答案 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]是否有任何缺点,因此可能需要对此进行改进。