在 Scala 中播放 json:反序列化具有未知字段的 json 而不会丢失它们 [英] play json in scala: deserializing json with unknown fields without losing them

查看:70
本文介绍了在 Scala 中播放 json:反序列化具有未知字段的 json 而不会丢失它们的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑我有一个如下的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"))

同样,您可以像这样执行 WritesFormat:

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆