【问题标题】:Writing custom object JSON as a simple value in Scala (JSON Reads/Writes)将自定义对象 JSON 编写为 Scala 中的简单值(JSON 读/写)
【发布时间】:2015-05-20 07:52:15
【问题描述】:

我在 Scala 中有一个自定义数据类型:

case class GPID(value: Int) {
    // ... other stuff ...

    implicit val writesGPID = new Writes[GPID] {
        def writes(g: GPID): JsValue = {
            Json.obj(
                "GPID" -> g.value
            )
        }
    }

    implicit val reads: Reads[GPID] = (
        (__ \ "GPID").read[Int]
        ).map(GPID(_))
}

正如你所看到的,它有一个读/写方法,但这会导致如下输出:

"id":{"GPID":1000}

但是,我们只是希望它像常规 Int 一样序列化/反序列化:

"id":1000

我一直在尝试弄清楚如何重写读/写,但运气不佳...任何建议将不胜感激!

谢谢。

【问题讨论】:

    标签: scala play-json


    【解决方案1】:

    我添加了一些验证,根据您的需要进行修改。

    object GPID {
      def unapply(in: Int): Option[GPID] = Option(in).filter(_ > 0).map(apply)
    
      implicit val reads = new Reads[GPID] {
        def reads(in: JsValue) =
          Option(in)
            .flatMap {
              case JsNumber(value) => Some(value)
              case _ => None
            }
            .flatMap(num => unapply(num.toInt))
            .map(JsSuccess(_, __))
            .getOrElse(JsError(__, "validate.error.expected.GPID"))
      }
    
      implicit val writes = new Writes[GPID] {
        def writes(g: GPID) = JsNumber(g.value)
      }
    
    }
    

    【讨论】:

    • 嗯。更接近,但不完全。它被序列化为"id":{"id":1000} 所以,它仍然把它当作一个对象,而不是一个简单的值......我也不能使用隐式读取,因为:ScalaReflectionException: value apply encapsulates multiple overloaded alternatives and cannot be treated as a method. Consider invoking <offending symbol>.asTerm.alternatives and manually picking the required method
    • 所以你需要提供一份!再次编辑。
    • 啊...您的 unapply 看起来与我尝试的完全不同!谢谢,现在工作得很好。我有点困惑为什么我们现在必须添加unapply,如果我们定义原始的读/写(来自我的第一篇文章)就没有必要了。我得仔细看看并弄清楚。 Json Reads/Writes/apply/unapply 对我来说仍然有点黑魔法......
    • 它们的神奇之处在于它们为您提供了多种实现相同效果的方法。一开始它是令人生畏和令人沮丧的,但是一旦你习惯了它,它们就会非常强大。祝你好运。
    • 当谈到unapply时,我已经写他们期望类被解构。我尝试了unapply(g: GPID),但你写了一个unapply(in: Int),你直接从读取中调用它......我仍然很困惑。我不明白为什么或如何工作......我认为unapply 被用来从本质上解构事物的一个实例。在这种情况下,事情是一个 GPID,所以......unapply 如何获取一个 Int 并实际工作?实际上,你写的unapply 在我看来就像apply 方法!
    猜你喜欢
    • 1970-01-01
    • 2021-10-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多