如何使用play-json编写和读取空案例类?

时间:2017-03-29 14:16:14

标签: scala serialization case-class play-json

我有一个与HTTP GET请求对应的空案例类:

case class GetFoo() extends MyQueryRequest {
  // ...
}

并且每条消息都有一个伴随对象,描述了它的隐式JSON编写器和读者:

object GetFoo extends MyImplicitJsonProvider[GetFoo] {
  implicit val write = Json.writes[GetFoo]
  implicit val read = Json.reads[GetFoo]
}

但是,因为GetFoo没有参数,所以没有办法(反)序列化它:

  

取消应用对象GetFoo没有参数。您使用的是空案例类吗?

将伪布尔变量注入GetFoo的构造函数的解决方法,但这是一个kludge。我想将GetFoo(de)序列化为空的JSON对象。我怎样才能做到这一点?

由于GET请求不发送数据,因此如果使用读取器/写入器会引发异常甚至更好,因为请求不应该被写入或读取,但是是扩展类所必需的。

我的设计依赖于扩展GetX的{​​{1}}类以及MyQueryRequest扩展的GetX个随播广告对象。

1 个答案:

答案 0 :(得分:7)

投掷错误

如果您只想拥有未实现的隐式值,则可以

implicit def format: Format[GetFoo] = ???

这将在您需要时在范围中添加隐式,但如果调用它将抛出NotImplementedException

虚拟序列化

如果您希望(de)序列化为空JsObject,请按原样实现:

implicit val nonStrictReads = Reads.pure(GetFoo()) // does not check anything on the `JsValue`, always give a `JsSuccess(GetFoo())`
implicit val strictReads = Reads[GetFoo](json => json.validate[JsObject].filter(_.values.isEmpty).map(_ => GetFoo())
implicit val writes = OWrites[GetFoo](_ => Json.obj())

尽可能地抓住它

但是,通过确保(通过更强的输入)您的请求没有内容,最好在编译时捕获错误。要做到这一点,我需要有关MyQueryRequestMyImplicitJsonProvider的更多信息来帮助您,但我会想象做MyQueryRequest[NoContent]MyQueryRequest[JsValue]之类的操作,具体取决于您何时拥有某些内容或不。然后一个需要JSON序列化器,而另一个则不需要。

顺便说一句,您可能希望用case对象替换空的case类,以避免不必要的多次分配(除非你做了一些)。