JSON 泛型在 Play 中的格式 2.x

JSON format for Generics in Play 2.x

我的类看起来像这样

trait Value[T] {
  def get:T
}

我有这个的实现,例如

class StringValue(value : String) extends Value[String] {
  override def get : String = value
}

class NumberValue(value : Int) extends Value[Int] {
  override def get: Int = value
}

问题是我需要为这种类型制作 jsonFormat 以便将其保存到 MongoDB。

我卡了两天还是不知道怎么弄

至于提供的.nullable which returns Reads for Option (generic type),需要先强制[=18=的类型参数] 本身提供了 ReadsWrites.

所需的实例

因此,对于通用 Reads[Value[T]],最小 def 如下所示。

def valueReads[T](implicit underlying: Reads[T]): Reads[Value[T]] = ???

类似地,对于Writes[Value[T]](或OWrites,如果它需要限制在JSON对象,因此BSON文档),最小定义如下。

def valueWrites[T](implicit underlying: Writes[T]): Writes[Value[T]] = ???
// or
def valueOWrites[T](implicit underlying: Writes[T]): OWrites[Value[T]] = ??? // don't define both as implicit to avoid conflict

然后实现取决于您希望将 Value[T] 表示为 JSON 的方式。

考虑以下 JSON 表示:

{ "_value": ... }

...那么 Reads 将是下面的内容。

implicit def valueReads[T](implicit underlying: Reads[T]): Reads[Value[T]] =
  Reads[Value[T]] { json =>
    (json \ "_value").validate(underlying).map { t: T =>
      Value(t)
    }
  }

类似地,OWrites[Value[T]] 将如下所示。

implicit def valueWrites[T](implicit underlying: Writes[T]): OWrites[Value[T]] =
  OWrites[Value[T]] { value => Json.obj("_value" -> value) }

Obviously, these implicits need to be in the implicit scope, either by being defined in the Value companion object, or by being explicitly imported if defined elsewhere.