播放 Json 读取嵌套的通用序列化 Json
Play Json Reads nested generic serialized Json
考虑以下 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" flatMap a string-reads 但卡住了,因为我无法从经过验证的 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])
}
您只需要在 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))),)
希望对您有所帮助!
考虑以下 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" flatMap a string-reads 但卡住了,因为我无法从经过验证的 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])
}
您只需要在 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))),)
希望对您有所帮助!