如何在scala中使用空值解析json列表?

时间:2018-09-27 16:59:40

标签: json scala playframework scalatest

我正在尝试用一个内部列表解析json对象

{
   "foo": 12,
   "bar": [ 12, null, null, 32 ]
}

在我们的项目中,我们引用了scala play文档,并试图声明一个简单的json读取解析器,例如Json.reads[MyObject]

案例类如下:

case class MyObject(
    foo: Int,
    bar: List[Option[Int]]
 )

但是编译器对此抱怨:

Error:(93, 42) No instance of play.api.libs.json.Reads is available for scala.collection.immutable.List[scala.Option[scala.Int]] in the implicit scope (Hint: if declared in the same file, make sure it's declared before) implicit val readMyObject = Json.reads[MyObject]

有人知道任何解决方法吗?

https://www.playframework.com/documentation/2.6.x/ScalaJsonCombinators

2 个答案:

答案 0 :(得分:0)

向对象随播广告添加optionReads方法。

val str = """{
   "foo": 12,
   "bar": [ 12, null, null, 32 ]
}"""

case class MyObject(foo: Int, bar: List[Option[Int]])

object MyObject {

  implicit def optionReads[T:Reads]: Reads[Option[T]] = (json: JsValue) => json.validateOpt[T]

  implicit val reads = Json.reads[MyObject]

}

val json = Json.parse(str)

val obj = Json.fromJson[MyObject](json)

println(obj)
// JsSuccess(MyObject(12,List(Some(12), None, None, Some(32))),)

答案 1 :(得分:0)

我不确定为什么

  implicit def optionReads[T:Reads]: Reads[Option[T]] = (json: JsValue) => json.validateOpt[T]

正在导致编译错误:

Error:(11, 73) type mismatch; found : play.api.libs.json.JsValue => play.api.libs.json.JsResult[Option[T]] required: play.api.libs.json.Reads[Option[T]] implicit def optionReads[T:Reads]: Reads[Option[T]] = (json: JsValue) => json.validateOpt[T]

但是我已经通过添加

解决了
    implicit def optionFormat[T: Format]: Format[Option[T]] =
      new Format[Option[T]] {
        override def reads(json: JsValue): JsResult[Option[T]] =
          json.validateOpt[T]
    }

来自帖子No Json formatter for Option[String]?