【问题标题】:JSON format for Generics in Play 2.xPlay 2.x 中泛型的 JSON 格式
【发布时间】:2017-06-21 01:42:25
【问题描述】:

我的课是这样的

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。

我坚持了两天,但仍然不知道如何使它工作

【问题讨论】:

    标签: scala playframework playframework-2.0


    【解决方案1】:

    对于提供的.nullable,它为Option(泛型类型)返回Reads,您需要首先强制Value的类型参数本身提供Reads和@987654327所需的实例@。

    因此,对于通用 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) }
    

    显然,这些隐式需要在隐式范围内,要么在 Value 伴随对象中定义,要么在其他地方定义时显式导入。

    【讨论】:

    • 谢谢,这似乎或多或少清楚(至少看一下选项示例是个好主意)。那你觉得 case class Foo(attributes: Map[Attribute, Value[_]]) 怎么办?
    • 不能,因为_ 表示类型参数未知。你需要一个Foo[T]
    • 但我希望这个 Map[Attribute, Value[_]] 包含 StringValue 和 NumberValue 两种类型
    • 你不能,类型类的实例是基于已知类型的,如果你删除类型,你就完成了(或者你会做一些不安全/无类型的代码)。您可以将类型参数称为密封系列,将所有可能的情况定义为子类型(基于/允许模式匹配)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-25
    • 1970-01-01
    • 2014-01-04
    • 2014-06-11
    • 1970-01-01
    相关资源
    最近更新 更多