如果Play / Scala JSON解析中的语句?

杰西姆

有没有一种方法可以在使用Scala / Play解析json时执行条件逻辑?

例如,我想执行以下操作:

implicit val playlistItemInfo: Reads[PlaylistItemInfo] = (
    (if(( (JsPath \ "type1").readNullable[String]) != null){ (JsPath \ "type1" \ "id").read[String]} else {(JsPath \ "type2" \ "id").read[String]}) and
      (JsPath \ "name").readNullable[String]
    )(PlaylistItemInfo.apply _)

在我的假设JSON解析示例中,有两种可能的方式来解析JSON。如果项目为“ type1”,则JSON中将有一个“ type1”的值。如果这在JSON中不存在或它的值为null / empty,那么我想改为读取JSON节点“ type2”。

上面的示例不起作用,但是它使您了解我正在尝试做的事情。

这可能吗?

迈克尔·扎亚克(Michael Zajac)

使用JSON组合器执行此操作的正确方法是使用orElse组合器的每个部分都必须为a Reads[YourType],因此,如果/否则由于您的if子句未返回a而不能正常工作时Boolean,它将返回Reads[PlaylistItemInfo]checked,null后者将始终为trueorElse让我们其中一个Reads用于寻找type1字段,将第二个用于寻找type2字段作为后备。

这可能不符合您的确切结构,但是这里是这样的想法:

import play.api.libs.json._
import play.api.libs.functional.syntax._

case class PlaylistItemInfo(id: Option[String], tpe: String)

object PlaylistItemInfo {
    implicit val reads: Reads[PlaylistItemInfo] = (
        (__ \ "id").readNullable[String] and
        (__ \ "type1").read[String].orElse((__ \ "type2").read[String])
    )(PlaylistItemInfo.apply _)
}

// Read type 1 over type 2
val js = Json.parse("""{"id": "test", "type1": "111", "type2": "2222"}""")

scala> js.validate[PlaylistItemInfo]
res1: play.api.libs.json.JsResult[PlaylistItemInfo] = JsSuccess(PlaylistItemInfo(Some(test),111),)

// Read type 2 when type 1 is unavailable
val js = Json.parse("""{"id": "test", "type2": "22222"}""")

scala> js.validate[PlaylistItemInfo]
res2: play.api.libs.json.JsResult[PlaylistItemInfo] = JsSuccess(PlaylistItemInfo(Some(test),22222),)

// Error from neither
val js = Json.parse("""{"id": "test", "type100": "fake"}""")

scala> js.validate[PlaylistItemInfo]
res3: play.api.libs.json.JsResult[PlaylistItemInfo] = JsError(List((/type2,List(ValidationError(error.path.missing,WrappedArray())))))

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章