6

我定义了一个递归类:

case class SettingsRepository(id: Option[BSONObjectID],
                          name: Option[String],
                          children: Option[List[SettingsRepository]])

JSON隐式格式如下:

implicit val repositoryFormat = Json.format[SettingsRepository]

我该如何解决这个编译错误?:

No implicit format for Option[List[models.practice.SettingsRepository]] available.
In /path/to/the/file.scala:95

95 implicit val repositoryFormat = Json.format[SettingsRepository] 

我试图定义一个懒惰的读/写/格式包装器,但没有成功……有人知道这样做的干净方法吗?

4

3 回答 3

9

正如您所发现的,您不能在此处使用 JSON inception 宏,但您可以编写自己的Format(请注意,为了完整的工作示例,我已替换为)BSONObjectIDLong

import play.api.libs.functional.syntax._
import play.api.libs.json._

case class SettingsRepository(
  id: Option[Long],
  name: Option[String],
  children: Option[List[SettingsRepository]]
)

implicit val repositoryFormat: Format[SettingsRepository] = (
  (__ \ 'id).formatNullable[Long] and
  (__ \ 'name).formatNullable[String] and
  (__ \ 'children).lazyFormatNullable(implicitly[Format[List[SettingsRepository]]])
)(SettingsRepository.apply, unlift(SettingsRepository.unapply))

诀窍是提供显式类型注释并使用implicitly而不仅仅是类型参数lazyFormatNullable

于 2015-06-08T15:07:56.220 回答
1

对于其他来这里寻找我们覆盖readswrites在 Format 类中的轻微变体的其他人(如API 文档中给出的示例),您可以声明对所需对象的惰性引用:

  lazy val tweetFormat: Format[Tweet] = TweetFormat
  implicit object UserFormat extends Format[User] {
  //...
  }

  //...
  implicit object TweetFormat extends Format[Tweet] {
  //...
于 2015-07-31T19:37:32.557 回答
0

只是一个更新。这已经修复了很长时间。例如,在play-json2.3.9 版本中,这是Maven中最旧的版本,以下工作:

import play.api.libs.json._

case class SettingsRepository(id: Option[Int],
                              name: Option[String],
                              children: Option[List[SettingsRepository]])

implicit val repositoryFormat = Json.format[SettingsRepository]

val s = SettingsRepository(Some(2), Some("name"), Some(List(SettingsRepository(Some(1), Some(""), None))))
println(Json.toJsObject(s))

和输出:

{"id":2,"name":"name","children":[{"id":1,"name":""}]}

代码在Scastie运行。

于 2021-01-26T14:24:16.553 回答