json4s删除值为None的键

时间:2014-01-18 02:22:01

标签: scala scalatra json4s

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

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

我尝试使用隐式转换将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 }

用于下划线键

1 个答案:

答案 0 :(得分:0)

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

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
  //  }

}