【问题标题】:json4s removing keys with value Nonejson4s 删除值为 None 的键
【发布时间】:2014-01-18 02:22:00
【问题描述】:

我一直在努力使用the docs 中描述的隐式转换从 Scalatra 应用程序返回 JSON。

我注意到带有空选项(即无)的键会从生成的 JSON 中删除(而不是为空,这似乎是预期的行为)

我尝试使用隐式转换将None 转换为null,例如:

class NoneJNullSerializer extends CustomSerializer[Option[_]](format => (
  {
    case JNull => None
  }, {
    case None => JNull
  }
  ))

protected implicit val jsonFormats: Formats = DefaultFormats.withBigDecimal + new NoneJNullSerializer()

但是,在执行自定义序列化程序之前,这些键似乎已被剥离。

有人找到解决办法了吗?

请注意,this question 中描述的解决方案适用于所描述的数组情况,但似乎不适用于地图。

更新: 这是我一直在使用的测试:

  get("/testJSON") {
    Map(
      "test_key" -> "testValue" ,

      "test_key6" -> "testValue6" ,
      "subObject" -> Map(
        "testNested1" -> "1" ,
        "testNested2" -> 2 ,
        "testArray" -> Seq(1, 2, 3, 4)
      ),
    "testNone" -> None ,
    "testNull" -> null ,
    "testSomeNull" -> Some(null) ,
    "testJNull" -> JNull ,
    "testSomeJNull" -> Some(JNull)
    )
  }

我正在寻找的输出是

{
    "test_key": "testValue",
    "test_some_j_null": null,
    "sub_object": {
        "test_nested1": "1",
        "test_nested2": 2,
        "test_array": [
            1,
            2,
            3,
            4
        ]
    },
    "test_none": null,
    "test_j_null": null,
    "test_key6": "testValue6",
    "test_null": null,
    "test_some_null": null
}

我也在用

protected override def transformResponseBody(body: JValue): JValue = { body.underscoreKeys }

下划线键

【问题讨论】:

  • 更新版本到 3.2.11 并使用 DefaultFormats.preservingEmptyValues

标签: scala scalatra json4s


【解决方案1】:

使用自定义序列化程序也应该适用于地图。

import org.json4s._
import org.json4s.jackson.JsonMethods._

object testNull extends App {

  val data = Map(
    "testNone" -> None,
    "testNull" -> null,
    "testSomeNull" -> Some(null),
    "testJNull" -> JNull,
    "testSomeJNull" -> Some(JNull)
  )

  class NoneJNullSerializer extends CustomSerializer[Option[_]](format => ( {
    case JNull => None
  }, {
    case None => JNull
  }))

  implicit val formats = DefaultFormats + new NoneJNullSerializer

  val ast = Extraction.decompose(data)

  println(pretty(ast))

  //  {
  //    "testSomeJNull" : null,
  //    "testJNull" : null,
  //    "testNone" : null,
  //    "testNull" : null,
  //    "testSomeNull" : null
  //  }

}

【讨论】:

  • 嗯,这还是不行。也许这是原生方法和杰克逊方法之间的区别。
  • 你能创建一个最小的示例项目吗?
  • 当我有时间的时候我会这样做,但老实说,我们已经开始远离 Scalatra,所以这不再是优先事项。当我有机会时,我会尝试确认这是实现之间的差异,并在必要时提交错误报告。
  • 我简单的做法是使用**implicit val formats = DefaultFormats.preservingEmptyValues**
猜你喜欢
  • 1970-01-01
  • 2018-08-12
  • 2013-04-12
  • 1970-01-01
  • 2016-02-21
  • 2022-10-25
  • 2019-09-28
  • 2021-02-13
  • 2022-01-06
相关资源
最近更新 更多