【问题标题】:How can I write and read an empty case class with play-json?如何使用 play-json 编写和读取空案例类?
【发布时间】:2017-08-23 02:17:46
【问题描述】:

我有一个对应于 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 的构造函数的解决方法,但这是一个杂项。我想让GetFoo (de)serializable 作为一个空的 JSON 对象。我怎样才能做到这一点?

由于 GET 请求不发送数据,如果读取器/写入器正在使用它,最好让其抛出异常,因为该请求不应该被写入或读取,而是由扩展类。

我的设计依赖于扩展MyQueryRequestGetX 类和扩展MyImplicitJsonProvider[GetX]GetX 伴随对象。

【问题讨论】:

    标签: scala serialization case-class play-json


    【解决方案1】:

    抛出错误

    如果你只想拥有未实现的隐式值,你可能会很好

    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 序列化器,而另一个不需要。

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

    【讨论】:

      猜你喜欢
      • 2017-12-25
      • 2014-12-14
      • 2020-08-27
      • 2015-02-13
      • 2016-12-15
      • 1970-01-01
      • 1970-01-01
      • 2020-01-14
      • 2021-06-27
      相关资源
      最近更新 更多