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

Configure spray-json for non strict parsing deserialization

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

例如,我正在解析一个 json,它有一个我的案例 class 没有的字段,它正在中断:

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

更新 :

一个简单的例子:

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

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

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

使用喷雾-json 格式,例如:

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

(简化代码)。

但问题更进一步,我想像其他解析器一样询问配置选项。更多示例:

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

这样的情况
case class MyClass(a: String, b: Int = 0) 

然后像 {"a":"foo"}

一样解析 json

但是如果你将第二个参数设置为Option。然后就可以了。

  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)

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 可能会派上用场,如果您使用匿名数组(即根是 [{...}] 而不是{"field":"value"...})