【问题标题】:Play Json Reads nested generic serialized Json播放 Json 读取嵌套的通用序列化 Json
【发布时间】:2020-02-17 09:08:05
【问题描述】:

考虑以下 JSON

{
    "a": "{\"b\": 12, \"c\": \"test\"}"
}

我想为这种序列化的 Json 定义一个泛型读取 Reads[Outer[T]]

import play.api.libs.json.{Json, Reads, __}

final case class Outer[T](inner: T)
final case class SpecializedInner(b: Int, c: String)

object SpecializedInner {
   implicit val reads: Reads[SpecializedInner] = Json.reads[SpecializedInner]
}

object Outer {
   implicit def reads[T](implicit readsT: Reads[T]): Reads[Outer[T]] = ???
}

我怎样才能实现我的目标?我尝试对字段“outer.a”进行平面映射字符串读取,但由于无法从经过验证的 JSON 中生成 Reads[T],因此卡住了

object Outer {
  implicit def reads[T](implicit readsT: Reads[T]): Reads[Outer[T]] =
    (__ \ "a").read[String].flatMap(x => Json.parse(x).validate[T])
}

【问题讨论】:

    标签: json scala playframework play-json


    【解决方案1】:

    您只需在validate[T] 调用之后在Outer.reads 构造中添加map

    请看下一个代码示例:

    object App {
    
      final case class Outer[T](inner: T)
    
      object Outer {
        implicit def reads[T](implicit innerReads: Reads[T]): Reads[Outer[T]] = { json: JsValue =>
          json.validate[String].flatMap(string => Json.parse(string).validate[T].map(Outer.apply[T]))
        }
      }
    
      final case class Root[T](a: Outer[T])
      object Root {
        implicit def reads[T](implicit innerReads: Reads[T]): Reads[Root[T]] = Json.reads
      }
    
      final case class SpecializedInner(b: Int, c: String)
    
      object SpecializedInner {
        implicit val reads: Reads[SpecializedInner] = Json.reads
      }
    
      def main(args: Array[String]): Unit = {
        val rawJson  = "{\"a\": \"{\\\"b\\\": 12, \\\"c\\\": \\\"test\\\"}\"}"
        println(Json.parse(rawJson).validate[Root[SpecializedInner]])
      }
    }
    

    在我的情况下产生了下一个结果:

    JsSuccess(Root(Outer(SpecializedInner(12,test))),)
    

    希望这会有所帮助!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-12-28
      • 1970-01-01
      • 1970-01-01
      • 2018-02-10
      • 1970-01-01
      • 2020-08-24
      • 1970-01-01
      相关资源
      最近更新 更多