配置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]
(简化代码)。
但问题更进一步,我想像其他解析器一样询问配置选项。更多示例:
- 能够忽略 JSON 中存在但 class 中不存在的字段。
- 管理空值或不存在值的方法。
等等
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"...}
)
如何在解析选项上配置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]
(简化代码)。
但问题更进一步,我想像其他解析器一样询问配置选项。更多示例:
- 能够忽略 JSON 中存在但 class 中不存在的字段。
- 管理空值或不存在值的方法。 等等
Spray Json 不支持默认参数。所以你不能有 class 像
这样的情况case class MyClass(a: String, b: Int = 0)
然后像 {"a":"foo"}
但是如果你将第二个参数设置为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"...}
)