配置spray-json进行非严格解析反序列化

时间:2018-03-09 17:11:56

标签: json scala spray spray-json

如何在解析选项上配置spray-json解析? 与Jackson Parsing Features类似。

例如,我正在解析一个json,它有一个我的case类没有的字段,它正在破坏:

spray.json.DeserializationException: Object is missing required member 'myfield'

更新

一个简单的例子:

case class MyClass(a: String, b: Long);

并尝试解析不完整的json,如

val data = "{a: \"hi\"}"

采用spray-json格式,如:

jsonFormat2(MyClass.apply)
// ...
data.parseJson.convertTo[MyClass]

(简化代码)。

但问题更进一步,我想问一下其他解析器中的配置选项。更多例子:

  • 能够忽略JSON中存在的字段,但不能忽略案例类中的字段。
  • 管理空值或不存在值的方法。 等

2 个答案:

答案 0 :(得分:1)

Spray Json不支持默认参数。所以你不能拥有像

这样的案例类
case class MyClass(a: String, b: Int = 0) 

然后解析json,如{"a":"foo"}

但是,如果您将第二个参数设为选项。那就行了。

  import spray.json._
  case class MyClass(a: String, b: Option[Int] = None)
  object MyProtocol extends DefaultJsonProtocol {
  implicit val f = jsonFormat2(MyClass)
  }
  import MyProtocol.f
  val mc1 = MyClass("foo", Some(10))
  val strJson = mc1.toJson.toString
  val strJson2 = """{"a": "foo"}"""
  val mc2 = strJson2.parseJson.convertTo[MyClass]
  println(mc2)

答案 1 :(得分:1)

SprayJson允许您定义自定义解析器,如下所示:

case class Foo(a: String, b: Int)
implicit object FooJsonFormat extends RootJsonFormat[Foo] {
  override def read(json: JsValue): Foo = {
    json.asJsObject.getFields("name", "id") match {
      case Seq(JsString(name), id) =>
        Foo(name, id.convertTo[Int])
    }
  }

  override def write(obj: Foo): JsValue = obj.toJson
}

这允许您解析任意有效负载并提取字段" name"和" id" - 忽略其他字段。如果不保证这些字段,您可以添加如下内容:

      case Seq(JsString(name), JsNull) =>
        Foo(name, 0)

您应该查看JsValue.scala中可用的内容 - 特别是JsArray如果您获得带有匿名数组的有效负载(即根目录为{{1}而不是[{...}]