如何使用 play-json 写入和读取空 case class?

How can I write and read an empty case class with play-json?

我有一个空案例 class 对应于 HTTP GET 请求:

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

并且每条消息都有一个伴随对象,其中描述了其隐含的 JSON 作者和 reader:

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

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

Unapply of object GetFoo has no parameters. Are you using an empty case class?

一种将虚拟布尔变量注入 GetFoo 的构造函数的变通方法,但这是一个问题。我想将 GetFoo(反)序列化为一个空的 JSON 对象。我怎样才能做到这一点?

由于 GET 请求不发送数据,如果 reader/writer 被使用则抛出异常会更好,因为请求永远不需要写入或读取,但是扩展 class.

需要

我的设计依赖于扩展 MyQueryRequestGetX class 和扩展 MyImplicitJsonProvider[GetX].

GetX 伴随对象

抛出错误

如果您只想拥有未实现的隐式值,您可能会这样做

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

这将在您需要时在作用域中添加隐式,但如果调用它则会抛出 NotImplementedException

虚拟序列化

如果您希望(反)序列化为空 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 序列化器,而另一个不需要。

顺便说一下,您可能希望用一个案例对象替换您的空案例 class,以避免不必要的多重分配(除非您做了一些 )。