考虑使用Play的JSON API(play.api.libs.json
)的示例:
case class FooJson( // lots of other fields omitted location: Option[LocationJson] ) object FooJson { implicit val writes = Json.writes[FooJson] }
和
case class LocationJson(latitude: Double, longitude: Double) object LocationJson { implicit val writes = Json.writes[LocationJson] }
如果location
为None
,则生成的JSON将完全没有location
字段。这是很好的并且是不可改变的。但是,如果出于某种原因(例如,使我的API更加自我记录),我该如何显式输出null
JSON?
{ "location": null }
我还尝试将字段定义为location: LocationJson
并将其传递option.orNull
给它,但是它不起作用(scala.MatchError: null
at play.api.libs.json.OWrites$$anon$2.writes
)。对于非自定义类型(例如String或Double),此方法将在JSON输出中生成null。
所以,虽然使用Json.writes[FooJson]
上述如图所示(或其他同样简单,即不具有编写自定义Writes
实现),有一个干净的方式包括在JSON空?
我要问的是类似于JsonInclude.Include.ALWAYS
Jackson库中的内容(也是Jackson的默认行为)。同样,在Gson中,这是微不足道的
(new GsonBuilder().serializeNulls().create()
)。
播放2.4.4
Play的提交者Greg Methvin 在一个相关的GitHub问题中向我写了这个答案:
JSON宏仅支持一种编码可选值的方式,即从JSON中省略None值。这不是错误,而是实现的限制。如果要包含null,那么很遗憾,您必须实现自己的null
Writes
。我确实认为我们应该尝试为宏提供更多的可配置性。
在这种情况下,即使值略微牺牲了API的一致性和可自我记录性,我也会让Play在该值为null时排除该字段。(在这个特定的API中)仍然是一件很小的事情,以至于它不像Writes
在具有十几个值的案例类中那样自定义将自定义代码那样丑陋。
我希望他们能在将来的Play版本中使此配置更具可配置性。