Dia*_*rat 18 json scala playframework-2.0
我正在使用play-json的宏来定义隐式Writes序列化JSON.但是,似乎默认情况下play-json省略了字段Option设置为的字段None.有没有办法改变默认值,以便输出null?我知道如果我定义自己的Writes定义,这是可能的,但我有兴趣通过宏来减少样板代码.
例
case class Person(name: String, address: Option[String])
implicit val personWrites = Json.writes[Person]
Json.toJson(Person("John Smith", None))
// Outputs: {"name":"John Smith"}
// Instead want to output: {"name":"John Smith", "address": null}
Run Code Online (Sandbox Code Playgroud)
Jul*_*ont 16
的Json.writes宏生成一个writeNullable[T]为可选字段.如您所知(或不知道),writeNullable[T]如果值为None,则省略该字段,而write[Option[T]]生成空字段.
定义自定义编写器是获得此行为的唯一选择.
(
(__ \ 'name).write[String] and
(__ \ 'address).write[Option[String]]
)(unlift(Person.unapply _))
Run Code Online (Sandbox Code Playgroud)
对你来说不是真正的解决方案.但比手动写入写入稍微好一些
我创建了一个可以"确保"字段的辅助类.
implicit class WritesOps[A](val self: Writes[A]) extends AnyVal {
def ensureField(fieldName: String, path: JsPath = __, value: JsValue = JsNull): Writes[A] = {
val update = path.json.update(
__.read[JsObject].map( o => if(o.keys.contains(fieldName)) o else o ++ Json.obj(fieldName -> value))
)
self.transform(js => js.validate(update) match {
case JsSuccess(v,_) => v
case err: JsError => throw new JsResultException(err.errors)
})
}
def ensureFields(fieldNames: String*)(value: JsValue = JsNull, path: JsPath = __): Writes[A] =
fieldNames.foldLeft(self)((w, fn) => w.ensureField(fn, path, value))
}
Run Code Online (Sandbox Code Playgroud)
这样你就可以写了
Json.writes[Person].ensureFields("address")()
Run Code Online (Sandbox Code Playgroud)
您可以使用自定义隐式JsonConfiguration,请参阅自定义宏以输出 null
implicit val config = JsonConfiguration(optionHandlers = OptionHandlers.WritesNull)
implicit val personWrites = Json.writes[Person]
Json.toJson(Person("John Smith", None))
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5739 次 |
| 最近记录: |