在 Scala 中播放 json:反序列化具有未知字段的 json 而不会丢失它们 [英] play json in scala: deserializing json with unknown fields without losing them
问题描述
考虑我有一个如下的json:
consider i have a json as following:
{
"a": "aa",
"b": "bb",
"c": "cc",
"d": "dd", // unknown in advance
"e": { //unknown in advance
"aa": "aa"
}
}
我确定 json 将包含 a、b、c,但我不知道此 json 可能包含哪些其他字段.
i know for sure that the json will contain a,b,c but i've no idea what other fields this json may contain.
我想将此 JSON 序列化为包含 a、b、c 的 case 类,但另一方面不要丢失其他字段(将它们保存在映射中,以便该类将反序列化为与接收到的 json 相同的 json).
i want to serialize this JSON into a case class containing a,b,c but on the other hand not to lose the other fields (save them in a map so the class will be deserialized to the same json as received).
想法?
推荐答案
一种选择是在 Map[String,JsValue]
中捕获未知"字段,您以后可以从中提取值如果你需要它们.
One option is to capture the "unknown" fields in a Map[String,JsValue]
, from which you can later extract values if you need them.
case class MyClass(a: String, b: String, c: String, extra: Map[String, JsValue])
implicit val reads: Reads[MyClass] = (
(__ \ "a").read[String] and
(__ \ "b").read[String] and
(__ \ "c").read[String] and
__.read[Map[String, JsValue]]
.map(_.filterKeys(k => !Seq("a", "b", "c").contains(k)))
)(MyClass.apply _)
// Result:
// MyClass(aa,bb,cc,Map(e -> {"aa":"aa"}, d -> "dd"))
同样,您可以像这样执行 Writes
或 Format
:
Likewise, you can do a Writes
or a Format
like so:
// And a writes...
implicit val writes: Writes[MyClass] = (
(__ \ "a").write[String] and
(__ \ "b").write[String] and
(__ \ "c").write[String] and
__.write[Map[String, JsValue]]
)(unlift(MyClass.unapply _))
// Or combine the two...
implicit val format: Format[MyClass] = (
(__ \ "a").format[String] and
(__ \ "b").format[String] and
(__ \ "c").format[String] and
__.format[Map[String, JsValue]](Reads
.map[JsValue].map(_.filterKeys(k => !Seq("a", "b", "c").contains(k))))
)(MyClass.apply, unlift(MyClass.unapply))
注意:它看起来有点混乱,因为你给 Map[String,JsValue]
的 format
一个显式的 Reads
作为参数(Reads.map
),然后您对其进行转换(使用 .map
方法)以删除已捕获的值.
Note: it looks a bit confusing because you give the format
for Map[String,JsValue]
an explicit Reads
as an argument (Reads.map
), which you then transform (using the .map
method) to remove the already-captures values.
这篇关于在 Scala 中播放 json:反序列化具有未知字段的 json 而不会丢失它们的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!