【问题标题】:How setup spray-json to set null when json element is not present?当 json 元素不存在时,如何设置 spray-json 以设置 null?
【发布时间】:2015-03-17 03:27:03
【问题描述】:

这里是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 解组配置为只设置空值而无需额外的 Option 类型?

附言

我知道通常Option 比空检查更好,但在我的情况下它只是猴子代码。

在响应处理期间编组的完整示例是here

【问题讨论】:

    标签: json scala spray spray-json


    【解决方案1】:

    看来你倒霉了

    来自您链接的文档:

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

    您可以自定义 json 写入,但不能自定义读取。

    【讨论】:

      【解决方案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)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-07-30
        • 1970-01-01
        • 1970-01-01
        • 2022-07-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多