当json元素不存在时,如何设置spray-json设置null?

时间:2015-01-19 06:51:01

标签: json scala spray spray-json

这是spray-json example。这是NullOptions特质。

问题是当我宣布一个案例类说

object MyJsonProtocol extends DefaultJsonProtocol  {
  implicit val some: RootJsonFormat[Some] = jsonFormat2(Some)
}

case class Some (
                name:String,
                age:Int
                )

和json不包含字段,例如:

{
    "name":"John"
}

我得到:java.util.NoSuchElementException: key not found: age

所以我必须添加OptionNullOption这样的特性:

object MyJsonProtocol extends DefaultJsonProtocol with NullOptions  {
  implicit val some: RootJsonFormat[Some] = jsonFormat2(Some)
}

case class Some (
                name:String,
                age:Option[Int]
                )

一切正常。但我不希望有一个案例类,其中所有成员都是Option。有没有办法配置喷json unmarshalling只是设置空值而没有额外的Option类型?

P.S。

据我所知,一般来说Option比null检查更好,但就我而言,它只是猴子代码。

响应处理期间编组的完整示例还有here

2 个答案:

答案 0 :(得分:2)

我能想到的唯一方法是通过read/write实现自己的协议,这可能很麻烦。下面是一个简化的例子。请注意,我将age更改为Integer而不是Int,因为IntAnyVal,默认情况下不可为空。此外,我只考虑age字段可以为空,因此您可能需要根据需要采用。希望它有所帮助。

 case class Foo (name:String, age: Integer)

 object MyJsonProtocol extends DefaultJsonProtocol {
    implicit object FooJsonFormat extends RootJsonFormat[Foo] {
      def write(foo: Foo) =
        JsObject("name" -> JsString(foo.name),
                 "age"  -> Option(foo.age).map(JsNumber(_)).getOrElse(JsNull))

      def read(value: JsValue) = value match {
        case JsObject(fields) =>
          val ageOpt: Option[Integer] = fields.get("age").map(_.toString().toInt) // implicit conversion from Int to Integer
          val age: Integer = ageOpt.orNull[Integer]
          Foo(fields.get("name").get.toString(), age)
        case _ => deserializationError("Foo expected")
      }
    }
  }

  import MyJsonProtocol._
  import spray.json._

  val json = """{ "name": "Meh" }""".parseJson
  println(json.convertTo[Foo]) // prints Foo("Meh",null)

答案 1 :(得分:1)

看来你运气不好

来自您关联的文档:

  

spray-json将始终读取缺少的可选成员以及null可选成员None

您可以自定义json书写,但不能自定义。