这是spray-json example。这是NullOptions特质。
问题是当我宣布一个案例类说
时object MyJsonProtocol extends DefaultJsonProtocol {
implicit val some: RootJsonFormat[Some] = jsonFormat2(Some)
}
case class Some (
name:String,
age:Int
)
和json不包含字段,例如:
{
"name":"John"
}
我得到:java.util.NoSuchElementException: key not found: age
所以我必须添加Option
和NullOption
这样的特性:
object MyJsonProtocol extends DefaultJsonProtocol with NullOptions {
implicit val some: RootJsonFormat[Some] = jsonFormat2(Some)
}
case class Some (
name:String,
age:Option[Int]
)
一切正常。但我不希望有一个案例类,其中所有成员都是Option
。有没有办法配置喷json unmarshalling只是设置空值而没有额外的Option
类型?
P.S。
据我所知,一般来说Option
比null检查更好,但就我而言,它只是猴子代码。
响应处理期间编组的完整示例还有here
答案 0 :(得分:2)
我能想到的唯一方法是通过read/write
实现自己的协议,这可能很麻烦。下面是一个简化的例子。请注意,我将age
更改为Integer
而不是Int
,因为Int
是AnyVal
,默认情况下不可为空。此外,我只考虑age
字段可以为空,因此您可能需要根据需要采用。希望它有所帮助。
case class Foo (name:String, age: Integer)
object MyJsonProtocol extends DefaultJsonProtocol {
implicit object FooJsonFormat extends RootJsonFormat[Foo] {
def write(foo: Foo) =
JsObject("name" -> JsString(foo.name),
"age" -> Option(foo.age).map(JsNumber(_)).getOrElse(JsNull))
def read(value: JsValue) = value match {
case JsObject(fields) =>
val ageOpt: Option[Integer] = fields.get("age").map(_.toString().toInt) // implicit conversion from Int to Integer
val age: Integer = ageOpt.orNull[Integer]
Foo(fields.get("name").get.toString(), age)
case _ => deserializationError("Foo expected")
}
}
}
import MyJsonProtocol._
import spray.json._
val json = """{ "name": "Meh" }""".parseJson
println(json.convertTo[Foo]) // prints Foo("Meh",null)
答案 1 :(得分:1)
看来你运气不好
来自您关联的文档:
spray-json将始终读取缺少的可选成员以及
null
可选成员None
您可以自定义json书写,但不能自定义。