如何使用 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.
需要
我的设计依赖于扩展 MyQueryRequest
的 GetX
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())
最好抓紧时间
但是,最好在编译时捕获错误,方法是确保(通过更强的类型)您的请求没有内容。为此,我需要有关 MyQueryRequest
和 MyImplicitJsonProvider
的更多信息来为您提供帮助,但我想根据您何时有一些内容,做一些类似 MyQueryRequest[NoContent]
或 MyQueryRequest[JsValue]
的事情或不。那么一个需要 JSON 序列化器,而另一个不需要。
顺便说一下,您可能希望用一个案例对象替换您的空案例 class,以避免不必要的多重分配(除非您做了一些 )。
我有一个空案例 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.
需要我的设计依赖于扩展 MyQueryRequest
的 GetX
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())
最好抓紧时间
但是,最好在编译时捕获错误,方法是确保(通过更强的类型)您的请求没有内容。为此,我需要有关 MyQueryRequest
和 MyImplicitJsonProvider
的更多信息来为您提供帮助,但我想根据您何时有一些内容,做一些类似 MyQueryRequest[NoContent]
或 MyQueryRequest[JsValue]
的事情或不。那么一个需要 JSON 序列化器,而另一个不需要。
顺便说一下,您可能希望用一个案例对象替换您的空案例 class,以避免不必要的多重分配(除非您做了一些 )。