当 json 元素不存在时,如何设置 spray-json 以设置 null?
Posted
技术标签:
【中文标题】当 json 元素不存在时,如何设置 spray-json 以设置 null?【英文标题】:How setup spray-json to set null when json element is not present? 【发布时间】:2015-03-17 03:27:03 【问题描述】:这里是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 解组配置为只设置空值而无需额外的 Option
类型?
附言
我知道通常Option
比空检查更好,但在我的情况下它只是猴子代码。
在响应处理期间编组的完整示例是here
【问题讨论】:
【参考方案1】:看来你倒霉了
来自您链接的文档:
spray-json 将始终将缺少的可选成员以及
null
可选成员读取为None
您可以自定义 json 写入,但不能自定义读取。
【讨论】:
【参考方案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)
【讨论】:
以上是关于当 json 元素不存在时,如何设置 spray-json 以设置 null?的主要内容,如果未能解决你的问题,请参考以下文章
spray-json 无法编组 Map[String,String]