5

我有一个对应于 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不带参数,所以无法(反)序列化它:

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

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

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

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

4

1 回答 1

7

抛出错误

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

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

顺便说一句,您可能希望用一个案例对象替换您的空案例类,以避免不必要的多次分配(除非您执行 some )。

于 2017-03-29T15:50:32.793 回答